You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dashboard/src/charts/Customer_care_regular_pivot...

203 lines
9.4 KiB
React

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);