|
|
import { useContext, useEffect, useState } from 'react';
|
|
|
import { observer } from 'mobx-react';
|
|
|
import { stores_Context } from '../config';
|
|
|
import { Table, Row, Col, Divider, Switch, Space, Tabs } from 'antd';
|
|
|
import SearchForm from '../components/search/SearchForm';
|
|
|
import { TableExportBtn, VSTag } from '../components/Data';
|
|
|
import { fixTo2Decimals, isEmpty } from '../utils/commons';
|
|
|
|
|
|
// 注意TdCell要提到DataTable作用域外声明
|
|
|
const TdCell = (tdprops) => {
|
|
|
// onMouseEnter, onMouseLeave在数据量多的时候,会严重阻塞表格单元格渲染,严重影响性能
|
|
|
const { onMouseEnter, onMouseLeave, ...restProps } = tdprops;
|
|
|
return <td {...restProps} />;
|
|
|
};
|
|
|
|
|
|
const CustomerCareRegularPivot = (props) => {
|
|
|
const { date_picker_store: searchFormStore, customer_store } = useContext(stores_Context);
|
|
|
const { formValues, formValuesToSub, siderBroken } = searchFormStore;
|
|
|
const { pivotData: pageData } = customer_store.sales_regular_data;
|
|
|
|
|
|
const pivotOptions = [{key: 'operatorName', label: '顾问'}, {key: 'country', label: '国家'}];
|
|
|
const [pivotRow, setPivotRow] = useState('operatorName');
|
|
|
|
|
|
const onTabsChange = (key) => {
|
|
|
setPivotRow(key);
|
|
|
};
|
|
|
|
|
|
const [dataSource, setDataSource] = useState([]);
|
|
|
const [ifmerge, setIfmerge] = useState(false);
|
|
|
const [dataForExport, setDataForExport] = useState([]);
|
|
|
const [dataForExportS, setDataForExportS] = useState([]);
|
|
|
|
|
|
useEffect(() => {
|
|
|
if ( ! ifmerge) {
|
|
|
setDataSource(pageData[pivotRow].data);
|
|
|
setDataForExport(
|
|
|
pageData[pivotRow].data.reduce(
|
|
|
(r, c) =>
|
|
|
r.concat(
|
|
|
[{ ...c, children: undefined }],
|
|
|
c.children
|
|
|
.reduce((rc, ele) => rc.concat([{ ...ele, [pivotRow]: ele.rowLabel }], [{ ...ele.vsData, [pivotRow]: ele.vsData.rowLabel, vsData: {} }]), [])
|
|
|
.filter((ele) => ele.SumOrder !== undefined)
|
|
|
),
|
|
|
[]
|
|
|
)
|
|
|
);
|
|
|
setDataForExportS(pageData[pivotRow].data.reduce((r, c) => r.concat([{...c, children: undefined}], [{ ...c.vsData, vsData: {} }]), []).filter((ele) => ele.SumOrder !== undefined));
|
|
|
} else {
|
|
|
setDataSource(pageData[pivotRow].mergedData);
|
|
|
setDataForExport(
|
|
|
pageData[pivotRow].mergedData.reduce(
|
|
|
(r, c) =>
|
|
|
r.concat(
|
|
|
[{ ...c, children: undefined }],
|
|
|
c.children.reduce((rc, ele) => rc.concat([{ ...ele, operatorName: ele.rowLabel }], [{ ...ele.vsData, operatorName: ele.vsData.rowLabel, vsData: {} }]), [])
|
|
|
.filter((ele) => ele.SumOrder !== undefined)
|
|
|
),
|
|
|
[]
|
|
|
)
|
|
|
);
|
|
|
setDataForExportS(pageData[pivotRow].mergedData.reduce((r, c) => r.concat([{...c, children: undefined}], [{ ...c.vsData, vsData: {} }]), []).filter((ele) => ele.SumOrder !== undefined));
|
|
|
}
|
|
|
|
|
|
return () => {};
|
|
|
}, [ifmerge, pageData[pivotRow].data]);
|
|
|
|
|
|
|
|
|
const rowColumns = [
|
|
|
{ title: '日期区间', dataIndex: 'seriesKey', key: 'seriesKey' },
|
|
|
{ title: '顾问', dataIndex: 'operatorName', key: 'operatorName' },
|
|
|
{ title: '订单号', dataIndex: 'o_id', key: 'o_id' },
|
|
|
{ title: '预定日期', dataIndex: 'applyDate', key: 'applyDate' },
|
|
|
{ title: '订单状态', key: 'orderState', render: (_, r) => r.orderState === '1' ? '成行' : '', },
|
|
|
{ title: '毛利', dataIndex: 'ML', key: 'ML' },
|
|
|
{ title: '人数', dataIndex: 'personNum', key: 'personNum' },
|
|
|
{ title: '天数', dataIndex: 'tourdays', key: 'tourdays' },
|
|
|
// { title: '人天数', dataIndex: 'CGI_PersonDays', key: 'CGI_PersonDays' },
|
|
|
// { title: '走团日期', dataIndex: 'COLI_OrderStartDate', key: 'COLI_OrderStartDate' },
|
|
|
{ title: '小组', dataIndex: 'dept', key: 'dept' },
|
|
|
{ title: '老客户', key: 'IsOld', render: (_, r) => r.IsOld === '1' ? '是' : '' },
|
|
|
{ title: '老客户推荐', key: 'IsCusCommend', render: (_, r) => r.isCusCommend === '1' ? '是' : '' },
|
|
|
{ title: '网站', dataIndex: 'WebCode', key: 'WebCode' },
|
|
|
{ title: '来源', dataIndex: 'SourceType', key: 'SourceType' },
|
|
|
{ title: '页面类型', dataIndex: 'COLI_LineClass', key: 'COLI_LineClass' },
|
|
|
];
|
|
|
const calcDelta = (r, key) => !isEmpty(Number(r.vsData[key])) ? fixTo2Decimals((Number(r[key] || 0) - Number(r.vsData[key]))/Number(r.vsData[key]) *100) : null;
|
|
|
const renderVS = (v, r, key) => {
|
|
|
const delta = calcDelta(r, key);
|
|
|
return <>
|
|
|
<Space direction={'vertical'}>
|
|
|
<span>
|
|
|
{v || 0}
|
|
|
{r.vsData[key] ? <span type="secondary"> VS {r.vsData[key]}</span> : null}
|
|
|
</span>
|
|
|
{delta && <VSTag diffPercent={delta} />}
|
|
|
</Space>
|
|
|
</>;
|
|
|
};
|
|
|
const columns = [
|
|
|
{ key: 'SumOrder', title: '订单数', dataIndex: 'SumOrder', width: '5em', render: (v, r) => renderVS(v, r, 'SumOrder') },
|
|
|
{ key: 'ConfirmOrder', title: '成交数', dataIndex: 'ConfirmOrder', width: '5em', render: (v, r) => renderVS(v, r, 'ConfirmOrder') },
|
|
|
{ key: 'ConfirmPersonNum', title: '✔人数(SUM)', dataIndex: 'ConfirmPersonNum', width: '5em', render: (v, r) => renderVS(v, r, 'ConfirmPersonNum') },
|
|
|
{ key: 'confirmTourdays', title: '✔团天数(AVG)', dataIndex: 'confirmTourdays', width: '5em', render: (v, r) => renderVS(v, r, 'confirmTourdays') },
|
|
|
{ key: 'SumML', title: '预计毛利', dataIndex: 'SumML', width: '5em', render: (v, r) => renderVS(v, r, 'SumML') }, // SumML_txt
|
|
|
{ key: 'ConfirmRates', title: '成交率', dataIndex: 'ConfirmRates_txt', width: '5em', render: (v, r) => renderVS(v, r, 'ConfirmRates') },
|
|
|
{ key: 'SingleML', title: '单团毛利', dataIndex: 'SingleML', width: '5em', render: (v, r) => renderVS(v, r, 'SingleML') },
|
|
|
];
|
|
|
return (
|
|
|
<>
|
|
|
<Row gutter={16} className={siderBroken ? '' : 'sticky-top'}>
|
|
|
<Col className="gutter-row" span={24}>
|
|
|
<SearchForm
|
|
|
defaultValue={{
|
|
|
initialValue: {
|
|
|
...formValues,
|
|
|
...customer_store.sales_regular_data.searchValues,
|
|
|
},
|
|
|
shows: ['DateType', 'DepartmentList', 'WebCode', 'dates', 'IncludeTickets'],
|
|
|
fieldProps: {
|
|
|
DepartmentList: { show_all: false, mode: 'multiple' },
|
|
|
WebCode: { show_all: false, mode: 'multiple' },
|
|
|
dates: { hide_vs: false },
|
|
|
},
|
|
|
}}
|
|
|
onSubmit={(_err, obj, form, str) => {
|
|
|
customer_store.setSearchValues(obj, form, 'sales_regular_data');
|
|
|
customer_store.get_sales_regular_data_vs(obj, pivotRow);
|
|
|
}}
|
|
|
/>
|
|
|
</Col>
|
|
|
</Row>
|
|
|
<Tabs
|
|
|
type={'card'}
|
|
|
activeKey={pivotRow}
|
|
|
onChange={onTabsChange}
|
|
|
items={pivotOptions.map((ele) => {
|
|
|
return {
|
|
|
...ele,
|
|
|
children: (
|
|
|
<>
|
|
|
{/* <h2>{ele.label}-老客户, 含推荐</h2> */}
|
|
|
<>
|
|
|
<Divider orientation={'right'} style={{backgroundColor: '#fff', margin: 0, padding: '10px 0'}} >
|
|
|
{pageData[pivotRow].data.length > 0 && pivotRow === 'operatorName' && (
|
|
|
<Switch
|
|
|
unCheckedChildren="各账户"
|
|
|
checkedChildren="合并"
|
|
|
key={'openOrMerge'}
|
|
|
checked={ifmerge}
|
|
|
onChange={(e) => {
|
|
|
setIfmerge(e);
|
|
|
}}
|
|
|
/>
|
|
|
)}
|
|
|
<Divider type={'vertical'} />
|
|
|
<TableExportBtn
|
|
|
btnTxt="导出明细"
|
|
|
label={`${formValuesToSub.Date1}-老客户-明细`}
|
|
|
{...{ columns: [{ title: ele.label, dataIndex: pivotRow, key: pivotRow }, ...rowColumns], dataSource: pageData[pivotRow].rawData }}
|
|
|
/>
|
|
|
<Divider type={'vertical'} />
|
|
|
<TableExportBtn
|
|
|
btnTxt="导出下表-展开"
|
|
|
label={`${formValuesToSub.Date1}-${ele.label}.老客户`}
|
|
|
{...{ columns: [{ title: ele.label, dataIndex: pivotRow, key: pivotRow }, ...columns], dataSource: dataForExport }}
|
|
|
/>
|
|
|
<Divider type={'vertical'} />
|
|
|
<TableExportBtn
|
|
|
btnTxt="导出下表-总"
|
|
|
label={`${formValuesToSub.Date1}-${ele.label}.老客户`}
|
|
|
{...{ columns: [{ title: ele.label, dataIndex: pivotRow, key: pivotRow }, ...columns], dataSource: dataForExportS }}
|
|
|
/>
|
|
|
</Divider>
|
|
|
</>
|
|
|
<Table
|
|
|
sticky
|
|
|
dataSource={dataSource}
|
|
|
loading={pageData[ele.key].loading}
|
|
|
columns={[
|
|
|
{
|
|
|
key: ele.key,
|
|
|
title: ele.label,
|
|
|
dataIndex: ele.key,
|
|
|
width: '6em',
|
|
|
filters: pageData[ele.key].filterColValues,
|
|
|
onFilter: (value, record) => value.includes(record[ele.key]),
|
|
|
filterSearch: true,
|
|
|
},
|
|
|
...columns,
|
|
|
]}
|
|
|
pagination={false}
|
|
|
/>
|
|
|
</>
|
|
|
),
|
|
|
};
|
|
|
})}
|
|
|
/>
|
|
|
</>
|
|
|
);
|
|
|
};
|
|
|
export default observer(CustomerCareRegularPivot);
|