import moment from 'moment'; export const datePartOptions = [ { label: '日', value: 'day' }, { label: '周', value: 'week' }, { label: '月', value: 'month' }, { label: '季', value: 'season' }, { label: '年', value: 'year' }, ]; export const datePartMethod = { 'day': (date) => { return { 'dateKey': date, 'groupKey': date, date }; }, 'week': (date, ...args) => { const dateO = moment(date); const year = dateO.weekYear(); const week = dateO.week(); // const weekOfMonth = dateO.week() - moment(date).startOf('month').week() + 1; const key = `W${String(week).padStart(2, '0')}`; const dateKey = `${year}-W${String(week).padStart(2, '0')}`; return { dateKey, 'groupKey': dateKey, date }; }, 'season': (date) => { const dateO = moment(date); // const key = dateO.format('YYYY-Q'); const key = `${dateO.year()}-${String(dateO.quarter()).padStart(2, 'Q')}`; const dateKey = `${dateO.year()}-${String(dateO.quarter()).padStart(2, 'Q')}`; return { dateKey, 'groupKey': key, date }; }, 'month': (date) => { const dateO = moment(date); const key = dateO.format('YYYY-MM'); const dateKey = dateO.format('YYYY-MM'); return { dateKey, 'groupKey': key, date }; }, 'year': (date) => { const dateO = moment(date); const key = dateO.format('YYYY'); const dateKey = dateO.format('YYYY'); return { dateKey, 'groupKey': key, date }; }, }; /** * * @param {Array} data 结果数组 * @param {*} dateType 切换的日期类型 * @param {Object} mapper 映射结果字段 * @returns {Object} { data, avg } * * data: 转换后的数组 * * avg: 平均值 */ export const parseDateType = (data, dateType = 'day', { dateKey, valueKey, seriesKey, _f }) => { const _calcF = { 'avg': (sum, len) => sum / len, }; const seriesDataMapped = data.reduce((r, v) => { const _k = v[seriesKey]; (r[_k] || (r[_k] = [])).push(v); return r; }, {}); const everySeries = Object.keys(seriesDataMapped).reduce((rs, _series) => { const e = seriesDataMapped[_series].reduce((r, v) => { const datePart = datePartMethod[dateType](v[dateKey]); const mergeKey = `${datePart.groupKey}@${_series}`; (r[mergeKey] || (r[mergeKey] = [])).push({ ...v, 'dateKey': datePart.dateKey, 'groupKey': datePart.groupKey, datePart }); return r; }, {}); return { ...rs, ...e }; }, {}); const resultKeys = Object.keys(everySeries); resultKeys.sort(); const dateArr = []; const groupSum = resultKeys.reduce((a, key) => { const [_dateKey, _seriesKey] = key.split('@'); dateArr.push(_dateKey); const containDate = everySeries[key].map((ele) => ele.datePart.date); const containDateM = [...new Set(containDate)].map((ele) => moment(ele)); const min = moment.min(containDateM).format('YYYY-MM-DD'); const max = moment.max(containDateM).format('YYYY-MM-DD'); const dateRangeStr = min === max ? min : `${min}~${max}`; const dateRange = [min, max]; const summaryVal = everySeries[key].reduce((rows, row) => rows + row[valueKey], 0); const retValue = _f === 'sum' ? summaryVal : _calcF(summaryVal, everySeries[key].length); a.push({ groupKey: key, value: retValue, dateKey: dateRangeStr, dateRange, containDate, [seriesKey]: _seriesKey, [dateKey]: _dateKey }); return a; }, []); const avgDiv = [...new Set(dateArr)].length; const avgVal = groupSum.length !== 0 ? groupSum.reduce((s, c) => s + c.value, 0) / avgDiv : 0; return { data: groupSum, avgVal }; }; /** * * @param {Array} dataRaw 结果数组 * @param {*} dateGroup 切换的日期类型, radio onchange 的值 * @param {Object} dataMapper 映射数据集字段 { data1, data2 } * @param {Object} mapper 映射结果字段 { dateKey, valueKey, _f } * * dateKey: 日期. 'ApplyDate' * * valueKey: 结果. 'orderCount' * * seriesKey: 序列. 'WebCode' * * _f: 计算方法. 'sum' | 'avg * @author LYT */ export const resultDataCb = (dataRaw, dateGroup, { data1, data2 }, fieldMapper, cb) => { const _data1 = data1 ? dataRaw[data1] : dataRaw; const _data2 = data2 ? dataRaw[data2] : []; const parse1 = parseDateType(_data1, dateGroup, fieldMapper); const parseData1 = parse1.data.map((ele) => ({ [fieldMapper.dateKey]: ele[fieldMapper.dateKey], [fieldMapper.valueKey]: ele.value, [fieldMapper.seriesKey]: ele[fieldMapper.seriesKey], groups: _data1[0].groups, dateKey: ele.dateKey, dateRange: ele.dateRange, dateGroup: ele[fieldMapper.dateKey], })); const parse2 = parseDateType(_data2, dateGroup, fieldMapper); const parseData2 = parse2.data.map((ele) => ({ [fieldMapper.dateKey]: ele[fieldMapper.dateKey], // [fieldMapper.dateKey]: ele.groupKey, [fieldMapper.valueKey]: ele.value, [fieldMapper.seriesKey]: ele[fieldMapper.seriesKey], groups: _data2[0].groups, dateKey: ele.dateKey, dateRange: ele.dateRange, dateGroup: ele[fieldMapper.dateKey], })); const useKeys = parseData1.map((ele) => ele[fieldMapper.dateKey]); const reindexData2 = parseData2.map((ele, index) => ({ ...ele, [fieldMapper.dateKey]: useKeys[index] || `_${ele[fieldMapper.dateKey]}`, dateKey: ele.dateKey })); const retData = [].concat(parseData1, reindexData2 ); const avg1 = parse1.avgVal; // console.log('callback', dateGroup, retData); cb(dateGroup, retData, avg1); };