顾问业绩跟踪

feature/2.0-sales-trade
Lei OT 2 years ago
parent fd76e36cd1
commit f53e89f4ae

@ -4,6 +4,7 @@ import * as config from '../config';
import * as comm from '../utils/commons';
import { NavLink } from 'react-router-dom';
import { groupsMappedByCode, dataFieldAlias } from './../libs/ht';
import * as req from '../utils/request';
// 销售数据
class SaleStore {
@ -29,6 +30,8 @@ class SaleStore {
type_data_sub = []; // 类型的子维度数据
date_title = 'date_title'; // 日期段,只用于显示,防止日期选择控件的变化导致页面刷新
salesTrade = { loading: false, operator: [], dept: [], overview: [] };
// 是否包含门票
handleChange_include_tickets = (value) => {
this.include_tickets = value;
@ -489,6 +492,38 @@ class SaleStore {
console.log('fetch data failed', error);
});
}
async fetchOperatorTradeData(groupType, queryData) {
this.salesTrade.loading = true;
const param1 = Object.assign(queryData, {groupType, groupDateType: 'year' });
const yearData = await this.fetchTradeData(param1);
const yData = parseSaleData(yearData, ['groupsKey', 'groupDateType']);
const param2 = Object.assign(queryData, {groupType, groupDateType: 'month' });
const monthData = await this.fetchTradeData(param2);
const mData = parseSaleData(monthData, ['groupsKey', 'groupDateType']);
const mergeYearMonth = Object.keys(yData).map(ykey => ({
...yData[ykey],
mData: mData[ykey].data,
yData: Object.values(yData[ykey].data)[0],
data: undefined,
}));
console.log(mergeYearMonth, ';;;;;;;;;;');
runInAction(() => {
this.salesTrade.loading = false;
this.salesTrade[groupType] = mergeYearMonth;
});
}
/**
* 获取业绩数据
*/
async fetchTradeData(queryData) {
const json = await req.fetchJSON('/service-Analyse2/GetTradeProcess', queryData);
if (json.errcode === 0) {
return json.result1;
}
return [];
}
}
const calcDiff = ({ result1 , result2 }) => {
@ -512,4 +547,29 @@ const calcDiff = ({ result1 , result2 }) => {
return afterCalc;
};
const parseSaleData = (res, keyArr = []) => {
const result = res.map((row) => ({
...row,
yearIndex: moment(row.start_date).year(),
}));
const byYear = comm.groupBy(result, (ele) => ele.yearIndex);
let ret = {};
const [key0, key1] = keyArr;
Object.keys(byYear).map((_yearVal) => {
const _subjectRet = comm.groupBy(byYear[_yearVal], (ele) => `${ele[key0]}`);
const afterGroup = Object.keys(_subjectRet).reduce((r, oID) => {
const isYear = _subjectRet[oID][0].groupDateType === 'year';
const data = (_subjectRet[oID] || []).map((ele) => ({ ...ele, 'dateVal': isYear ? ele.groupDateVal : moment(ele.groupDateVal).format('MM') }));
// const mappedData = comm.groupBy(data, ele => `${ele.groupDateType}_${ele.dateVal}`);
const mappedData = data.reduce((rd, ele) => ({...rd, [`${ele.groupDateType}_${ele.dateVal}`]: ele}), {});
const row = comm.pick(_subjectRet[oID][0], ['groupDateType', 'groupType', 'groupsKey', 'groupsLabel']);
// return {...row, data};
return { ...r, [oID]: { ...row, data: mappedData } };
}, {});
ret = afterGroup;
return afterGroup;
});
return ret;
};
export default SaleStore;

@ -1,5 +1,5 @@
import React, { useContext, useEffect } from 'react';
import { Row, Col, Button, Tabs, Table, Divider, Radio, Select } from 'antd';
import React, { useContext, useEffect, useState } from 'react';
import { Row, Col, Button, Tabs, Table, Divider, Radio, Select, Space, Typography, Progress } from 'antd';
import { ContainerOutlined, SearchOutlined, UserSwitchOutlined } from '@ant-design/icons';
import { stores_Context } from '../config';
import { observer } from 'mobx-react';
@ -8,15 +8,81 @@ import * as comm from '../utils/commons';
import * as config from '../config';
import { utils, writeFileXLSX } from 'xlsx';
import SearchForm from './../components/search/SearchForm';
import { dataFieldAlias } from '../libs/ht';
const { Text } = Typography;
const Sale_KPI = () => {
const { sale_store, date_picker_store: searchFormStore } = useContext(stores_Context);
const { formValues } = searchFormStore;
const { loading, operator } = sale_store.salesTrade;
const [groupType, setGroupType] = useState('dept');
const dataSource = [].concat(sale_store.salesTrade[groupType], operator);
const pageRefresh = (queryData) => {
const overviewFlag = queryData.DepartmentList.toLowerCase() === 'all' || queryData.DepartmentList.toLowerCase().includes(',');
queryData.groupType = overviewFlag ? 'overview' : 'dept';
const _groupType = overviewFlag ? 'overview' : 'dept';
setGroupType(_groupType);
sale_store.fetchOperatorTradeData(_groupType, { ...queryData, groupDateType: 'year' });
sale_store.fetchOperatorTradeData('operator', { ...queryData, groupDateType: 'year' });
};
const monthCol = new Array(12).fill(1).map((_, index) => {
return {
title: `${index + 1}`,
dataIndex: `M${index + 1}Percent`,
valueType: 'digit',
width: '7.5em',
render: (_, row) => (
<Space direction={'vertical'}>
<div>
<Text italic type={'secondary'}>
{dataFieldAlias.SumML.formatter(row.mData[`month_${String(index + 1).padStart(2, '0')}`]?.MLKPIvalue || 0)}
</Text>
</div>
<div>{dataFieldAlias.SumML.formatter(row.mData[`month_${String(index + 1).padStart(2, '0')}`]?.SumML || 0)}</div>
{row.mData[`month_${String(index + 1).padStart(2, '0')}`]?.MLKPIrates || 0 ? (
<Progress
percent={row.mData[`month_${String(index + 1).padStart(2, '0')}`]?.MLKPIrates || 0}
size="small"
format={(percent) => `${row.mData[`month_${String(index + 1).padStart(2, '0')}`]?.MLKPIrates || 0}%`}
/>
) : (
'-'
)}
</Space>
),
};
});
const columns = [
{
title: ``,
dataIndex: 'groupsLabel',
editable: false,
width: '7.5em',
},
{
title: '年度',
dataIndex: 'yearValue',
width: '10em',
render: (_, row) => (
<Space direction={'vertical'}>
<div>
<Text italic type={'secondary'}>
<span style={{ marginRight: '.5em' }}>目标</span>
{dataFieldAlias.SumML.formatter(row.yData?.MLKPIvalue || 0)}
</Text>
</div>
<div>
<span style={{ marginRight: '.5em' }}>完成</span>
{dataFieldAlias.SumML.formatter(row.yData?.SumML || 0)}
</div>
{row.yData?.MLKPIrates || 0 ? <Progress percent={row.yData?.MLKPIrates || 0} size="small" format={(percent) => `${row.yData?.MLKPIrates || 0}%`} /> : '-'}
</Space>
),
},
...monthCol,
];
return (
<div>
<Row gutter={16} style={{ margin: '-16px -8px' }}>
@ -41,7 +107,19 @@ const Sale_KPI = () => {
</Row>
<Row>
<Col className="gutter-row" md={24}></Col>
<Col className="gutter-row" md={24}>
<Table
key={`salesTradeTable`}
loading={loading}
columns={columns}
rowKey="groupsKey"
scroll={{
x: 1000,
}}
dataSource={dataSource}
pagination={false}
/>
</Col>
</Row>
</div>
);

Loading…
Cancel
Save