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

334 lines
11 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 React, { useContext, useEffect, useState } from "react";
import { Row, Col, Tabs, Table, Divider } from "antd";
import { ContainerOutlined } from "@ant-design/icons";
import { stores_Context } from "../config";
import { Line } from "@ant-design/charts";
import { observer } from "mobx-react";
import { NavLink, useParams } from "react-router-dom";
import * as comm from "../utils/commons";
import * as config from "../config";
import { utils, writeFileXLSX } from "xlsx";
import DateGroupRadio from '../components/DateGroupRadio';
import SearchForm from './../components/search/SearchForm';
import { TableExportBtn } from './../components/Data';
const Orders_sub = () => {
const { ordertype, ordertype_sub, ordertype_title } = useParams();
const { orders_store, date_picker_store } = useContext(stores_Context);
useEffect(() => {
orders_store.getOrderCount_type(ordertype, ordertype_sub);
orders_store.getOrderCountByType_sub(ordertype, ordertype_sub, orders_store.active_tab_key_sub);
}, []);
// const data_source = orders_store.orderCountData_type;
const data_source = orders_store.orderCountData_type ? orders_store.orderCountData_type : [];
const avg_line_y = Math.round(orders_store.orderCount_type_dateRadio.avgLine1);
// const avg_line_y = data_source.length ? Math.round(data_source.reduce((a, b) => a + b.yField, 0) / data_source.length) : 0; // 平均值,显示一条平均线
const line = {
data: data_source,
padding: "auto",
xField: "xField",
yField: "yField",
seriesField: "seriesField",
xAxis: {
type: "cat",
},
annotations: [
{
type: "text",
position: ["start", avg_line_y],
content: avg_line_y,
offsetX: -15,
style: {
fill: "#F4664A",
textBaseline: "bottom",
},
},
{
type: "line",
start: [-10, avg_line_y],
end: ["max", avg_line_y],
style: {
stroke: "#F4664A",
lineDash: [2, 2],
},
},
],
tooltip: {
customItems: (originalItems) => {
return originalItems.map(ele => ({...ele, name: ele.data?.seriesField || ele.data?.xField}));
},
title: (title, datum) => {
return orders_store.orderCount_type_dateRadio.lineChartXGroup === 'day' ? `${title} ${comm.getWeek(datum.xField)}` : title;
},
},
label: {}, // 显示标签
legend: {
title: {
text: ordertype_title,
},
itemValue: {
formatter: (text, item) => {
const items = data_source.filter(d => d.seriesField === item.value); // 按站点筛选
return items.length ? items.reduce((a, b) => a + b.yField, 0) : ""; // 计算总数
},
},
},
// smooth: true,
};
const format_data = data => {
const result = { dataSource: [], columns: [] };
if (!comm.empty(data)) {
result.columns = [
{
title: "页面",
children: [
{
title: "",
dataIndex: "request_uri",
},
],
},
{
title: "访问量",
children: [
{
title: data.reduce((a, b) => a + b.viewCount, 0),
dataIndex: "viewCount",
},
],
},
];
result.dataSource = data;
}
return result;
};
const format_data_detail = data => {
const result = { dataSource: [], columns: [] };
if (!comm.empty(data)) {
result.columns = [
{
title: "订单号",
dataIndex: "COLI_ID",
key: "COLI_ID",
},
{
title: "网站",
dataIndex: "COLI_WebCode",
key: "COLI_WebCode",
},
{
title: "成行",
dataIndex: "COLI_Success",
key: "COLI_Success",
render: (text, record) => <span>{text == 1 ? "是" : "否"}</span>,
sorter: (a, b) => b.COLI_Success - a.COLI_Success,
},
// {
// title: "人数(成/童/婴)",
// dataIndex: "COLI_PersonNum",
// key: "COLI_PersonNum",
// render: (text, record) => (
// <span>
// {record.COLI_PersonNum}/{record.COLI_ChildNum}/{record.COLI_BabyNum}
// </span>
// ),
// },
{
title: "预计利润",
dataIndex: "CGI_YJLY",
key: "CGI_YJLY",
},
{
title: "预定时间",
dataIndex: "COLI_ApplyDate",
key: "COLI_ApplyDate",
},
{
title: "出发日期",
dataIndex: "CGI_ArriveDate",
key: "CGI_ArriveDate",
},
{
title: "客人需求",
dataIndex: "COLI_CustomerRequest",
key: "COLI_CustomerRequest",
ellipsis: true,
},
{
title: "订单内容",
dataIndex: "COLI_OrderDetailText",
key: "COLI_OrderDetailText",
ellipsis: true,
},
Table.EXPAND_COLUMN,
];
result.dataSource = data;
}
return result;
};
// 在逗号和分号处自动换行的函数
const addLineBreaksAtCommas = (text) => {
if (!text) return '';
return text.replace(/&amp;/g, "&").replace(//g, '\n').replace(/,/g, ',\n').replace(//g, '\n').replace(/;/g, ';\n');
};
const table_data = format_data_detail(orders_store.orderCountData_Form_sub.ordercount1);
const table_data2 = format_data_detail(orders_store.orderCountData_Form_sub.ordercount2);
const table_data_p = format_data(orders_store.orderCountData_Form_sub.ordercount1);
const table_data2_p = format_data(orders_store.orderCountData_Form_sub.ordercount2);
const tab_items = [
{
key: 'detail', label: <span><ContainerOutlined />订单内容</span>, title: '',
children: (<Row>
<Col span={24}>
{date_picker_store.start_date.format(config.DATE_FORMAT)}~{date_picker_store.end_date.format(config.DATE_FORMAT)}
<Table
id="table_to_xlsx_form"
dataSource={table_data.dataSource}
columns={table_data.columns}
size="small"
pagination={false}
rowKey={record => record.key}
expandable={{
expandedRowRender: record => (
<pre style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word', fontSize: '16px' }}>
<Divider orientation="left" plain>
客户需求
</Divider>
{record.COLI_CustomerRequest}
<Divider orientation="left" plain>
订单内容
</Divider>
{addLineBreaksAtCommas(record.COLI_OrderDetailText)}
</pre>
),
}}
/>
<Divider orientation="right" plain>
<a
onClick={() => {
const wb = utils.table_to_book(document.getElementById("table_to_xlsx_form").getElementsByTagName("table")[0]);
writeFileXLSX(wb, "订单列表.xlsx");
}}>
导出excel
</a>
</Divider>
</Col>
<Col span={24}>
{date_picker_store.start_date_cp ? date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "~" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) : ""}
<Table
dataSource={table_data2.dataSource}
columns={table_data2.columns}
size="small"
rowKey={record => record.key}
expandable={{
expandedRowRender: record => <pre style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word', fontSize: '16px' }}>{record.COLI_OrderDetailText}</pre>,
}}
/>
</Col>
</Row>),
},
{ key: 'page', label: <span><ContainerOutlined />访问路径</span>, title: '访',children: (<Row>
<Col span={24}>
{date_picker_store.start_date.format(config.DATE_FORMAT)}~{date_picker_store.end_date.format(config.DATE_FORMAT)}
<Table dataSource={table_data_p.dataSource} rowKey={record => record.key} columns={table_data_p.columns} size="small" />
</Col>
<Col span={24}>
{date_picker_store.start_date_cp ? date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "~" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) : ""}
<Table dataSource={table_data2_p.dataSource} rowKey={record => record.key} columns={table_data2_p.columns} size="small" />
</Col>
</Row>)},
{ key: 'page_cxstate1', label: <span><ContainerOutlined />访问路径成行</span>, title: '访',children: (<Row>
<Col span={24}>
{date_picker_store.start_date.format(config.DATE_FORMAT)}~{date_picker_store.end_date.format(config.DATE_FORMAT)}
<Table dataSource={table_data_p.dataSource} rowKey={record => record.key} columns={table_data_p.columns} size="small" />
</Col>
<Col span={24}>
{date_picker_store.start_date_cp ? date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "~" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) : ""}
<Table dataSource={table_data2_p.dataSource} rowKey={record => record.key} columns={table_data2_p.columns} size="small" />
</Col>
</Row>)},
];
const [propsForExport, setPropsForExport] = useState(tab_items[0]);
const tabItemsMapped = tab_items.reduce((r, v) => ({...r, [v.key]: v}), {});
const onTabsChange = (active_key) => {
setPropsForExport(tabItemsMapped[active_key]);
orders_store.onChange_Tabs_sub(ordertype, ordertype_sub, active_key);
};
return (
<div>
<Row gutter={{ sm: 16, lg: 32 }} className={date_picker_store.siderBroken ? "" : "sticky-top"}>
<Col md={24} lg={12} xxl={14}>
<NavLink to={`/orders`}>返回</NavLink>
</Col>
<Col className="gutter-row" span={24}>
<SearchForm
defaultValue={{
initialValue: {
...date_picker_store.formValues,
},
shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'dates'],
fieldProps: {
DepartmentList: { show_all: false, mode: 'multiple' },
WebCode: { show_all: false, mode: 'multiple' },
// dates: { hide_vs: true },
},
}}
onSubmit={(_err, obj, form, str) => {
orders_store.setSearchValues(obj, form);
orders_store.getOrderCount_type(ordertype, ordertype_sub);
orders_store.getOrderCountByType_sub(ordertype, ordertype_sub, orders_store.active_tab_key_sub);
}}
/>
</Col>
</Row>
<Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
<Col span={24} style={{ textAlign: 'right' }}>
<DateGroupRadio
visible={data_source.length !== 0}
dataRaw={orders_store.orderCountDataRaw_type}
onChange={orders_store.onChangeDateGroupSub}
value={orders_store.orderCount_type_dateRadio.lineChartXGroup}
dataMapper={orders_store.orderCount_type_dateRadio.orderCountDataMapper}
fieldMapper={orders_store.orderCount_type_dateRadio.orderCountDataFieldMapper}
/>
</Col>
<Col className="gutter-row" span={24}>
<Line {...line} />
</Col>
<Col className="gutter-row" span={24}>
<Tabs
activeKey={orders_store.active_tab_key_sub}
onChange={onTabsChange}
tabBarExtraContent={{
right: (
<TableExportBtn
label={propsForExport.title}
{...(orders_store.active_tab_key_sub === 'detail'
? { columns: table_data.columns, dataSource: table_data.dataSource }
: { columns: table_data_p.columns, dataSource: table_data_p.dataSource })}
/>
),
}}
items={tab_items}
/>
</Col>
</Row>
</div>
);
};
export default observer(Orders_sub);