|
|
|
|
import { makeAutoObservable, runInAction, toJS } 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";
|
|
|
|
|
import { groupsMappedByCode } from './../libs/ht';
|
|
|
|
|
import { resultDataCb } from '../components/DateGroupRadio/date';
|
|
|
|
|
|
|
|
|
|
class OrdersStore {
|
|
|
|
|
constructor(rootStore) {
|
|
|
|
|
this.rootStore = rootStore;
|
|
|
|
|
makeAutoObservable(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
loading = false;
|
|
|
|
|
site_select_mode = false; // 是否多选站点
|
|
|
|
|
group_select_mode = false;
|
|
|
|
|
groups = [groupsMappedByCode.GH.key]; // 默认GH事业部
|
|
|
|
|
webcode = "ALL";
|
|
|
|
|
date_type = "applyDate";
|
|
|
|
|
include_tickets = "1"; // 是否包含门票,1是含有,0不含
|
|
|
|
|
// diff_count_day = 0; //开始日期和结束日期的间隔,用于计算平均数
|
|
|
|
|
active_tab_key = "Form"; // 当前切换的标签页
|
|
|
|
|
active_tab_key_sub = "detail"; // 当前切换的子维度标签页
|
|
|
|
|
orderCountDataRaw = [];
|
|
|
|
|
orderCountData = []; // 订单统计数据源
|
|
|
|
|
orderCountDataRaw_type = []; // 子维度订单统计
|
|
|
|
|
orderCountData_type = []; // 子维度订单统计
|
|
|
|
|
orderCountData_Form = []; // 表单类型统计数据源
|
|
|
|
|
orderCountData_Form_sub = []; // 子维度类型统计
|
|
|
|
|
diff_days1 = 0; // 日期相差天数,用于计算日平均值
|
|
|
|
|
diff_days2 = 0; // 日期相差天数,比较数据时使用
|
|
|
|
|
|
|
|
|
|
lineChartXGroup = ''; // x轴: 按 日/月/年
|
|
|
|
|
avgLine1 = 0;
|
|
|
|
|
orderCountDataMapper = { 'data1': 'ordercount1', data2: 'ordercount2' };
|
|
|
|
|
orderCountDataFieldMapper ={ 'dateKey': 'ApplyDate', 'valueKey': 'orderCount', 'seriesKey': 'WebCode', _f: 'sum' };
|
|
|
|
|
|
|
|
|
|
orderCount_type_dateRadio = {
|
|
|
|
|
lineChartXGroup: '', // x轴: 按 日/月/年
|
|
|
|
|
avgLine1: 0,
|
|
|
|
|
orderCountDataMapper: { 'data1': 'ordercount1', data2: 'ordercount2' },
|
|
|
|
|
orderCountDataFieldMapper:{ 'dateKey': 'ApplyDate', 'valueKey': 'orderCount', 'seriesKey': 'WebCode', _f: 'sum' },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 选择事业部
|
|
|
|
|
group_handleChange(value) {
|
|
|
|
|
this.groups = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算两个时间段的有多少天
|
|
|
|
|
get diff_count_day() {
|
|
|
|
|
const date_picker_store = this.rootStore.date_picker_store;
|
|
|
|
|
const _start_date = moment(date_picker_store.start_date.format(config.DATE_FORMAT));
|
|
|
|
|
const _end_date = moment(date_picker_store.end_date.format(config.DATE_FORMAT));
|
|
|
|
|
return _end_date.diff(_start_date, `${this.lineChartXGroup}s`) + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下单日期、确认日期、出发日期
|
|
|
|
|
onChange_datetype(value) {
|
|
|
|
|
this.date_type = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 选择来源网站
|
|
|
|
|
handleChange_webcode = value => {
|
|
|
|
|
this.webcode = value;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 是否包含门票
|
|
|
|
|
handleChange_include_tickets = value => {
|
|
|
|
|
this.include_tickets = value;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
searchValues = {
|
|
|
|
|
DateType: { key: 'applyDate', label: '提交日期'},
|
|
|
|
|
WebCode: { key: 'All', label: '所有来源'},
|
|
|
|
|
IncludeTickets: { key: '1', label: '含门票'},
|
|
|
|
|
DepartmentList: groupsMappedByCode.GH,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
setSearchValues(obj, values) {
|
|
|
|
|
this.groups = obj.DepartmentList;
|
|
|
|
|
this.webcode = obj.WebCode;
|
|
|
|
|
this.include_tickets = obj.IncludeTickets;
|
|
|
|
|
this.date_type = obj.DateType;
|
|
|
|
|
this.searchValues = values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 切换标签页
|
|
|
|
|
onChange_Tabs_sub(ordertype, ordertype_sub, active_key) {
|
|
|
|
|
this.active_tab_key_sub = active_key;
|
|
|
|
|
this.getOrderCountByType_sub(ordertype, ordertype_sub, this.active_tab_key_sub);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 格式化一下数据
|
|
|
|
|
// 映射时间,做时间段对比的时候需要把对比时间段映射到开始时间上才能在同一个x轴显示
|
|
|
|
|
// 比如2022-10-01~2022-10-30 vs 2021-10-01~2021-10-30 ,则需要在2021年的时间段加365天的时间映射成2022起始时间段
|
|
|
|
|
// 相差的天数用a.diff(b, 'days')计算
|
|
|
|
|
format_data_source(data_source, start_date, end_date) {
|
|
|
|
|
const result = [];
|
|
|
|
|
for (const item of data_source.ordercount1) {
|
|
|
|
|
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计算,因为日期是含有时间的,会导致计算差一天,先转成格式化的日期再比较
|
|
|
|
|
const _start_date = moment(start_date.format(config.DATE_FORMAT));
|
|
|
|
|
const _end_date = moment(end_date.format(config.DATE_FORMAT));
|
|
|
|
|
const diff_days = _start_date.diff(_end_date, "days");
|
|
|
|
|
for (const item of data_source.ordercount2) {
|
|
|
|
|
const ApplyDate = moment(item.ApplyDate).add(diff_days, "days").format(config.DATE_FORMAT);
|
|
|
|
|
const 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 comm.set_array_index(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 更新值: orderCountData
|
|
|
|
|
* @author LYT
|
|
|
|
|
* @returns void
|
|
|
|
|
*/
|
|
|
|
|
onChangeDateGroup = (value, data, avg1) => {
|
|
|
|
|
const groupByDate = data.reduce((r, v) => {
|
|
|
|
|
(r[v.ApplyDate] || (r[v.ApplyDate] = [])).push(v);
|
|
|
|
|
return r;
|
|
|
|
|
}, {});
|
|
|
|
|
const _data = Object.keys(groupByDate)
|
|
|
|
|
.reduce((r, _d) => {
|
|
|
|
|
const xAxisGroup = groupByDate[_d].reduce((a, v) => {
|
|
|
|
|
(a[v.groups] || (a[v.groups] = [])).push(v);
|
|
|
|
|
return a;
|
|
|
|
|
}, {});
|
|
|
|
|
Object.keys(xAxisGroup).map((_group) => {
|
|
|
|
|
const summaryVal = xAxisGroup[_group].reduce((rows, row) => rows + row.orderCount, 0);
|
|
|
|
|
r.push({ ...xAxisGroup[_group][0], orderCount: summaryVal });
|
|
|
|
|
return _group;
|
|
|
|
|
});
|
|
|
|
|
return r;
|
|
|
|
|
}, [])
|
|
|
|
|
.map((row) => ({ xField: row.ApplyDate, yField: row.orderCount, seriesField: row.groups }));
|
|
|
|
|
this.lineChartXGroup = value;
|
|
|
|
|
this.orderCountData = _data;
|
|
|
|
|
this.avgLine1 = avg1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 子维度页面的时间轴切换
|
|
|
|
|
*/
|
|
|
|
|
onChangeDateGroupSub = (value, data, avg1) => {
|
|
|
|
|
const groupByDate = data.reduce((r, v) => {
|
|
|
|
|
(r[v.ApplyDate] || (r[v.ApplyDate] = [])).push(v);
|
|
|
|
|
return r;
|
|
|
|
|
}, {});
|
|
|
|
|
const _data = Object.keys(groupByDate)
|
|
|
|
|
.reduce((r, _d) => {
|
|
|
|
|
const xAxisGroup = groupByDate[_d].reduce((a, v) => {
|
|
|
|
|
(a[v.groups] || (a[v.groups] = [])).push(v);
|
|
|
|
|
return a;
|
|
|
|
|
}, {});
|
|
|
|
|
Object.keys(xAxisGroup).map((_group) => {
|
|
|
|
|
const summaryVal = xAxisGroup[_group].reduce((rows, row) => rows + row.orderCount, 0);
|
|
|
|
|
r.push({ ...xAxisGroup[_group][0], orderCount: summaryVal });
|
|
|
|
|
return _group;
|
|
|
|
|
});
|
|
|
|
|
return r;
|
|
|
|
|
}, [])
|
|
|
|
|
.map((row) => ({ xField: row.ApplyDate, yField: row.orderCount, seriesField: row.groups, rowX: row.dateRange[0] }));
|
|
|
|
|
|
|
|
|
|
this.orderCount_type_dateRadio.lineChartXGroup = value;
|
|
|
|
|
this.orderCountData_type = _data;
|
|
|
|
|
this.orderCount_type_dateRadio.avgLine1 = avg1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
summaryAllWebcode = (json) => {
|
|
|
|
|
const groupByDate1 = json.ordercount1.reduce((r, v) => {
|
|
|
|
|
(r[v.ApplyDate] || (r[v.ApplyDate] = [])).push(v);
|
|
|
|
|
return r;
|
|
|
|
|
}, {});
|
|
|
|
|
const ordercount1 = Object.keys(groupByDate1).reduce((r, _date) => {
|
|
|
|
|
const summaryVal = groupByDate1[_date].reduce((rows, row) => rows + row.orderCount, 0);
|
|
|
|
|
r.push({ ...groupByDate1[_date][0], orderCount: summaryVal });
|
|
|
|
|
return r;
|
|
|
|
|
}, []);
|
|
|
|
|
const groupByDate2 = json.ordercount2.reduce((r, v) => {
|
|
|
|
|
(r[v.ApplyDate] || (r[v.ApplyDate] = [])).push(v);
|
|
|
|
|
return r;
|
|
|
|
|
}, {});
|
|
|
|
|
const ordercount2 = Object.keys(groupByDate2).reduce((r, _date) => {
|
|
|
|
|
const summaryVal = groupByDate2[_date].reduce((rows, row) => rows + row.orderCount, 0);
|
|
|
|
|
r.push({ ...groupByDate2[_date][0], orderCount: summaryVal });
|
|
|
|
|
return r;
|
|
|
|
|
}, []);
|
|
|
|
|
return { ...json, ordercount1, ordercount2 };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
parseOrderCount = (orderCountData, dateGroup) => {
|
|
|
|
|
resultDataCb(orderCountData, dateGroup, this.orderCountDataMapper, this.orderCountDataFieldMapper, this.onChangeDateGroup);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
parseOrderCount_type = (orderCountData, dateGroup) => {
|
|
|
|
|
resultDataCb(orderCountData, dateGroup, this.orderCount_type_dateRadio.orderCountDataMapper, this.orderCount_type_dateRadio.orderCountDataFieldMapper, this.onChangeDateGroupSub);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 网站订单数量,根据类型
|
|
|
|
|
getOrderCount_type(ordertype, ordertype_sub) {
|
|
|
|
|
this.loading = true;
|
|
|
|
|
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.SMALL_DATETIME_FORMAT);
|
|
|
|
|
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.SMALL_DATETIME_FORMAT);
|
|
|
|
|
}
|
|
|
|
|
fetch(config.HT_HOST + url)
|
|
|
|
|
.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;
|
|
|
|
|
const data = this.summaryAllWebcode(json);
|
|
|
|
|
this.orderCountDataRaw_type = data;
|
|
|
|
|
// 第一次得到数据
|
|
|
|
|
this.parseOrderCount_type(data, 'day');
|
|
|
|
|
this.loading = false;
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
this.loading = false;
|
|
|
|
|
console.log("fetch data failed", error);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 网站订单数量
|
|
|
|
|
getOrderCount() {
|
|
|
|
|
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;
|
|
|
|
|
url += "&COLI_ApplyDate1=" + date_picker_store.start_date.format(config.DATE_FORMAT) + "&COLI_ApplyDate2=" + date_picker_store.end_date.format(config.SMALL_DATETIME_FORMAT) ;
|
|
|
|
|
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.SMALL_DATETIME_FORMAT) ;
|
|
|
|
|
}
|
|
|
|
|
fetch(config.HT_HOST + url)
|
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(json => {
|
|
|
|
|
runInAction(() => {
|
|
|
|
|
const data = this.summaryAllWebcode(json);
|
|
|
|
|
this.orderCountDataRaw = data;
|
|
|
|
|
// 第一次得到数据
|
|
|
|
|
this.parseOrderCount(data, 'day');
|
|
|
|
|
this.loading = false;
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
this.loading = false;
|
|
|
|
|
console.log("fetch data failed", error);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 网站订单类型
|
|
|
|
|
getOrderCountByType(order_type) {
|
|
|
|
|
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.SMALL_DATETIME_FORMAT);
|
|
|
|
|
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.SMALL_DATETIME_FORMAT);
|
|
|
|
|
}
|
|
|
|
|
fetch(config.HT_HOST + url)
|
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(json => {
|
|
|
|
|
runInAction(() => {
|
|
|
|
|
// 错误:[MOBX]由于启用了严格模式,所以不允许改变观察到的在动作之外的值。如果此更改是有意的,请将代码包在“Actudio”中。
|
|
|
|
|
this.orderCountData_Form = json;
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.log("fetch data failed", error);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 子维度查询
|
|
|
|
|
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";
|
|
|
|
|
}
|
|
|
|
|
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.SMALL_DATETIME_FORMAT);
|
|
|
|
|
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.SMALL_DATETIME_FORMAT);
|
|
|
|
|
}
|
|
|
|
|
fetch(config.HT_HOST + url)
|
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(json => {
|
|
|
|
|
runInAction(() => {
|
|
|
|
|
// 错误:[MOBX]由于启用了严格模式,所以不允许改变观察到的在动作之外的值。如果此更改是有意的,请将代码包在“Actudio”中。
|
|
|
|
|
this.orderCountData_Form_sub = json;
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.log("fetch data failed", error);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 切换标签页
|
|
|
|
|
onChange_Tabs(active_key) {
|
|
|
|
|
this.active_tab_key = active_key;
|
|
|
|
|
this.getOrderCountByType(this.active_tab_key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default OrdersStore;
|