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
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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