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/views/Sale.jsx

311 lines
9.4 KiB
React

import React, { useContext } from 'react';
import { Row, Col, Tabs, Table, Divider, Spin } from 'antd';
import { ContainerOutlined, UserSwitchOutlined } from '@ant-design/icons';
2 years ago
import { stores_Context } from '../config';
import { Column, Pie } from '@ant-design/charts';
2 years ago
import { observer } from 'mobx-react';
import * as comm from '../utils/commons';
import { utils, writeFileXLSX } from 'xlsx';
import SearchForm from './../components/search/SearchForm';
2 years ago
import { TableExportBtn } from './../components/Data';
const Sale = () => {
2 years ago
const { sale_store, date_picker_store } = useContext(stores_Context);
2 years ago
//const ml_data = sale_store.ml_data; // 毛利数据
const type_data = comm.empty(sale_store.type_data) ? { dataSource: [], columns: [] } : sale_store.type_data; // 毛利数据
2 years ago
const column_config_create = (tab_name) => {
2 years ago
let average_value = 0; //平均线的值
let config_data = [];
2 years ago
switch (tab_name) {
case 'All':
config_data.data = type_data.dataSource;
config_data.xField = 'OPI_Name';
config_data.yField = 'COLI_ML2';
2 years ago
average_value = Math.round(config_data.data.reduce((a, b) => a + b.COLI_ML2, 0) / config_data.data.length);
2 years ago
break;
case 'ResponseRateWhatsApp':
config_data.data = type_data.dataSource;
config_data.xField = 'OPI_Name';
config_data.yField = 'COLI_ConfirmTimeAVG';
2 years ago
average_value = Math.round(config_data.data.reduce((a, b) => a + b.COLI_ConfirmTimeAVG, 0) / config_data.data.length);
2 years ago
break;
case 'ResponseRateByWL':
config_data.data = type_data.dataSource;
config_data.xField = 'OPI_Name';
config_data.yField = 'PriceTime';
2 years ago
average_value = Math.round(config_data.data.reduce((a, b) => a + b.PriceTime, 0) / config_data.data.length);
2 years ago
break;
default:
// config_data.data = [];
config_data.data = type_data.dataSource;
config_data.xField = 'T_name';
config_data.yField = 'T_total';
2 years ago
break;
}
2 years ago
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],
},
},
]
: [],
},
};
2 years ago
};
const column_config = column_config_create(sale_store.active_tab_key);
2 years ago
// 直方图,先隐藏
// 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,
// };
// };
2 years ago
// 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',
},
],
};
const tab_items = [
{
key: 'All',
label: (
<span>
<ContainerOutlined /> 总览
</span>
),
},
{
key: 'ResponseRateWhatsApp',
label: (
<span>
<UserSwitchOutlined /> 回复率
</span>
),
},
{
key: 'ResponseRateByWL',
label: (
<span>
<UserSwitchOutlined /> 沟通数据
</span>
),
},
{
key: 'Country',
label: (
<span>
<ContainerOutlined /> 国籍
</span>
),
},
{
key: 'Product',
label: (
<span>
<ContainerOutlined /> 产品类型
</span>
),
},
{
key: 'TravelMotivation',
label: (
<span>
<ContainerOutlined /> 出行目的
</span>
),
},
{
key: 'GuestGroupType',
label: (
<span>
<ContainerOutlined /> 成员关系
</span>
),
},
];
const tableColumns = type_data.columns.map((ele, i) =>
i === 0 ? { ...ele, fixed: 'left', children: (ele?.children || []).map((ele_child, i_child) => (i_child === 0 ? { ...ele_child, fixed: 'left' } : { ...ele_child })) } : { ...ele }
);
2 years ago
return (
<div>
<Row gutter={16} className={date_picker_store.siderBroken ? "" : "sticky-top"} >
<Col className="gutter-row" span={24}>
<SearchForm
defaultValue={{
initialValue: {
...date_picker_store.formValues,
...sale_store.searchValues,
},
shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'dates'],
fieldProps: {
DepartmentList: { show_all: false, mode: 'multiple' },
WebCode: { show_all: false, mode: 'multiple' },
years: { hide_vs: true },
},
}}
onSubmit={(_err, obj, form, str) => {
sale_store.setSearchValues(obj, form);
sale_store.get_department_order_ml_by_type(date_picker_store);
}}
/>
</Col>
</Row>
2 years ago
{/* <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> */}
2 years ago
<Row>
<Col className="gutter-row" md={24}>
<Spin spinning={sale_store.loading_table} >
<Column {...column_config} /></Spin>
2 years ago
</Col>
2 years ago
<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);
}}
items={tab_items}
></Tabs>
2 years ago
<Row>
<Col span={24}>
<Table sticky
2 years ago
id="table_to_xlsx_sale"
dataSource={type_data.dataSource}
columns={tableColumns}
2 years ago
size="small"
rowKey={(record) => record.key}
loading={sale_store.loading_table}
pagination={false}
scroll={{ x: (100*(tableColumns.length)) }}
2 years ago
/>
<Divider orientation="right" plain>
2 years ago
<TableExportBtn label={'sale'} {...{ columns: tableColumns, dataSource: type_data.dataSource }} />
2 years ago
</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);