主页: 走势: +商务数据

feature/bak/sales-kpi
Lei OT 2 years ago
parent ddace149b1
commit a427a221a9

@ -1,6 +1,6 @@
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { Line } from '@ant-design/plots'; import { Line } from '@ant-design/plots';
import { merge, isEmpty } from '../utils/commons'; import { merge, isEmpty, groupBy } from '../utils/commons';
import { dataFieldAlias } from '../libs/ht'; import { dataFieldAlias } from '../libs/ht';
const uniqueByKey = (array, key, pickLast) => { const uniqueByKey = (array, key, pickLast) => {
@ -26,15 +26,22 @@ const uniqueByKey = (array, key, pickLast) => {
export default observer((props) => { export default observer((props) => {
const { dataSource, ...config } = props; const { dataSource, ...config } = props;
const kpiKey = dataFieldAlias[config.yField]?.nestkey?.v; const kpiKey = dataFieldAlias[config.yField]?.nestkey?.v;
const _data = dataSource.reduce((r, v) => { const seriesData = groupBy(dataSource, ele => ele[config.seriesField]);
r.push(v); const pickKey4KPI = Object.keys(seriesData)[0];
const KPIData = (seriesData?.[pickKey4KPI] || []).reduce((r, v) => {
if ( ! isEmpty(v[kpiKey])) { // 线 : #F4664A if ( ! isEmpty(v[kpiKey])) { // 线 : #F4664A
r.push({...v, [config.yField]: v[kpiKey], [config.seriesField]: dataFieldAlias[kpiKey].label, extraLine: true,}); r.push({...v, [config.yField]: v[kpiKey], [config.seriesField]: dataFieldAlias[kpiKey].label, extraLine: true,});
} }
return r; return r;
}, []); }, []);
const dataColors = ['#598cf3', '#69deae', '#FAAD14'];
const colorSets = Object.keys(seriesData).sort().reduce((obj, k, i) => ({...obj, [k]: dataColors[i]}), {});
const mergeLineConfig = merge({ const mergeLineConfig = merge({
color: ['#598cf3', '#F4664A', '#FAAD14'], // color: ['#598cf3', '#69deae', '#F4664A', '#FAAD14'],
color: (item) => {
const thisSeries = item[config.seriesField];
return thisSeries.includes('目标') ? '#F4664A' : colorSets[thisSeries];
},
lineStyle: (data) => { lineStyle: (data) => {
// console.log(data); // console.log(data);
if (data[config.seriesField].includes('目标')) { if (data[config.seriesField].includes('目标')) {
@ -49,5 +56,5 @@ export default observer((props) => {
}; };
}, },
}, config); }, config);
return <Line {...mergeLineConfig} data={_data} />; return <Line {...mergeLineConfig} data={[...dataSource, ...KPIData]} />;
}); });

@ -14,7 +14,7 @@ export default observer((props) => {
const ValueIcon = props.icon; const ValueIcon = props.icon;
const valueStyle = { color: (props?.VSrate || -1) < 0 ? '#3f8600' : '#cf1322' }; const valueStyle = { color: (props?.VSrate || -1) < 0 ? '#3f8600' : '#cf1322' };
const VSIcon = () => ((props?.VSrate || -1) < 0 ? <ArrowDownOutlined /> : <ArrowUpOutlined />); const VSIcon = () => ((props?.VSrate || -1) < 0 ? <ArrowDownOutlined /> : <ArrowUpOutlined />);
console.log(props, ';;;;'); // console.log(props, ';;;;');
const [responsive, setResponsive] = useState(false); const [responsive, setResponsive] = useState(false);
const bulletData = [ const bulletData = [
{ {
@ -25,7 +25,7 @@ export default observer((props) => {
target: kpiVal || 0, target: kpiVal || 0,
}, },
]; ];
console.log(bulletData, 'bbbbbbbbb'); // console.log(bulletData, 'bbbbbbbbb');
const RingProgressConfigBlue = { const RingProgressConfigBlue = {
height: 60, height: 60,

@ -1,6 +1,6 @@
import { makeAutoObservable, runInAction, toJS } from 'mobx'; import { makeAutoObservable, runInAction, toJS } from 'mobx';
import * as req from '../utils/request'; import * as req from '../utils/request';
import { isEmpty, sortBy, pick, merge, fixTo2Decimals } from '../utils/commons'; import { isEmpty, sortBy, pick, merge, fixTo2Decimals, groupBy, sortKeys } from '../utils/commons';
import { dataFieldAlias } from './../libs/ht'; import { dataFieldAlias } from './../libs/ht';
class Trade { class Trade {
@ -17,9 +17,8 @@ class Trade {
queryData.groupType = queryData?.groupType || 'overview'; queryData.groupType = queryData?.groupType || 'overview';
queryData.groupDateType = 'year'; queryData.groupDateType = 'year';
const multiData = await this.fetchTradeDataAll(queryData); const multiData = await this.fetchTradeDataAll(queryData);
console.log(multiData, 'mmmmmmmm', queryData);
// this.fetchTradeData(queryData).then((json) => {
const { summary, traditional, biz } = multiData.result1; const { summary, traditional, biz } = multiData.result1;
// console.log(JSON.stringify(summary), 'mmmmmmmmmmm');
const summaryData = { const summaryData = {
loading: false, loading: false,
dataSource: [ dataSource: [
@ -77,26 +76,27 @@ class Trade {
const kpi = { label: '', value: summary?.[0]?.MLKPIvalue }; const kpi = { label: '', value: summary?.[0]?.MLKPIvalue };
this.summaryData.kpi = kpi; this.summaryData.kpi = kpi;
}); });
// });
} }
/** /**
* 时间轴 * 时间轴
*/ */
fetchTradeDataByDate(queryData = {}) { async fetchTradeDataByDate(queryData = {}) {
this.timeData.loading = true; this.timeData.loading = true;
queryData = Object.assign({}, this.searchPayloadHome, queryData); // queryData || this.searchPayloadHome; queryData = Object.assign({}, this.searchPayloadHome, queryData); // queryData || this.searchPayloadHome;
queryData.groupType = queryData?.groupType || 'overview'; queryData.groupType = queryData?.groupType || 'overview';
Object.assign(queryData, { groupDateType: this.timeLineKey }); Object.assign(queryData, { groupDateType: this.timeLineKey });
this.fetchTradeData(queryData).then((json) => { const multiData = await this.fetchTradeDataAll(queryData);
if (json.errcode === 0) { const { traditional, biz } = multiData.result1;
const data = json.result1.sort(sortBy('groupDateVal')); // console.log(biz, 'mmmmmmmm', queryData);
runInAction(() => { const dataT = traditional.map(ele => ({...ele, groupsLabel: '传统'}));
// 标注KPI const dataB = biz.map(ele => ({...ele, groupsLabel: '商务'}));
this.timeData.loading = false; const mergeData = [].concat(dataT, dataB);
this.timeData.dataSource = data; const dateKeyData = groupBy(mergeData, ele => ele.groupDateVal);
}); const sortByDateKey = Object.values(sortKeys(dateKeyData)).reduce( (a, b) => a.concat(b), []);
} runInAction(() => {
this.timeData.loading = false;
this.timeData.dataSource = sortByDateKey;
}); });
} }
@ -229,8 +229,8 @@ class Trade {
groupsData[groupsKey]?.[0] || {} groupsData[groupsKey]?.[0] || {}
); );
}).map(row => ({...row, }).map(row => ({...row,
ConfirmRates: fixTo2Decimals((row.ConfirmOrder/row.SumOrder)*100), ConfirmRates: row.SumOrder ? fixTo2Decimals((row.ConfirmOrder/row.SumOrder)*100) : 0,
MLKPIrates: fixTo2Decimals((row.SumML/row.MLKPIvalue)*100), MLKPIrates: row.MLKPIvalue ? fixTo2Decimals((row.SumML/row.MLKPIvalue)*100) : 0,
// todo: // todo:
})); }));
return Object.assign(res, { [resKey]: Object.assign({}, mergeItem, { summary }) }); return Object.assign(res, { [resKey]: Object.assign({}, mergeItem, { summary }) });

@ -283,6 +283,11 @@ export const sortBy = (key) => {
return (a, b) => (a[key] > b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0); return (a, b) => (a[key] > b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0);
}; };
export const sortKeys = (obj) =>
Object.keys(obj)
.sort()
.reduce((a, k2) => ({...a, [k2]: obj[k2]}), {});
/** /**
* 合并Object, 递归地 * 合并Object, 递归地
*/ */

@ -53,7 +53,7 @@ export default observer(() => {
TradeStore.resetData(); TradeStore.resetData();
TradeStore.fetchSummaryData(Object.assign({}, queryData, { groupType })); TradeStore.fetchSummaryData(Object.assign({}, queryData, { groupType }));
TradeStore.fetchTradeDataByDate(queryData); TradeStore.fetchTradeDataByDate(queryData);
TradeStore.fetchTradeDataByBU(queryData); // TradeStore.fetchTradeDataByBU(queryData);
TradeStore.fetchTradeDataByMonth(queryData); TradeStore.fetchTradeDataByMonth(queryData);
const topSeriesF = _overviewFlag ? topSeries : topSeries.filter((ele) => ele.key !== 'dept'); const topSeriesF = _overviewFlag ? topSeries : topSeries.filter((ele) => ele.key !== 'dept');
setTopSeriesSet(topSeriesF); setTopSeriesSet(topSeriesF);
@ -155,7 +155,7 @@ export default observer(() => {
tooltip: { tooltip: {
customItems: (originalItems) => { customItems: (originalItems) => {
// process originalItems, // process originalItems,
const items = originalItems.map((ele) => ({ ...ele, name: ele.data?.extraLine ? ele.name : dataFieldAlias[key]?.alias || key })); const items = originalItems.map((ele) => ({ ...ele, name: ele.data?.extraLine ? ele.name : `${ele.name} ${dataFieldAlias[key]?.alias || key}` }));
return items; return items;
}, },
}, },
@ -224,7 +224,7 @@ export default observer(() => {
</Spin> </Spin>
</section> </section>
<section> <section>
<h3>市场</h3> <h3>市场 (仅传统订单) </h3>
<Spin spinning={BuData.loading}> <Spin spinning={BuData.loading}>
<Row gutter={layoutProps3.gutter}> <Row gutter={layoutProps3.gutter}>
<Col {...layoutProps3}> <Col {...layoutProps3}>

Loading…
Cancel
Save