diff --git a/src/components/StatisticCard2.jsx b/src/components/StatisticCard2.jsx
new file mode 100644
index 0000000..ac6a624
--- /dev/null
+++ b/src/components/StatisticCard2.jsx
@@ -0,0 +1,128 @@
+import { useContext, useState } from 'react';
+import { observer } from 'mobx-react';
+import { StatisticCard } from '@ant-design/pro-components';
+import { RingProgress, Progress, Bullet, } from '@ant-design/plots';
+import RcResizeObserver from 'rc-resize-observer';
+import { stores_Context } from '../config';
+import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
+import { Table } from 'antd';
+
+const { Statistic, Divider } = StatisticCard;
+
+export default observer((props) => {
+ const { icon, traditional, biz, kpiVal, originVal, ...extProps } = props;
+ const ValueIcon = props.icon;
+ const valueStyle = { color: (props?.VSrate || -1) < 0 ? '#3f8600' : '#cf1322' };
+ const VSIcon = () => ((props?.VSrate || -1) < 0 ? : );
+ console.log(props, ';;;;');
+ const [responsive, setResponsive] = useState(false);
+ const bulletData = [
+ {
+ title: '',
+ // ranges: [0, kpiVal || (traditional.value + biz.value + 100 )],
+ ranges: [0, Math.ceil(originVal*1.1)],
+ measures: [traditional.value, biz.value],
+ target: kpiVal || 0,
+ },
+ ];
+ console.log(bulletData, 'bbbbbbbbb');
+
+ const RingProgressConfigBlue = {
+ height: 60,
+ width: 60,
+ autoFit: false,
+ color: ['#5B8FF9', '#E8EDF3'],
+ label: false,
+ };
+ const RingProgressConfigGreen = {
+ height: 50,
+ width: 50,
+ autoFit: false,
+ // color: ['#f6bd16', '#E8EDF3'],
+ color: ['#61ddaa', '#E8EDF3'], // #7cb305
+ // innerRadius: 0.90,
+ };
+
+ const bulletConfig = {
+ // data,
+ measureField: 'measures',
+ rangeField: 'ranges',
+ targetField: 'target',
+ xField: 'title',
+ // autoFit: false,
+ // width: 20,
+ height: 60,
+ // renderer: 'svg',
+ color: {
+ range: [ '#E8EDF3', '#FFF3E1'],
+ // range: ['#FFbcb8', '#FFe0b0', '#bfeec8'],
+ measure: ['#5B8FF9', '#61DDAA'],
+ target: '#39a3f4',
+ },
+ label: {
+ measure: {
+ position: 'middle',
+ style: {
+ fill: '#fff',
+ },
+ },
+ },
+ xAxis: {
+ line: null,
+ label: false,
+ },
+ yAxis: false,
+ tooltip: false,
+ // 自定义 legend
+ legend: false,
+ };
+ return (
+ {
+ setResponsive(offset.width < 596);
+ }}
+ >
+
+ ,
+ }}
+ chart={}
+ />
+ {false && <>
+ {/* {props.childrenVisible && <> */}
+
+ ,
+ }}
+ chart={}
+ chartPlacement="left"
+ />
+ ,
+ }}
+ chart={
}
+ chartPlacement="left"
+ />
+ >}
+
+
+ );
+});
diff --git a/src/stores/Trade.js b/src/stores/Trade.js
index 5524272..5dab423 100644
--- a/src/stores/Trade.js
+++ b/src/stores/Trade.js
@@ -12,43 +12,72 @@ class Trade {
/**
* 年度总额
*/
- fetchSummaryData(queryData) {
+ async fetchSummaryData(queryData) {
this.summaryData.loading = true;
queryData.groupType = queryData?.groupType || 'overview';
queryData.groupDateType = 'year';
- this.fetchTradeData(queryData).then((json) => {
- if (json.errcode === 0) {
+ const multiData = await this.fetchTradeDataAll(queryData);
+ console.log(multiData, 'mmmmmmmm', queryData);
+ // this.fetchTradeData(queryData).then((json) => {
+ const { summary, traditional, biz } = multiData.result1;
+ const summaryData = {
+ loading: false,
+ dataSource: [
+ {
+ title: '成团',
+ value: summary?.[0]?.ConfirmOrder,
+ originVal: (summary?.[0]?.ConfirmOrder || 0),
+ valueSuffix: summary?.[0]?.ConfirmRates ? ` / ${summary?.[0]?.ConfirmRates} %` : undefined,
+ // VSrate: summary?.[0]?.ConfirmOrderrate,
+ KPIrate: summary?.[0]?.[dataFieldAlias.ConfirmOrder.nestkey.p],
+ // hasKPI: !isEmpty(summary?.[0]?.[dataFieldAlias.ConfirmOrder.nestkey.p]),
+ hasKPI: false,
+ childrenVisible: true,
+ kpiVal: summary?.[0]?.[dataFieldAlias.ConfirmOrder.nestkey.v],
+ traditional: { title: '传统', value: traditional?.[0]?.ConfirmOrder },
+ biz: { title: '商务', value: biz?.[0]?.ConfirmOrder },
+ },
+ {
+ title: '毛利',
+ originVal: (summary?.[0]?.SumML || 0),
+ value: dataFieldAlias.SumML.formatter(summary?.[0]?.SumML || 0) + '=' + dataFieldAlias.SumML.formatter((traditional?.[0]?.SumML || 0)) + '+' + dataFieldAlias.SumML.formatter((biz?.[0]?.SumML || 0)),
+ KPIrate: summary?.[0]?.[dataFieldAlias.SumML.nestkey.p],
+ hasKPI: false,
+ childrenVisible: true,
+ kpiVal: summary?.[0]?.[dataFieldAlias.SumML.nestkey.v],
+ traditional: { title: '传统', value: (traditional?.[0]?.SumML || 0) },
+ biz: { title: '商务', value: (biz?.[0]?.SumML || 0) },
+ },
+ {
+ title: '完成率',
+ originVal: (summary?.[0]?.[dataFieldAlias.SumML.nestkey.p] || 0),
+ value: `${summary?.[0]?.[dataFieldAlias.SumML.nestkey.p] || ''}%`,
+ hasKPI: false,
+ childrenVisible: false,
+ kpiVal: 0 , // summary?.[0]?.[dataFieldAlias.SumML.nestkey.p],
+ traditional: { title: '传统', value: traditional?.[0]?.[dataFieldAlias.SumML.nestkey.p] || 0, },
+ biz: { title: '商务', value: biz?.[0]?.[dataFieldAlias.SumML.nestkey.p] || 0, },
+ },
+ {
+ title: '人数',
+ originVal: (summary?.[0]?.SumPersonNum || 0),
+ value: summary?.[0]?.SumPersonNum,
+ // VSrate: summary?.[0]?.SumPersonNumrate,
+ // KPIrate: summary?.[0]?.[dataFieldAlias.SumPersonNum.nestkey.p],
+ hasKPI: false, // // !isEmpty(summary?.[0]?.[dataFieldAlias.SumPersonNum.nestkey.p]),,
+ childrenVisible: true,
+ // kpiVal: summary?.[0]?.[dataFieldAlias.SumPersonNum.nestkey.v],
+ traditional: { title: '传统', value: traditional?.[0]?.SumPersonNum, },
+ biz: { title: '商务', value: biz?.[0]?.SumPersonNum, },
+ },
+ ],
+ };
runInAction(() => {
- const summary = json.result1?.[0] || {};
- const summaryData = {
- loading: false,
- dataSource: [
- {
- title: '成团',
- value: summary?.ConfirmOrder,
- valueSuffix: summary?.ConfirmRates ? ` / ${summary.ConfirmRates} %` : undefined,
- // VSrate: summary?.ConfirmOrderrate,
- KPIrate: summary?.[dataFieldAlias.ConfirmOrder.nestkey.p],
- // hasKPI: !isEmpty(summary?.[dataFieldAlias.ConfirmOrder.nestkey.p]),
- hasKPI: false
- },
- { title: '毛利', value: dataFieldAlias.SumML.formatter(summary?.SumML || 0), KPIrate: summary?.[dataFieldAlias.SumML.nestkey.p], hasKPI: false },
- { title: '完成率', value: `${summary?.[dataFieldAlias.SumML.nestkey.p] || ''}%`, hasKPI: false },
- {
- title: '人数',
- value: summary?.SumPersonNum,
- // VSrate: summary?.SumPersonNumrate,
- // KPIrate: summary?.[dataFieldAlias.SumPersonNum.nestkey.p],
- hasKPI: false, // // !isEmpty(summary?.[dataFieldAlias.SumPersonNum.nestkey.p]),
- },
- ],
- };
this.summaryData = summaryData;
- const kpi = { label: '', value: summary.MLKPIvalue };
+ const kpi = { label: '', value: summary?.[0]?.MLKPIvalue };
this.summaryData.kpi = kpi;
});
- }
- });
+ // });
}
/**
@@ -157,14 +186,56 @@ class Trade {
}
/**
- * 获取业绩数据
+ * 获取业绩数据: 传统订单
*/
async fetchTradeData(queryData) {
const json = await req.fetchJSON('/service-Analyse2/GetTradeProcess', queryData);
- if (json.errcode === 0) {
- return json;
- }
- return null;
+ // if (json.errcode === 0) {
+ // return json;
+ // }
+ return json;
+ }
+
+ /**
+ * 获取业绩数据: 商务订单
+ */
+ async fetchTradeDataBiz(queryData) {
+ const json = await req.fetchJSON('/service-Analyse2/GetTradeProcess_biz', queryData);
+ // if (json.errcode === 0) {
+ // return json;
+ // }
+ return json;
+ }
+
+ /**
+ * 合并传统和商务
+ */
+ async fetchTradeDataAll(queryData) {
+ const traditional = await this.fetchTradeData(queryData);
+ const biz = await this.fetchTradeDataBiz(queryData);
+ const rr = ['result1', 'result2'].reduce((res, resKey) => {
+ const mergeItem = { traditional: traditional[resKey], biz: biz[resKey] };
+ const mergeRes = [].concat(traditional[resKey], biz[resKey]);
+ // const kpiKeys = [];
+ const groupsData = mergeRes.reduce((r, v) => {
+ if (v.groupsLabel ) {
+ (r[v.groupsLabel] || (r[v.groupsLabel] = [])).push(v);
+ }
+ return r;
+ }, {});
+ const summary = Object.keys(groupsData).map(groupsKey => {
+ return ['ConfirmOrder', 'SumOrder', 'SumML', 'transactions', 'SumPersonNum'].reduce(
+ (r, skey) => ({ ...r, [skey]: groupsData[groupsKey].reduce((a, c) => a + c[skey], 0) }),
+ groupsData[groupsKey]?.[0] || {}
+ );
+ }).map(row => ({...row,
+ ConfirmRates: fixTo2Decimals((row.ConfirmOrder/row.SumOrder)*100),
+ MLKPIrates: fixTo2Decimals((row.SumML/row.MLKPIvalue)*100),
+ // todo:
+ }));
+ return Object.assign(res, { [resKey]: Object.assign({}, mergeItem, { summary }) });
+ }, {});
+ return rr;
}
/**
diff --git a/src/views/Home.jsx b/src/views/Home.jsx
index d798a40..c60c94a 100644
--- a/src/views/Home.jsx
+++ b/src/views/Home.jsx
@@ -5,6 +5,7 @@ import { CheckCircleTwoTone, MoneyCollectTwoTone, FlagTwoTone, SmileTwoTone } fr
import { stores_Context } from '../config';
import { useNavigate } from 'react-router-dom';
import StatisticCard from '../components/StatisticCard';
+import StatisticCard2 from '../components/StatisticCard2';
import Bullet from '../components/BulletWithSort';
import Waterfall from '../components/Waterfall';
import LineWithKPI from '../components/LineWithKPI';
@@ -54,7 +55,7 @@ export default observer(() => {
TradeStore.fetchTradeDataByDate(queryData);
TradeStore.fetchTradeDataByBU(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);
setOverviewFlag(_overviewFlag);
for (const iterator of topSeriesF) {
@@ -154,7 +155,7 @@ export default observer(() => {
tooltip: {
customItems: (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 : dataFieldAlias[key]?.alias || key }));
return items;
},
},
@@ -165,7 +166,7 @@ export default observer(() => {
setDateField(value);
TradeStore.setTimeLineKey(value);
if (!isEmpty(TradeStore.searchPayloadHome)) {
- TradeStore.fetchTradeDataByDate({groupType: groupTypeVal});
+ TradeStore.fetchTradeDataByDate({ groupType: groupTypeVal });
}
};
return (
@@ -194,14 +195,19 @@ export default observer(() => {
- 年度业绩
+ 年度业绩=传统+商务
- {summaryData.dataSource.map((item, i) => (
+ {/* {summaryData.dataSource.map((item, i) => (
+ ))} */}
+ {summaryData.dataSource.map((item, i) => (
+
+
+
))}