diff --git a/src/charts/Customer_care_inchina.js b/src/charts/Customer_care_inchina.js index d2b6ba8..9b251f7 100644 --- a/src/charts/Customer_care_inchina.js +++ b/src/charts/Customer_care_inchina.js @@ -43,7 +43,7 @@ const Customer_care_inchina = () => { - 预定日期 + 提交日期 出发日期 } loading={inchina_data.loading} diff --git a/src/charts/DataTypeSelect.js b/src/charts/DataTypeSelect.js new file mode 100644 index 0000000..d6790e9 --- /dev/null +++ b/src/charts/DataTypeSelect.js @@ -0,0 +1,30 @@ +import React, { Component } from "react"; +import { Select } from "antd"; +import { observer } from "mobx-react"; + +class DataTypeSelect extends Component { + constructor(props) { + super(props); + } + + render() { + const store = this.props.store; + return ( + + store.onChange_datetype(value)}> + + 提交日期 + + + 确认日期 + + + 走团日期 + + + + ); + } +} + +export default observer(DataTypeSelect); diff --git a/src/charts/DatePickerCharts.js b/src/charts/DatePickerCharts.js index 731d9f6..38245d5 100644 --- a/src/charts/DatePickerCharts.js +++ b/src/charts/DatePickerCharts.js @@ -22,6 +22,7 @@ class DatePickerCharts extends Component { store.group_handleChange(value)} > - {this.props.show_all ? ALL 小组 : ''} + {this.props.show_all ? 所有小组 : ''} GH事业部 国际事业部 孵化学院 CH直销 CH大客户 - AH + AH亚洲项目组 市场推广 德语 日语 diff --git a/src/charts/SiteSelect.js b/src/charts/SiteSelect.js index af3e114..bdda6fe 100644 --- a/src/charts/SiteSelect.js +++ b/src/charts/SiteSelect.js @@ -15,23 +15,28 @@ class SiteSelect extends Component { - {this.props.show_all ? ALL : ''} + {this.props.show_all ? 所有来源 : ''} CHT AH GH 客运中国 客运海外 日语JP - 西语VAC - 意大利语IT - 德语GM - 俄语RU - 法语VC + 西语 + 西语海外 + 意大利 + 意大利海外 + 德语 + 德语海外 + 俄语 + 俄语海外 + 法语 + 法语海外 CT TP 花梨鹰 diff --git a/src/stores/OrdersStore.js b/src/stores/OrdersStore.js index 540de93..0095fce 100644 --- a/src/stores/OrdersStore.js +++ b/src/stores/OrdersStore.js @@ -2,6 +2,7 @@ import { makeAutoObservable, runInAction } from "mobx"; import { CaretUpOutlined, CaretDownOutlined } from "@ant-design/icons"; import { Tag } from "antd"; import * as config from "../config"; +import * as comm from "../utils/commons"; import moment from "moment"; import { NavLink } from "react-router-dom"; @@ -13,7 +14,10 @@ class OrdersStore { loading = false; site_select_mode = false; //是否多选站点 - webcode = "AH"; + group_select_mode = false; + groups = ["1,2,28,7"]; + webcode = "ALL"; + date_type = "applyDate"; include_tickets = "1"; //是否包含门票,1是含有,0不含 //diff_count_day = 0; //开始日期和结束日期的间隔,用于计算平均数 active_tab_key = "Form"; //当前切换的标签页 @@ -25,19 +29,30 @@ class OrdersStore { diff_days1 = 0; //日期相差天数,用于计算日平均值 diff_days2 = 0; //日期相差天数,比较数据时使用 + //选择事业部 + group_handleChange(value) { + this.groups = value; + } - get diff_count_day(){ - const date_picker_store = this.rootStore.date_picker_store; - let _start_date = moment(date_picker_store.start_date.format(config.DATE_FORMAT)); - let _end_date = moment(date_picker_store.end_date.format(config.DATE_FORMAT)); - return _end_date.diff(_start_date, "days")+1; - } + //计算两个时间段的有多少天 + get diff_count_day() { + const date_picker_store = this.rootStore.date_picker_store; + let _start_date = moment(date_picker_store.start_date.format(config.DATE_FORMAT)); + let _end_date = moment(date_picker_store.end_date.format(config.DATE_FORMAT)); + return _end_date.diff(_start_date, "days") + 1; + } - handleChange_webcode = (value) => { + //下单日期、确认日期、出发日期 + onChange_datetype(value) { + this.date_type = value; + } + + //选择来源网站 + handleChange_webcode = value => { this.webcode = value; }; - - handleChange_include_tickets = (value) => { + //是否包含门票 + handleChange_include_tickets = value => { this.include_tickets = value; }; @@ -54,11 +69,15 @@ class OrdersStore { format_data_source(data_source, start_date, end_date) { let result = []; for (let item of data_source.ordercount1) { - result.push({ - xField: item.ApplyDate, - yField: item.orderCount, - seriesField: item.groups, - }); + if (result[item.ApplyDate]) { + result[item.ApplyDate].yField += item.orderCount; + } else { + result[item.ApplyDate] = { + xField: item.ApplyDate, + yField: item.orderCount, + seriesField: item.groups, + }; + } } if (data_source.ordercount2 && end_date) { //不能直接用diff计算,因为日期是含有时间的,会导致计算差一天,先转成格式化的日期再比较 @@ -66,14 +85,20 @@ class OrdersStore { let _end_date = moment(end_date.format(config.DATE_FORMAT)); let diff_days = _start_date.diff(_end_date, "days"); for (let item of data_source.ordercount2) { - result.push({ - xField: moment(item.ApplyDate).add(diff_days, "days").format(config.DATE_FORMAT), - yField: item.orderCount, - seriesField: item.groups, - }); + let ApplyDate = moment(item.ApplyDate).add(diff_days, "days").format(config.DATE_FORMAT); + let ApplyDate_key = ApplyDate + "_";//这个作为key + if (result[ApplyDate_key]) { + result[ApplyDate_key].yField += item.orderCount; + } else { + result[ApplyDate_key] = { + xField: ApplyDate, + yField: item.orderCount, + seriesField: item.groups, + }; + } } } - return result; + return comm.set_array_index(result); } //网站订单数量,根据类型 @@ -82,19 +107,20 @@ class OrdersStore { const date_picker_store = this.rootStore.date_picker_store; let url = "/service-web/QueryData/GetOrderCount"; url += `?OrderType=${ordertype}&OrderType_val=${ordertype_sub}&IncludeTickets=${this.include_tickets}`; + url += `&DepartmentList=${this.groups.toString()}&DateType=${this.date_type}`; url += "&WebCode=" + this.webcode + "&COLI_ApplyDate1=" + date_picker_store.start_date.format(config.DATE_FORMAT) + "&COLI_ApplyDate2=" + date_picker_store.end_date.format(config.DATE_FORMAT) + "%2023:59:59"; if (date_picker_store.start_date_cp && date_picker_store.end_date_cp) { url += "&COLI_ApplyDateold1=" + date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "&COLI_ApplyDateold2=" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) + "%2023:59:59"; } fetch(config.HT_HOST + url) - .then((response) => response.json()) - .then((json) => { + .then(response => response.json()) + .then(json => { runInAction(() => { this.orderCountData_type = this.format_data_source(json, date_picker_store.start_date, date_picker_store.start_date_cp); this.loading = false; }); }) - .catch((error) => { + .catch(error => { this.loading = false; console.log("fetch data failed", error); }); @@ -105,28 +131,21 @@ class OrdersStore { this.loading = true; const date_picker_store = this.rootStore.date_picker_store; let url = "/service-web/QueryData/GetOrderCount"; //?WebCode=cht&COLI_ApplyDate1=2022-08-01&COLI_ApplyDate2=2022-08-31&COLI_ApplyDateold1=2021-08-01&COLI_ApplyDateold2=2021-08-31'; - url += - "?WebCode=" + - this.webcode + - "&IncludeTickets=" + - this.include_tickets + - "&COLI_ApplyDate1=" + - date_picker_store.start_date.format(config.DATE_FORMAT) + - "&COLI_ApplyDate2=" + - date_picker_store.end_date.format(config.DATE_FORMAT) + - "%2023:59:59"; + url += "?WebCode=" + this.webcode + "&IncludeTickets=" + this.include_tickets; + url += "&COLI_ApplyDate1=" + date_picker_store.start_date.format(config.DATE_FORMAT) + "&COLI_ApplyDate2=" + date_picker_store.end_date.format(config.DATE_FORMAT) + "%2023:59:59"; + url += `&DepartmentList=${this.groups.toString()}&DateType=${this.date_type}`; if (date_picker_store.start_date_cp && date_picker_store.end_date_cp) { url += "&COLI_ApplyDateold1=" + date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "&COLI_ApplyDateold2=" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) + "%2023:59:59"; } fetch(config.HT_HOST + url) - .then((response) => response.json()) - .then((json) => { + .then(response => response.json()) + .then(json => { runInAction(() => { this.orderCountData = this.format_data_source(json, date_picker_store.start_date, date_picker_store.start_date_cp); this.loading = false; }); }) - .catch((error) => { + .catch(error => { this.loading = false; console.log("fetch data failed", error); }); @@ -137,19 +156,20 @@ class OrdersStore { const date_picker_store = this.rootStore.date_picker_store; let url = "/service-web/QueryData/GetOrderCountByType"; url += "?WebCode=" + this.webcode + "&OrderType=" + order_type + "&IncludeTickets=" + this.include_tickets; + url += `&DepartmentList=${this.groups.toString()}&DateType=${this.date_type}`; url += "&COLI_ApplyDate1=" + date_picker_store.start_date.format(config.DATE_FORMAT) + "&COLI_ApplyDate2=" + date_picker_store.end_date.format(config.DATE_FORMAT) + "%2023:59:59"; if (date_picker_store.start_date_cp && date_picker_store.end_date_cp) { url += "&COLI_ApplyDateold1=" + date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "&COLI_ApplyDateold2=" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) + "%2023:59:59"; } fetch(config.HT_HOST + url) - .then((response) => response.json()) - .then((json) => { + .then(response => response.json()) + .then(json => { runInAction(() => { //错误:[MOBX]由于启用了严格模式,所以不允许改变观察到的在动作之外的值。如果此更改是有意的,请将代码包在“Actudio”中。 this.orderCountData_Form = json; }); }) - .catch((error) => { + .catch(error => { console.log("fetch data failed", error); }); } @@ -158,23 +178,25 @@ class OrdersStore { getOrderCountByType_sub(ordertype, ordertype_sub, sub_type) { const date_picker_store = this.rootStore.date_picker_store; let url = "/service-web/QueryData/GetOrderCountByType_Sub"; - if (sub_type=='page_cxstate1'){ //统计成行订单的路径 - sub_type='page&cxstate=1' + if (sub_type == "page_cxstate1") { + //统计成行订单的路径 + sub_type = "page&cxstate=1"; } url += `?WebCode=${this.webcode}&OrderType=${ordertype}&OrderType_val=${ordertype_sub}&SubOrderType=${sub_type}` + "&IncludeTickets=" + this.include_tickets; + url += `&DepartmentList=${this.groups.toString()}&DateType=${this.date_type}`; url += "&COLI_ApplyDate1=" + date_picker_store.start_date.format(config.DATE_FORMAT) + "&COLI_ApplyDate2=" + date_picker_store.end_date.format(config.DATE_FORMAT) + "%2023:59:59"; if (date_picker_store.start_date_cp && date_picker_store.end_date_cp) { url += "&COLI_ApplyDateold1=" + date_picker_store.start_date_cp.format(config.DATE_FORMAT) + "&COLI_ApplyDateold2=" + date_picker_store.end_date_cp.format(config.DATE_FORMAT) + "%2023:59:59"; } fetch(config.HT_HOST + url) - .then((response) => response.json()) - .then((json) => { + .then(response => response.json()) + .then(json => { runInAction(() => { //错误:[MOBX]由于启用了严格模式,所以不允许改变观察到的在动作之外的值。如果此更改是有意的,请将代码包在“Actudio”中。 this.orderCountData_Form_sub = json; }); }) - .catch((error) => { + .catch(error => { console.log("fetch data failed", error); }); } diff --git a/src/stores/SaleStore.js b/src/stores/SaleStore.js index 7baf810..7528ad3 100644 --- a/src/stores/SaleStore.js +++ b/src/stores/SaleStore.js @@ -16,8 +16,10 @@ class SaleStore { spinning = false; //加载状态 active_tab_key = "All"; //当前选择的标签 group_select_mode = false; + groups = ["1,2,28,7"]; //默认GH事业部 + site_select_mode = false; //是否多选站点 + webcode = "ALL"; date_type = "ConfirmDate"; - groups = ["1,2,28,7"]; ml_data = []; //毛利数据 type_data = []; //类型的数据 type_data_sub = []; //类型的子维度数据 @@ -27,6 +29,10 @@ class SaleStore { group_handleChange(value) { this.groups = value; } + //选择站点 + handleChange_webcode = value => { + this.webcode = value; + }; //切换标签页 onChange_Tabs(active_key) { @@ -48,7 +54,7 @@ class SaleStore { this.loading = true; this.date_title = `${date1_start}~${date1_end}`; let url = "/service-web/QueryData/GetDepartmentOrderML"; - url += `?DepartmentList=${this.groups.toString()}&DateType=${this.date_type}`; + url += `?DepartmentList=${this.groups.toString()}&DateType=${this.date_type}&WebCode=${this.webcode}`; url += `&Date1=${date1_start}&Date2=${date1_end}%2023:59:59`; if (date2_start && date2_end) { url += `&OldDate1=${date2_start}&OldDate2=${date2_end}%2023:59:59`; @@ -90,7 +96,7 @@ class SaleStore { this.loading_table = true; this.date_title = `${date1_start}~${date1_end}`; let url = "/service-web/QueryData/GetDepartmentOrderMLByType"; - url += `?DepartmentList=${this.groups.toString()}&DateType=${this.date_type}&OrderType=${this.active_tab_key}`; + url += `?DepartmentList=${this.groups.toString()}&DateType=${this.date_type}&OrderType=${this.active_tab_key}&WebCode=${this.webcode}`; url += `&Date1=${date1_start}&Date2=${date1_end}%2023:59:59`; if (date2_start && date2_end) { url += `&OldDate1=${date2_start}&OldDate2=${date2_end}%2023:59:59`; @@ -321,7 +327,7 @@ class SaleStore { const date2_start = comm.empty(date_moment.start_date_cp) ? "" : date_moment.start_date_cp.format(config.DATE_FORMAT); const date2_end = comm.empty(date_moment.end_date_cp) ? "" : date_moment.end_date_cp.format(config.DATE_FORMAT); let url = "/service-web/QueryData/GetDepartmentOrderMLByType_sub"; - url += `?DepartmentList=${this.groups.toString()}&DateType=${this.date_type}&subType=${type_sub}&subTypeVal=-1`; + url += `?DepartmentList=${this.groups.toString()}&DateType=${this.date_type}&subType=${type_sub}&subTypeVal=-1&WebCode=${this.webcode}`; url += `&Date1=${date1_start}&Date2=${date1_end}%2023:59:59`; if (date2_start && date2_end) { url += `&OldDate1=${date2_start}&OldDate2=${date2_end}%2023:59:59`; diff --git a/src/utils/commons.js b/src/utils/commons.js index 72bde5e..210672f 100644 --- a/src/utils/commons.js +++ b/src/utils/commons.js @@ -252,3 +252,14 @@ export function getWeek(date) { return "周日"; } } + +//把非数字下标的数组设置下标,因为非数字数组的length为0导致读取失败 +export function set_array_index(result) { + let result_array = []; + let result_keys = Object.keys(result); + result_keys.sort(); //必须做一次排序,用for in循环会导致顺序错误 + for (let key of result_keys) { + result_array.push(result[key]); + } + return result_array; +} diff --git a/src/views/Orders.js b/src/views/Orders.js index 0a569e2..8837db6 100644 --- a/src/views/Orders.js +++ b/src/views/Orders.js @@ -4,6 +4,8 @@ import { ContainerOutlined, CarryOutOutlined, BlockOutlined, SmileOutlined, Tags import { stores_Context } from "../config"; import { Line, Pie } from "@ant-design/charts"; import SiteSelect from "../charts/SiteSelect"; +import GroupSelect from "../charts/GroupSelect"; +import DataTypeSelect from "../charts/DataTypeSelect"; import { observer } from "mobx-react"; import DatePickerCharts from "../charts/DatePickerCharts"; import * as config from "../config"; @@ -262,7 +264,7 @@ class Orders extends Component { legend: { itemValue: { formatter: (text, item) => { - const items = data_source.filter((d) => d.seriesField === item.value); //按站点筛选 + const items = data_source.filter(d => d.seriesField === item.value); //按站点筛选 return items.length ? items.reduce((a, b) => a + b.yField, 0) : ""; //计算总数 }, }, @@ -302,12 +304,17 @@ class Orders extends Component { return ( - - + + - - - + + + + + + + + 含门票 @@ -316,10 +323,15 @@ class Orders extends Component { - + + + + + + - + } @@ -340,7 +352,7 @@ class Orders extends Component { - orders_store.onChange_Tabs(active_key)}> + orders_store.onChange_Tabs(active_key)}> diff --git a/src/views/Orders_sub.js b/src/views/Orders_sub.js index 8504f6b..79684a8 100644 --- a/src/views/Orders_sub.js +++ b/src/views/Orders_sub.js @@ -1,10 +1,13 @@ import React, { useContext, useEffect } from "react"; -import { Row, Col, Button, Tabs, Table, Space, Divider } from "antd"; +import { Row, Col, Button, Tabs, Table, Select, Divider } from "antd"; import { ContainerOutlined, SearchOutlined } from "@ant-design/icons"; import { stores_Context } from "../config"; import { Line } from "@ant-design/charts"; import { observer } from "mobx-react"; import DatePickerCharts from "../charts/DatePickerCharts"; +import SiteSelect from "../charts/SiteSelect"; +import GroupSelect from "../charts/GroupSelect"; +import DataTypeSelect from "../charts/DataTypeSelect"; import { NavLink, useParams } from "react-router-dom"; import * as comm from "../utils/commons"; import * as config from "../config"; @@ -171,27 +174,52 @@ const Orders_sub = () => { return ( - - + + 返回 - - - - - - } - loading={orders_store.loading} - onClick={() => { - orders_store.getOrderCount_type(ordertype, ordertype_sub); - orders_store.getOrderCountByType_sub(ordertype, ordertype_sub, orders_store.active_tab_key_sub); - }}> - 统计 - + + + + + + + + + + + + 含门票 + + + 不含门票 + + + + + + + + + + + + + } + loading={orders_store.loading} + onClick={() => { + orders_store.getOrderCount_type(ordertype, ordertype_sub); + orders_store.getOrderCountByType_sub(ordertype, ordertype_sub, orders_store.active_tab_key_sub); + }}> + 统计 + + + + diff --git a/src/views/Sale.js b/src/views/Sale.js index 5964396..513cdfc 100644 --- a/src/views/Sale.js +++ b/src/views/Sale.js @@ -1,13 +1,15 @@ 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 { ContainerOutlined, SearchOutlined, UserSwitchOutlined } from "@ant-design/icons"; import { stores_Context } from "../config"; import { Column, Pie } from "@ant-design/charts"; import { observer } from "mobx-react"; import DatePickerCharts from "../charts/DatePickerCharts"; +import DataTypeSelect from "../charts/DataTypeSelect"; import { NavLink, useParams } from "react-router-dom"; import * as comm from "../utils/commons"; import * as config from "../config"; +import SiteSelect from "../charts/SiteSelect"; import GroupSelect from "../charts/GroupSelect"; import { utils, writeFileXLSX } from "xlsx"; @@ -28,7 +30,7 @@ const Sale = () => { legend: { itemValue: { formatter: (text, item) => { - const items = ml_data.filter((d) => d.groups === item.value); //按分组筛选 + const items = ml_data.filter(d => d.groups === item.value); //按分组筛选 return items.length ? items.reduce((a, b) => a + b.COLI_YJLY, 0) : ""; //计算总数 }, }, @@ -45,10 +47,10 @@ const Sale = () => { }; //格式化数据,饼图只支持数字模式 - const format_data_for_pie = (data) => { + const format_data_for_pie = data => { let result_arr = []; if (!comm.empty(data)) { - data.map((item) => { + data.map(item => { item.COLI_ML_number = comm.price_to_number(item.COLI_ML); result_arr.push(item); }); @@ -80,27 +82,25 @@ const Sale = () => { return ( - - + + - + - sale_store.onChange_datetype(value)}> - - 确认日期 - - - 提交日期 - - - 走团日期 - - - - + + - + + + + + + + + + + } @@ -124,7 +124,7 @@ const Sale = () => { { + onChange={active_key => { sale_store.onChange_Tabs(active_key); sale_store.get_department_order_ml_by_type(date_picker_store); }}> @@ -183,16 +183,25 @@ const Sale = () => { - record.key} loading={sale_store.loading_table} pagination={false} scroll={{ x: "100%" }} /> + record.key} + loading={sale_store.loading_table} + pagination={false} + scroll={{ x: "100%" }} + /> - { - const wb = utils.table_to_book(document.getElementById("table_to_xlsx_sale").getElementsByTagName("table")[0]); - writeFileXLSX(wb, "sale.xlsx"); - }}> - 导出excel - - + { + const wb = utils.table_to_book(document.getElementById("table_to_xlsx_sale").getElementsByTagName("table")[0]); + writeFileXLSX(wb, "sale.xlsx"); + }}> + 导出excel + + {sale_store.active_tab_key == "All" ? : ""}