|
|
|
import React, { useContext, useEffect } from 'react';
|
|
|
|
import { Row, Col, Button, Tabs, Table, Divider, Radio, Select } from 'antd';
|
|
|
|
import { ContainerOutlined, SearchOutlined, UserSwitchOutlined } from '@ant-design/icons';
|
|
|
|
import { stores_Context } from '../config';
|
|
|
|
import { Column, Pie, Treemap } from '@ant-design/charts';
|
|
|
|
import { observer } from 'mobx-react';
|
|
|
|
import DatePickerCharts from '../components/search/DatePickerCharts';
|
|
|
|
import DataTypeSelect from '../components/search/DataTypeSelect';
|
|
|
|
import { NavLink, useParams } from 'react-router-dom';
|
|
|
|
import * as comm from '../utils/commons';
|
|
|
|
import * as config from '../config';
|
|
|
|
import SiteSelect from '../components/search/SiteSelect';
|
|
|
|
import GroupSelect from '../components/search/GroupSelect';
|
|
|
|
import { utils, writeFileXLSX } from 'xlsx';
|
|
|
|
|
|
|
|
const Sale = () => {
|
|
|
|
const { sale_store, date_picker_store } = useContext(stores_Context);
|
|
|
|
|
|
|
|
//const ml_data = sale_store.ml_data; // 毛利数据
|
|
|
|
const type_data = comm.empty(sale_store.type_data) ? { dataSource: [], columns: [] } : sale_store.type_data; // 毛利数据
|
|
|
|
|
|
|
|
// const column_config = {
|
|
|
|
// data: type_data.dataSource,
|
|
|
|
// xField: 'OPI_Name',
|
|
|
|
// yField: 'COLI_ML2',
|
|
|
|
// //seriesField: "OPI_Name",
|
|
|
|
// label: {
|
|
|
|
// position: 'top',
|
|
|
|
// },
|
|
|
|
// xAxis: {
|
|
|
|
// label: {
|
|
|
|
// autoHide: false,
|
|
|
|
// autoRotate: true,
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// // legend: {
|
|
|
|
// // itemValue: {
|
|
|
|
// // formatter: (text, item) => {
|
|
|
|
// // const items = ml_data.filter(d => d.groups === item.value); // 按分组筛选
|
|
|
|
// // return items.length ? items.reduce((a, b) => a + b.COLI_ML, 0) : ""; // 计算总数
|
|
|
|
// // },
|
|
|
|
// // },
|
|
|
|
// // },
|
|
|
|
// // tooltip: {
|
|
|
|
// // customContent: (title, items) => {
|
|
|
|
// // const data = items[0].data || {};console.log(data);
|
|
|
|
// // return `<div>${title}</div>wwwwwww<div></div>`;
|
|
|
|
// // },
|
|
|
|
// // title: (title, datum) => {
|
|
|
|
// // return title; // + " " + comm.getWeek(datum.COLI_Date); // 显示周几
|
|
|
|
// // },
|
|
|
|
// // },
|
|
|
|
// };
|
|
|
|
|
|
|
|
const column_config_create = (tab_name) => {
|
|
|
|
let average_value = 0; //平均线的值
|
|
|
|
let config_data = [];
|
|
|
|
switch (tab_name) {
|
|
|
|
case 'All':
|
|
|
|
config_data.data = type_data.dataSource;
|
|
|
|
config_data.xField = 'OPI_Name';
|
|
|
|
config_data.yField = 'COLI_ML2';
|
|
|
|
average_value = Math.round(config_data.data.reduce((a, b) => a + b.COLI_ML2, 0) / config_data.data.length);
|
|
|
|
break;
|
|
|
|
case 'ResponseRateWhatsApp':
|
|
|
|
config_data.data = type_data.dataSource;
|
|
|
|
config_data.xField = 'OPI_Name';
|
|
|
|
config_data.yField = 'COLI_ConfirmTimeAVG';
|
|
|
|
average_value = Math.round(config_data.data.reduce((a, b) => a + b.COLI_ConfirmTimeAVG, 0) / config_data.data.length);
|
|
|
|
break;
|
|
|
|
case 'ResponseRateByWL':
|
|
|
|
config_data.data = type_data.dataSource;
|
|
|
|
config_data.xField = 'OPI_Name';
|
|
|
|
config_data.yField = 'PriceTime';
|
|
|
|
average_value = Math.round(config_data.data.reduce((a, b) => a + b.PriceTime, 0) / config_data.data.length);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
config_data.data = [];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
...config_data,
|
|
|
|
...{
|
|
|
|
//seriesField: "OPI_Name",//分组
|
|
|
|
label: {
|
|
|
|
position: 'top',
|
|
|
|
},
|
|
|
|
xAxis: {
|
|
|
|
label: {
|
|
|
|
autoHide: false,
|
|
|
|
autoRotate: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// legend: {
|
|
|
|
// itemValue: {
|
|
|
|
// formatter: (text, item) => {
|
|
|
|
// const items = ml_data.filter(d => d.groups === item.value); // 按分组筛选
|
|
|
|
// return items.length ? items.reduce((a, b) => a + b.COLI_ML, 0) : ""; // 计算总数
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// tooltip: {
|
|
|
|
// customContent: (title, items) => {
|
|
|
|
// const data = items[0].data || {};console.log(data);
|
|
|
|
// return `<div>${title}</div>wwwwwww<div></div>`;
|
|
|
|
// },
|
|
|
|
// title: (title, datum) => {
|
|
|
|
// return title; // + " " + comm.getWeek(datum.COLI_Date); // 显示周几
|
|
|
|
// },
|
|
|
|
// },};
|
|
|
|
annotations: average_value
|
|
|
|
? [
|
|
|
|
{
|
|
|
|
type: 'text',
|
|
|
|
position: ['start', average_value],
|
|
|
|
content: average_value,
|
|
|
|
offsetX: -15,
|
|
|
|
style: {
|
|
|
|
fill: '#F4664A',
|
|
|
|
textBaseline: 'bottom',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'line',
|
|
|
|
start: [-10, average_value],
|
|
|
|
end: ['max', average_value],
|
|
|
|
style: {
|
|
|
|
stroke: '#F4664A',
|
|
|
|
lineDash: [2, 2],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]
|
|
|
|
: [],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const column_config = column_config_create(sale_store.active_tab_key);
|
|
|
|
|
|
|
|
// 直方图,先隐藏
|
|
|
|
// const format_data_for_treemap=(data=[])=>{
|
|
|
|
// const children_array= data.map(item => ({...item, name: item.OPI_Name,value:item.COLI_ML2}));
|
|
|
|
// return {
|
|
|
|
// name: 'root',
|
|
|
|
// children:children_array,
|
|
|
|
// };
|
|
|
|
// };
|
|
|
|
|
|
|
|
// const treemap_config={
|
|
|
|
// data:format_data_for_treemap(type_data.dataSource),
|
|
|
|
// colorField: 'OPI_Name',
|
|
|
|
// };
|
|
|
|
|
|
|
|
//格式化数据,饼图只支持数字模式
|
|
|
|
const format_data_for_pie = (data = []) => {
|
|
|
|
return data.map((item) => ({ ...item, COLI_ML_number: comm.price_to_number(item.COLI_ML) }));
|
|
|
|
};
|
|
|
|
|
|
|
|
const pie_config = {
|
|
|
|
appendPadding: 10,
|
|
|
|
data: format_data_for_pie(type_data.dataSource),
|
|
|
|
angleField: 'COLI_ML_number',
|
|
|
|
colorField: 'OPI_Name',
|
|
|
|
radius: 0.8,
|
|
|
|
label: {
|
|
|
|
type: 'outer',
|
|
|
|
content: '{name} {value} \n {percentage}',
|
|
|
|
},
|
|
|
|
legend: false, // 不显示图例
|
|
|
|
interactions: [
|
|
|
|
{
|
|
|
|
type: 'element-selected',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'element-active',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
|
|
|
|
<Col md={24} lg={12} xxl={14}></Col>
|
|
|
|
<Col md={24} lg={12} xxl={10}>
|
|
|
|
<Row>
|
|
|
|
<Col md={24} lg={8} xxl={8}>
|
|
|
|
<GroupSelect store={sale_store} />
|
|
|
|
</Col>
|
|
|
|
<Col md={24} lg={8} xxl={8}>
|
|
|
|
<SiteSelect store={sale_store} show_all={true} />
|
|
|
|
</Col>
|
|
|
|
<Col md={24} lg={8} xxl={8}>
|
|
|
|
<Select style={{ width: '100%' }} placeholder="是否含门票" value={sale_store.include_tickets} onChange={sale_store.handleChange_include_tickets}>
|
|
|
|
<Select.Option key="1" value="1">
|
|
|
|
含门票
|
|
|
|
</Select.Option>
|
|
|
|
<Select.Option key="0" value="0">
|
|
|
|
不含门票
|
|
|
|
</Select.Option>
|
|
|
|
</Select>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Row>
|
|
|
|
<Col md={24} lg={8} xxl={8}>
|
|
|
|
<DataTypeSelect store={sale_store} />
|
|
|
|
</Col>
|
|
|
|
<Col md={24} lg={12} xxl={12}>
|
|
|
|
<DatePickerCharts />
|
|
|
|
</Col>
|
|
|
|
<Col md={24} lg={4} xxl={4} className="align_right">
|
|
|
|
<Button
|
|
|
|
type="primary"
|
|
|
|
icon={<SearchOutlined />}
|
|
|
|
loading={sale_store.loading}
|
|
|
|
onClick={() => {
|
|
|
|
// sale_store.get_department_order_ml(date_picker_store);
|
|
|
|
sale_store.get_department_order_ml_by_type(date_picker_store);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
统计
|
|
|
|
</Button>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
{/* <Row>
|
|
|
|
<Col md={24} lg={12} xxl={12}>
|
|
|
|
<Select mode="multiple" style={{ width: "100%" }} placeholder="筛选国籍" value={sale_store.filter_country} onChange={value => sale_store.onChange_Country(value)} allowClear={true}>
|
|
|
|
<Select.Option key="3" value="3">
|
|
|
|
美国
|
|
|
|
</Select.Option>
|
|
|
|
<Select.Option key="5" value="5">
|
|
|
|
加拿大
|
|
|
|
</Select.Option>
|
|
|
|
<Select.Option key="7" value="7">
|
|
|
|
英国
|
|
|
|
</Select.Option>
|
|
|
|
<Select.Option key="18" value="18">
|
|
|
|
澳大利亚
|
|
|
|
</Select.Option>
|
|
|
|
</Select>
|
|
|
|
</Col>
|
|
|
|
<Col md={24} lg={12} xxl={12}>
|
|
|
|
<Select mode="multiple" style={{ width: "100%" }} placeholder="成员关系" value={sale_store.filter_guest_type} onChange={value => sale_store.onChange_GuestGroupType(value)} allowClear={true}>
|
|
|
|
<Select.Option key="146001" value="146001">
|
|
|
|
夫妻
|
|
|
|
</Select.Option>
|
|
|
|
<Select.Option key="146002" value="146002">
|
|
|
|
家庭
|
|
|
|
</Select.Option>
|
|
|
|
<Select.Option key="146003" value="146003">
|
|
|
|
solo
|
|
|
|
</Select.Option>
|
|
|
|
<Select.Option key="146005" value="146005">
|
|
|
|
其他
|
|
|
|
</Select.Option>
|
|
|
|
</Select>
|
|
|
|
</Col>
|
|
|
|
</Row> */}
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
<Row>
|
|
|
|
<Col className="gutter-row" md={24}>
|
|
|
|
<Column {...column_config} />
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
<Col className="gutter-row" md={24}>
|
|
|
|
<Tabs
|
|
|
|
activeKey={sale_store.active_tab_key}
|
|
|
|
onChange={(active_key) => {
|
|
|
|
sale_store.onChange_Tabs(active_key);
|
|
|
|
sale_store.get_department_order_ml_by_type(date_picker_store);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<Tabs.TabPane
|
|
|
|
tab={
|
|
|
|
<span>
|
|
|
|
<ContainerOutlined /> 总览
|
|
|
|
</span>
|
|
|
|
}
|
|
|
|
key="All"
|
|
|
|
></Tabs.TabPane>
|
|
|
|
<Tabs.TabPane
|
|
|
|
tab={
|
|
|
|
<span>
|
|
|
|
<UserSwitchOutlined /> 回复率
|
|
|
|
</span>
|
|
|
|
}
|
|
|
|
key="ResponseRateWhatsApp"
|
|
|
|
></Tabs.TabPane>
|
|
|
|
<Tabs.TabPane
|
|
|
|
tab={
|
|
|
|
<span>
|
|
|
|
<UserSwitchOutlined /> 沟通数据
|
|
|
|
</span>
|
|
|
|
}
|
|
|
|
key="ResponseRateByWL"
|
|
|
|
></Tabs.TabPane>
|
|
|
|
<Tabs.TabPane
|
|
|
|
tab={
|
|
|
|
<span>
|
|
|
|
<ContainerOutlined /> 国籍
|
|
|
|
</span>
|
|
|
|
}
|
|
|
|
key="Country"
|
|
|
|
></Tabs.TabPane>
|
|
|
|
<Tabs.TabPane
|
|
|
|
tab={
|
|
|
|
<span>
|
|
|
|
<ContainerOutlined />
|
|
|
|
产品类型
|
|
|
|
</span>
|
|
|
|
}
|
|
|
|
key="Product"
|
|
|
|
></Tabs.TabPane>
|
|
|
|
<Tabs.TabPane
|
|
|
|
tab={
|
|
|
|
<span>
|
|
|
|
<ContainerOutlined />
|
|
|
|
出行目的
|
|
|
|
</span>
|
|
|
|
}
|
|
|
|
key="TravelMotivation"
|
|
|
|
></Tabs.TabPane>
|
|
|
|
<Tabs.TabPane
|
|
|
|
tab={
|
|
|
|
<span>
|
|
|
|
<ContainerOutlined />
|
|
|
|
成员关系
|
|
|
|
</span>
|
|
|
|
}
|
|
|
|
key="GuestGroupType"
|
|
|
|
></Tabs.TabPane>
|
|
|
|
</Tabs>
|
|
|
|
<Row>
|
|
|
|
<Col span={24}>
|
|
|
|
<Table
|
|
|
|
id="table_to_xlsx_sale"
|
|
|
|
dataSource={type_data.dataSource}
|
|
|
|
columns={type_data.columns}
|
|
|
|
size="small"
|
|
|
|
rowKey={(record) => record.key}
|
|
|
|
loading={sale_store.loading_table}
|
|
|
|
pagination={false}
|
|
|
|
scroll={{ x: '100%' }}
|
|
|
|
/>
|
|
|
|
<Divider orientation="right" plain>
|
|
|
|
<a
|
|
|
|
onClick={() => {
|
|
|
|
const wb = utils.table_to_book(document.getElementById('table_to_xlsx_sale').getElementsByTagName('table')[0]);
|
|
|
|
writeFileXLSX(wb, 'sale.xlsx');
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
导出excel
|
|
|
|
</a>
|
|
|
|
</Divider>
|
|
|
|
</Col>
|
|
|
|
<Col sm={24} lg={12}>
|
|
|
|
{sale_store.active_tab_key === 'All' ? <Pie {...pie_config} /> : ''}
|
|
|
|
</Col>
|
|
|
|
{/* <Col sm={24} lg={24}>
|
|
|
|
<Treemap {...treemap_config} />
|
|
|
|
</Col> */}
|
|
|
|
</Row>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
export default observer(Sale);
|