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.jsx

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 !== '' && (
<>
&nbsp;&nbsp;
<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);