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.
445 lines
14 KiB
JavaScript
445 lines
14 KiB
JavaScript
import React, { useContext, useState, useEffect } from 'react';
|
|
import { Row, Col, Divider, Table, Tooltip } from 'antd';
|
|
import { InfoCircleOutlined } from '@ant-design/icons';
|
|
import { utils, writeFileXLSX } from 'xlsx';
|
|
import { stores_Context } from '../config';
|
|
import { observer } from 'mobx-react';
|
|
import SearchForm from './../components/search/SearchForm';
|
|
import LineWithAvg from '../components/LineWithAvg';
|
|
import { toJS } from 'mobx';
|
|
import { TableExportBtn, RenderVSDataCell } from '../components/Data';
|
|
|
|
import useCustomerRelationsStore from '../zustand/CustomerRelations';
|
|
import { useShallow } from 'zustand/shallow';
|
|
import { fixTo2Decimals, isEmpty } from '@haina/utils-commons';
|
|
|
|
const Customer_care_regular = () => {
|
|
const { date_picker_store, customer_store } = useContext(stores_Context);
|
|
const regular_data = customer_store.regular_data;
|
|
|
|
const [loading, loading2, searchValues, searchValuesToSub] = useCustomerRelationsStore(useShallow((state) => [state.loading, state.loading2, state.searchValues, state.searchValuesToSub]));
|
|
const [setSearchValues] = useCustomerRelationsStore(useShallow((state) => [state.setSearchValues]));
|
|
|
|
const [regular] = useCustomerRelationsStore(useShallow((state) => [state.regular]));
|
|
|
|
const getRegularCustomer = useCustomerRelationsStore((state) => state.getRegularCustomer);
|
|
|
|
const columns = [
|
|
{
|
|
title: '订单号',
|
|
dataIndex: 'COLI_ID',
|
|
key: 'COLI_ID',
|
|
},
|
|
{
|
|
title: '预定日期',
|
|
dataIndex: 'COLI_ApplyDate',
|
|
key: 'COLI_ApplyDate',
|
|
},
|
|
{
|
|
title: '订单状态',
|
|
width: '4rem',
|
|
dataIndex: 'OrderState1',
|
|
key: 'OrderState1',
|
|
render: (text, record) => record.OrderState === 1 ? '成行' : '未成行',
|
|
sorter: (a, b) => b.OrderState - a.OrderState,
|
|
},
|
|
{
|
|
title: '毛利',
|
|
dataIndex: 'ML',
|
|
key: 'ML',
|
|
},
|
|
{
|
|
title: '人数',
|
|
dataIndex: 'PersonNum',
|
|
key: 'PersonNum',
|
|
},
|
|
{
|
|
title: '天数',
|
|
dataIndex: 'COLI_Days',
|
|
key: 'COLI_Days',
|
|
},
|
|
{
|
|
title: '人天数',
|
|
dataIndex: 'CGI_PersonDays',
|
|
key: 'CGI_PersonDays',
|
|
},
|
|
{
|
|
title: '走团日期',
|
|
dataIndex: 'COLI_OrderStartDate',
|
|
key: 'COLI_OrderStartDate',
|
|
},
|
|
{
|
|
title: '走团国家',
|
|
dataIndex: 'recommend_country',
|
|
key: 'recommend_country',
|
|
width: '4em',
|
|
},
|
|
{
|
|
title: '经过城市',
|
|
dataIndex: 'PassCity_This',
|
|
key: 'PassCity_This',
|
|
},
|
|
{
|
|
title: '小组',
|
|
dataIndex: 'Department',
|
|
key: 'Department',
|
|
},
|
|
{
|
|
title: '老客户',
|
|
dataIndex: 'COLI_IsOld',
|
|
key: 'COLI_IsOld',
|
|
},
|
|
{
|
|
title: '老客户推荐',
|
|
dataIndex: 'COLI_IsCusCommend',
|
|
key: 'COLI_IsCusCommend',
|
|
},
|
|
{
|
|
title: '国籍',
|
|
dataIndex: 'MEI_Country',
|
|
key: 'MEI_Country',
|
|
},
|
|
{
|
|
title: '网站',
|
|
dataIndex: 'COLI_WebCode',
|
|
key: 'COLI_WebCode',
|
|
},
|
|
{
|
|
title: '来源',
|
|
dataIndex: 'SourceType',
|
|
key: 'SourceType',
|
|
},
|
|
{
|
|
title: '页面类型',
|
|
dataIndex: 'COLI_LineClass',
|
|
key: 'COLI_LineClass',
|
|
},
|
|
{
|
|
title: '产品类型',
|
|
dataIndex: 'TourType_Name',
|
|
key: 'TourType_Name',
|
|
},
|
|
{
|
|
title: '券额',
|
|
dataIndex: 'Voucher_amount',
|
|
key: 'Voucher_amount',
|
|
width: '4em',
|
|
},
|
|
{
|
|
title: '券类别',
|
|
dataIndex: 'Voucher_type',
|
|
key: 'Voucher_type',
|
|
width: '5em',
|
|
},
|
|
{
|
|
title: '上次 订单号',
|
|
dataIndex: 'coli_id_Last',
|
|
key: 'coli_id_Last',
|
|
width: '5em',
|
|
onCell: (r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' },
|
|
}),
|
|
},
|
|
{
|
|
title: '上次 走团日期',
|
|
dataIndex: 'COLI_OrderStartDate_Last',
|
|
key: 'COLI_OrderStartDate_Last',
|
|
width: '4em',
|
|
onCell: (_, r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' } ,
|
|
}),
|
|
},
|
|
{
|
|
title: '上次 小组',
|
|
dataIndex: 'Department_Last',
|
|
key: 'Department_Last',
|
|
width: '4em',
|
|
onCell: (_, r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' } ,
|
|
}),
|
|
},
|
|
];
|
|
const export_columns = [].concat(columns, [
|
|
{
|
|
title: '上次经过国家',
|
|
dataIndex: 'last_country',
|
|
key: 'last_country',
|
|
onCell: (r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' },
|
|
}),
|
|
},
|
|
{
|
|
title: '上次经过城市',
|
|
dataIndex: 'PassCity_Last',
|
|
key: 'PassCity_Last',
|
|
onCell: (r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' },
|
|
}),
|
|
},
|
|
{
|
|
title: '复购周期',
|
|
dataIndex: 'Repurchase_cycle',
|
|
key: 'Repurchase_cycle',
|
|
width: '4em',
|
|
onCell: (_, r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' },
|
|
}),
|
|
},
|
|
{
|
|
title: '下单次数',
|
|
dataIndex: 'Orders_number',
|
|
key: 'Orders_number',
|
|
width: '4em',
|
|
onCell: (_, r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' },
|
|
}),
|
|
},
|
|
{
|
|
title: '推荐次数',
|
|
dataIndex: 'recommend_time',
|
|
key: 'recommend_time',
|
|
width: '4em',
|
|
onCell: (_, r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' },
|
|
}),
|
|
},
|
|
{
|
|
title: '历史成行次数',
|
|
dataIndex: 'Travel_count',
|
|
key: 'Travel_count',
|
|
width: '4em',
|
|
onCell: (_, r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' },
|
|
}),
|
|
},
|
|
{
|
|
title: '旅行周期',
|
|
dataIndex: 'Travel_cycle',
|
|
key: 'Travel_cycle',
|
|
width: '4em',
|
|
onCell: (_, r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' },
|
|
}),
|
|
},
|
|
{
|
|
title: '第1次走团日期',
|
|
dataIndex: 'firstStartdate',
|
|
key: 'firstStartdate',
|
|
width: '4em',
|
|
onCell: (_, r) => ({
|
|
style: { backgroundColor: '#5B8FF9' + '1A' },
|
|
}),
|
|
},
|
|
]);
|
|
|
|
return (
|
|
<div>
|
|
<Row gutter={16} className={toJS(date_picker_store.siderBroken) ? '' : 'sticky-top'}>
|
|
<Col className="gutter-row" span={24}>
|
|
<SearchForm
|
|
defaultValue={{
|
|
initialValue: {
|
|
...toJS(date_picker_store.formValues),
|
|
// ...toJS(regular_data.searchValues),
|
|
...searchValues,
|
|
},
|
|
shows: ['DateType', 'DepartmentList', 'WebCode', 'dates', 'IncludeTickets'],
|
|
fieldProps: {
|
|
DepartmentList: { show_all: false, mode: 'multiple' },
|
|
WebCode: { show_all: false, mode: 'multiple' },
|
|
years: { hide_vs: true },
|
|
},
|
|
}}
|
|
onSubmit={async (_err, obj, form, str) => {
|
|
customer_store.setSearchValues(obj, form, 'regular_data');
|
|
setSearchValues(obj, form);
|
|
getRegularCustomer({ ...obj, IsDetail: 0 });
|
|
getRegularCustomer({ ...obj, IsDetail: 1 });
|
|
|
|
// regular_data.data_compare=[];
|
|
// if (obj.DateDiff1 && obj.DateDiff2){
|
|
// regular_data.isCompareLine=true;
|
|
// regular_data.showCompareSum=true;
|
|
// await customer_store.regular_customer_order();
|
|
// customer_store.regular_customer_order(false,true);
|
|
// // customer_store.regular_customer_order(true,false,true);
|
|
// customer_store.regular_customer_order(true,true,true);
|
|
// }
|
|
// else{
|
|
// regular_data.isCompareLine=false;
|
|
// regular_data.showCompareSum=false;
|
|
// customer_store.regular_customer_order();
|
|
// customer_store.regular_customer_order(true);
|
|
// }
|
|
}}
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
<Row gutter={16}>
|
|
<Col span={24}>
|
|
<h2>老客户</h2>
|
|
</Col>
|
|
<Col span={24}>
|
|
<Table
|
|
dataSource={regular.data}
|
|
loading={loading}
|
|
columns={[
|
|
{
|
|
title: '统计条目',
|
|
dataIndex: 'ItemName',
|
|
key: 'ItemName',
|
|
},
|
|
{
|
|
title: () => (
|
|
<>
|
|
订单数{' '}
|
|
<Tooltip key="total_data_tips_title" title="总订单: 当同时勾选老客户和推荐时, 将重复计数">
|
|
<InfoCircleOutlined />
|
|
</Tooltip>
|
|
</>
|
|
),
|
|
dataIndex: 'OrderNum',
|
|
key: 'OrderNum',
|
|
render: (text, record, index) => (
|
|
<>
|
|
<RenderVSDataCell showDiffData={!isEmpty(searchValuesToSub.DateDiff1)} data1={record.OrderNum} data2={record.diff?.OrderNum} />
|
|
{index === 0 && regular.total_data_tips !== '' && (
|
|
<>
|
|
|
|
<Tooltip key="total_data_tips" title={regular.total_data_tips}>
|
|
<InfoCircleOutlined className="ant-tag-gold" />
|
|
</Tooltip>
|
|
</>
|
|
)}
|
|
</>
|
|
),
|
|
},
|
|
{
|
|
title: '订单数占比',
|
|
dataIndex: 'OrderRate',
|
|
key: 'OrderRate',
|
|
render: (text, record) => (
|
|
<RenderVSDataCell
|
|
showDiffData={!isEmpty(searchValuesToSub.DateDiff1)}
|
|
data1={fixTo2Decimals(record.OrderRate * 100)}
|
|
data2={fixTo2Decimals(record.diff?.OrderRate * 100)}
|
|
dataSuffix="%"
|
|
/>
|
|
),
|
|
},
|
|
{
|
|
title: '订单数占比(市场)',
|
|
dataIndex: 'OrderRate2',
|
|
key: 'OrderRate2',
|
|
render: (text, record) => (
|
|
<RenderVSDataCell
|
|
showDiffData={!isEmpty(searchValuesToSub.DateDiff1)}
|
|
data1={fixTo2Decimals(record.OrderRate2 * 100)}
|
|
data2={fixTo2Decimals(record.diff?.OrderRate2 * 100)}
|
|
dataSuffix="%"
|
|
/>
|
|
),
|
|
},
|
|
{
|
|
title: '成行数',
|
|
dataIndex: 'SUCOrderNum',
|
|
key: 'SUCOrderNum',
|
|
render: (text, record) => <RenderVSDataCell showDiffData={!isEmpty(searchValuesToSub.DateDiff1)} data1={record.SUCOrderNum} data2={record.diff?.SUCOrderNum} />,
|
|
},
|
|
{
|
|
title: '成行率',
|
|
dataIndex: 'SUCRate',
|
|
key: 'SUCRate',
|
|
render: (text, record) => (
|
|
<RenderVSDataCell
|
|
showDiffData={!isEmpty(searchValuesToSub.DateDiff1)}
|
|
data1={fixTo2Decimals(record.SUCRate * 100)}
|
|
data2={fixTo2Decimals(record.diff?.SUCRate * 100)}
|
|
dataSuffix="%"
|
|
/>
|
|
),
|
|
},
|
|
{
|
|
title: '毛利',
|
|
dataIndex: 'ML',
|
|
key: 'ML',
|
|
render: (text, record) => <RenderVSDataCell showDiffData={!isEmpty(searchValuesToSub.DateDiff1)} data1={record.ML} data2={record.diff?.ML} />,
|
|
},
|
|
{
|
|
title: '毛利占比',
|
|
dataIndex: 'OrderMLRate',
|
|
key: 'OrderMLRate',
|
|
render: (text, record) => (
|
|
<RenderVSDataCell
|
|
showDiffData={!isEmpty(searchValuesToSub.DateDiff1)}
|
|
data1={fixTo2Decimals(record.OrderMLRate * 100)}
|
|
data2={fixTo2Decimals(record.diff?.OrderMLRate * 100)}
|
|
dataSuffix="%"
|
|
/>
|
|
),
|
|
},
|
|
{
|
|
title: '毛利占比(市场)',
|
|
dataIndex: 'OrderMLRate2',
|
|
key: 'OrderMLRate2',
|
|
render: (text, record) => (
|
|
<RenderVSDataCell
|
|
showDiffData={!isEmpty(searchValuesToSub.DateDiff1)}
|
|
data1={fixTo2Decimals(record.OrderMLRate2 * 100)}
|
|
data2={fixTo2Decimals(record.diff?.OrderMLRate2 * 100)}
|
|
dataSuffix="%"
|
|
/>
|
|
),
|
|
},
|
|
{
|
|
title: '人数(含成人+儿童)',
|
|
dataIndex: 'PersonNum',
|
|
key: 'PersonNum',
|
|
render: (text, record) => <RenderVSDataCell showDiffData={!isEmpty(searchValuesToSub.DateDiff1)} data1={record.PersonNum} data2={record.diff?.PersonNum} />,
|
|
},
|
|
]}
|
|
size="small"
|
|
pagination={false}
|
|
rowKey={(record) => record.ItemName}
|
|
/>
|
|
</Col>
|
|
|
|
<Col span={24}>
|
|
<div style={{ height: '100%' }}>
|
|
<Col span={24}>
|
|
<LineWithAvg
|
|
dataSource={regular.pivotData}
|
|
loading={loading2}
|
|
xField={regular.pivotX}
|
|
yField={regular.pivotY}
|
|
seriesField="_ylabel"
|
|
showCompareSum={false}
|
|
solidLineTime={false}
|
|
solidLineCompareTime={false}
|
|
solidLineDash={false}
|
|
isCompareLine={false}
|
|
/>
|
|
</Col>
|
|
|
|
<Col span={24}>
|
|
<Divider orientation="right" plain>
|
|
<a
|
|
onClick={() => {
|
|
const wb = utils.table_to_book(document.getElementById('table_to_xlsx').getElementsByTagName('table')[0]);
|
|
writeFileXLSX(wb, '老客户.xlsx');
|
|
}}
|
|
>
|
|
导出下表
|
|
</a>
|
|
<TableExportBtn btnTxt="导出详情" label={'老客户-详情'} columns={export_columns} dataSource={regular.details} style={{ marginLeft: '10px' }} />
|
|
</Divider>
|
|
<Table id="table_to_xlsx" pagination={false} loading={loading2} dataSource={regular.details} scroll={{ x: 1200 }} columns={columns} size="small" rowKey={(record) => record.COLI_ID} />
|
|
</Col>
|
|
</div>
|
|
</Col>
|
|
</Row>
|
|
</div>
|
|
);
|
|
};
|
|
export default observer(Customer_care_regular);
|