主页: 总额: +商务数据

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

@ -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 ? <ArrowDownOutlined /> : <ArrowUpOutlined />);
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 (
<RcResizeObserver
key="resize-observer"
onResize={(offset) => {
setResponsive(offset.width < 596);
}}
>
<StatisticCard.Group direction={responsive ? 'column' : 'row'}>
<StatisticCard
statistic={{
className: '__hn-sta-wrapper',
valueStyle,
...extProps,
value: props.valueSuffix ? `${props.value} ${props.valueSuffix}` : props.value,
prefix: <ValueIcon twoToneColor="#89B67F" />,
}}
chart={<Bullet data={bulletData} {...bulletConfig} layout={'horizontal'} />}
/>
{false && <>
{/* {props.childrenVisible && <> */}
<Divider type={responsive ? 'horizontal' : 'vertical'} />
<StatisticCard
statistic={{
className: '__hn-sta-wrapper',
valueStyle,
// title: '',
// value: 3701928,
value: props.traditional.value,
// description: <Statistic title="" value="61.5%" />,
}}
chart={<RingProgress {...RingProgressConfigBlue} percent={0.7} statistic={{title: false,}} />}
chartPlacement="left"
/>
<StatisticCard
statistic={{
className: '__hn-sta-wrapper',
valueStyle,
value: props.biz.value,
// title: '',
// value: 1806062,
description: <Statistic title="占比" value="38.5%" />,
}}
chart={<img src="https://gw.alipayobjects.com/zos/alicdn/6YR18tCxJ/huanlv.svg" alt="百分比" width="100%" />}
chartPlacement="left"
/>
</>}
</StatisticCard.Group>
</RcResizeObserver>
);
});

@ -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;
}
/**

@ -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(() => {
</Row>
<section>
<Space>
<h2>年度业绩</h2>
<h2>年度业绩=传统+商务</h2>
</Space>
<Spin spinning={summaryData.loading}>
<Row gutter={layoutProps.gutter}>
{summaryData.dataSource.map((item, i) => (
{/* {summaryData.dataSource.map((item, i) => (
<Col {...layoutProps} key={item.title}>
<StatisticCard {...item} showProgress={item.hasKPI} icon={iconSets[i]} />
</Col>
))} */}
{summaryData.dataSource.map((item, i) => (
<Col {...layoutProps} key={item.title}>
<StatisticCard2 {...item} showProgress={item.hasKPI} icon={iconSets[i]} />
</Col>
))}
</Row>
</Spin>

Loading…
Cancel
Save