|
|
|
|
@ -4,17 +4,21 @@ import { immer } from 'zustand/middleware/immer';
|
|
|
|
|
import { groupsCTplus, groupsMappedByCode } from '../libs/ht';
|
|
|
|
|
import { fetchJSON } from '../utils/request';
|
|
|
|
|
import { HT_HOST } from '../config';
|
|
|
|
|
import { resultDataCb } from '../components/DateGroupRadio/date';
|
|
|
|
|
import { fixTo2Decimals, fixTo4Decimals, groupBy, isEmpty } from '../utils/commons';
|
|
|
|
|
import { fixTo2Decimals, fixTo4Decimals, groupBy, isEmpty, price_to_number } from '../utils/commons';
|
|
|
|
|
|
|
|
|
|
const SERVICETYPE_TRAINSBOOKING = '2'; // 火车票服务
|
|
|
|
|
const FORM_TRAINSBOOKING = 32024; // 火车票预定
|
|
|
|
|
const FORM_TRAINSUPSELL = 32214; // 火车票Upsell
|
|
|
|
|
/** 火车票服务 */
|
|
|
|
|
export const SERVICETYPE_TRAINSBOOKING = '2';
|
|
|
|
|
/** 火车票预定 */
|
|
|
|
|
export const FORM_TRAINSBOOKING = 32024;
|
|
|
|
|
/** 火车票Upsell */
|
|
|
|
|
export const FORM_TRAINSUPSELL = 32214;
|
|
|
|
|
/** 外联老客户营销 */
|
|
|
|
|
export const FORM_SALESSUPSELL = 32213;
|
|
|
|
|
|
|
|
|
|
const defaultParams = { WebCode: 'all', IncludeTickets: 1, IncludeInternal: 1 };
|
|
|
|
|
const _res = { ordercount1: [], ordercount2: [] };
|
|
|
|
|
|
|
|
|
|
export const fetchBizTrainsOrderSummaryByType = async (params, type = 'Form', typeVal = '') => {
|
|
|
|
|
export const fetchBizTrainsOrderSummaryByType = async (params, type = 'Form', typeVals = []) => {
|
|
|
|
|
const { errcode, errmsg, ...result } = await fetchJSON(HT_HOST + '/service-web/QueryData/GetOrderCountByType_biz', {
|
|
|
|
|
...defaultParams,
|
|
|
|
|
...params,
|
|
|
|
|
@ -27,20 +31,36 @@ export const fetchBizTrainsOrderSummaryByType = async (params, type = 'Form', ty
|
|
|
|
|
const res = errcode !== 0 ? _res : result || _res;
|
|
|
|
|
const dateStr = [params.Date1, params.Date2].map((d) => d.substring(0, 10)).join('~');
|
|
|
|
|
const ret = [
|
|
|
|
|
{ dateRangeStr: dateStr, data: res.ordercount1.find((row) => row.OrderTypeSN === typeVal) },
|
|
|
|
|
{
|
|
|
|
|
dateRangeStr: dateStr,
|
|
|
|
|
data: res.ordercount1.filter((row) => typeVals.includes(row.OrderTypeSN)).map((row) => ({ ...row, YJLYx: price_to_number(row.YJLY), label: '商务' })),
|
|
|
|
|
total: { ...res.ordercountTotal1, YJLYx: price_to_number(res.ordercountTotal1.YJLY), label: '商务' },
|
|
|
|
|
type,
|
|
|
|
|
},
|
|
|
|
|
// { dateRangeStr: dateDiffStr, data: res.ordercount2.find((row) => row.OrderTypeSN === typeVal) },
|
|
|
|
|
];
|
|
|
|
|
const dateDiffStr = isEmpty(params.DateDiff1) ? '' : [params.DateDiff1, params.DateDiff2].map((d) => d.substring(0, 10)).join('~');
|
|
|
|
|
if (!isEmpty(dateDiffStr)) {
|
|
|
|
|
ret.push({ dateRangeStr: dateDiffStr, data: res.ordercount2.find((row) => row.OrderTypeSN === typeVal) });
|
|
|
|
|
ret[0].total.diff = { ...res.ordercountTotal2, YJLYx: price_to_number(res.ordercountTotal2.YJLY) };
|
|
|
|
|
ret[0].data.forEach((row) => {
|
|
|
|
|
const _find = res.ordercount2.find((row2) => row2.OrderTypeSN === row.OrderTypeSN) || {};
|
|
|
|
|
row.diff = { ..._find, YJLYx: price_to_number(_find.YJLY || 0) };
|
|
|
|
|
});
|
|
|
|
|
ret.push({
|
|
|
|
|
dateRangeStr: dateDiffStr,
|
|
|
|
|
data: res.ordercount2.filter((row) => typeVals.includes(row.OrderTypeSN)).map((row) => ({ ...row, YJLYx: price_to_number(row.YJLY), label: '商务' })),
|
|
|
|
|
total: { ...res.ordercountTotal2, YJLYx: price_to_number(res.ordercountTotal2.YJLY), label: '商务' },
|
|
|
|
|
type,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
// console.log('😉', ret);
|
|
|
|
|
return ret;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从传统订单中获取upsell数据
|
|
|
|
|
*/
|
|
|
|
|
export const fetchTrainsUpsellTSummaryByType = async (params, type = 'Form', typeVal = '') => {
|
|
|
|
|
export const fetchTrainsUpsellTSummaryByType = async (params, type = 'Form', typeVals = []) => {
|
|
|
|
|
const { errcode, errmsg, ...result } = await fetchJSON(HT_HOST + '/service-web/QueryData/GetOrderCountByType', {
|
|
|
|
|
...defaultParams,
|
|
|
|
|
...params,
|
|
|
|
|
@ -53,13 +73,29 @@ export const fetchTrainsUpsellTSummaryByType = async (params, type = 'Form', typ
|
|
|
|
|
const res = errcode !== 0 ? _res : result || _res;
|
|
|
|
|
const dateStr = [params.Date1, params.Date2].map((d) => d.substring(0, 10)).join('~');
|
|
|
|
|
const ret = [
|
|
|
|
|
{ dateRangeStr: dateStr, data: res.ordercount1.find((row) => row.OrderTypeSN === typeVal) },
|
|
|
|
|
{
|
|
|
|
|
dateRangeStr: dateStr,
|
|
|
|
|
data: res.ordercount1.filter((row) => typeVals.includes(row.OrderTypeSN)).map(row => ({...row, YJLYx: price_to_number(row.YJLY), label: '传统'})),
|
|
|
|
|
total: { ...res.ordercountTotal1, YJLYx: price_to_number(res.ordercountTotal1.YJLY), label: '传统' },
|
|
|
|
|
type,
|
|
|
|
|
},
|
|
|
|
|
// { dateRangeStr: dateDiffStr, data: res.ordercount2.find((row) => row.OrderTypeSN === typeVal) },
|
|
|
|
|
];
|
|
|
|
|
const dateDiffStr = isEmpty(params.DateDiff1) ? '' : [params.DateDiff1, params.DateDiff2].map((d) => d.substring(0, 10)).join('~');
|
|
|
|
|
if (!isEmpty(dateDiffStr)) {
|
|
|
|
|
ret.push({ dateRangeStr: dateDiffStr, data: res.ordercount2.find((row) => row.OrderTypeSN === typeVal) });
|
|
|
|
|
ret[0].total.diff = { ...res.ordercountTotal2, YJLYx: price_to_number(res.ordercountTotal2.YJLY) };
|
|
|
|
|
ret[0].data.forEach((row) => {
|
|
|
|
|
const _find = res.ordercount2.find((row2) => row2.OrderTypeSN === row.OrderTypeSN) || {};
|
|
|
|
|
row.diff = { ..._find, YJLYx: price_to_number(_find.YJLY || 0) };
|
|
|
|
|
});
|
|
|
|
|
ret.push({
|
|
|
|
|
dateRangeStr: dateDiffStr,
|
|
|
|
|
data: res.ordercount2.filter((row) => typeVals.includes(row.OrderTypeSN)).map(row => ({...row, YJLYx: price_to_number(row.YJLY), label: '传统'})),
|
|
|
|
|
total: { ...res.ordercountTotal2, YJLYx: price_to_number(res.ordercountTotal2.YJLY), label: '传统' },
|
|
|
|
|
type,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
// console.log('😉😉', ret);
|
|
|
|
|
return ret;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -83,10 +119,10 @@ const calcSummary = (arr, keepKeys = []) => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const _detailRes = { ordercount1: [], ordercount2: [] };
|
|
|
|
|
export const fetchUpsellOrderDetailByType = async (params, type = 'Form', typeVal = FORM_TRAINSUPSELL, orderContent = 'detail') => {
|
|
|
|
|
export const fetchUpsellOrderDetailByType = async (params, type = 'Form', typeVal = FORM_TRAINSUPSELL) => {
|
|
|
|
|
const { errcode, errmsg, ...result } = await fetchJSON(HT_HOST + '/service-web/QueryData/GetOrderCountByType_Sub', {
|
|
|
|
|
...defaultParams,
|
|
|
|
|
SubOrderType: orderContent,
|
|
|
|
|
SubOrderType: 'detail',
|
|
|
|
|
...params,
|
|
|
|
|
COLI_ApplyDate1: params.Date1,
|
|
|
|
|
COLI_ApplyDate2: params.Date2,
|
|
|
|
|
@ -114,8 +150,8 @@ export const fetchUpsellOrderDetailByType = async (params, type = 'Form', typeVa
|
|
|
|
|
if (!isEmpty(dateDiffStr)) {
|
|
|
|
|
const [{ byWebCode: byWebCode1 }, { byWebCode: byWebCode2 }] = retS;
|
|
|
|
|
const withDiff1 = byWebCode1.map((row, i) => {
|
|
|
|
|
const row2 = byWebCode2.find((r2) => r2.COLI_WebCode === row.COLI_WebCode);
|
|
|
|
|
row.diff = row2 || {};
|
|
|
|
|
const row2 = (byWebCode2.find((r2) => r2.COLI_WebCode === row.COLI_WebCode)) || {};
|
|
|
|
|
row.diff = row2;
|
|
|
|
|
row.CJCount_vs = row2.CJCount ? fixTo2Decimals(((row.CJCount - row2.CJCount) / row2.CJCount) * 100) : 0;
|
|
|
|
|
row.CJPersonNum_vs = row2.CJPersonNum ? fixTo2Decimals(((row.CJPersonNum - row2.CJPersonNum) / row2.CJPersonNum) * 100) : 0;
|
|
|
|
|
row.CJrate_vs = row2.CJrate ? fixTo2Decimals(row.CJrate - row2.CJrate) : 0;
|
|
|
|
|
@ -156,6 +192,9 @@ export const fetchUpsellOrderDetailByType = async (params, type = 'Form', typeVa
|
|
|
|
|
retS.forEach(({ summary, byWebCode }, i) => {
|
|
|
|
|
summary.CJrate = `${summary.CJrate}%`;
|
|
|
|
|
if (i !== 0) {
|
|
|
|
|
byWebCode.forEach((row) => {
|
|
|
|
|
row.CJrate = `${row.CJrate}%`;
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
byWebCode.forEach((row) => {
|
|
|
|
|
row.CJrate = `${row.CJrate}%`;
|
|
|
|
|
@ -172,37 +211,33 @@ export const fetchUpsellOrderDetailByType = async (params, type = 'Form', typeVa
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const fetchTrainsWithUpsellSummary = async (params) => {
|
|
|
|
|
const [trains, upsell] = await Promise.all([
|
|
|
|
|
// fetchBizTrainsOrderSummaryByType(params, 'Form', FORM_TRAINSBOOKING), // todo: 换成servicetype=2
|
|
|
|
|
fetchBizTrainsOrderSummaryByType(params, 'servicetype', SERVICETYPE_TRAINSBOOKING),
|
|
|
|
|
fetchTrainsUpsellTSummaryByType(params, 'Form', FORM_TRAINSUPSELL),
|
|
|
|
|
const [bizForm, bizService, upsell] = await Promise.all([
|
|
|
|
|
fetchBizTrainsOrderSummaryByType(params, 'Form', [FORM_TRAINSBOOKING]),
|
|
|
|
|
fetchBizTrainsOrderSummaryByType(params, 'servicetype', [SERVICETYPE_TRAINSBOOKING]),
|
|
|
|
|
fetchTrainsUpsellTSummaryByType(params, 'Form', [FORM_TRAINSUPSELL, FORM_SALESSUPSELL]),
|
|
|
|
|
]);
|
|
|
|
|
if (!isEmpty(trains[1])) {
|
|
|
|
|
trains[0].data.diff = trains[1].data;
|
|
|
|
|
upsell[0].data.diff = upsell[1].data;
|
|
|
|
|
}
|
|
|
|
|
const mergedMap = [...trains, ...upsell].reduce((acc, currentItem, currentIndex) => {
|
|
|
|
|
const dateRange = currentItem.dateRangeStr;
|
|
|
|
|
// console.log('🟠','\n', structuredClone(bizForm), '\n', structuredClone(bizService),'\n', structuredClone(upsell));
|
|
|
|
|
const bizTotalOnly = structuredClone(bizForm).map((item) => ({ ...item, data: [] }));
|
|
|
|
|
const bizServiceDataOnly = structuredClone(bizService).map((item) => ({ ...item, total: {} }));
|
|
|
|
|
// console.log('🟠',bizTotalOnly, '\n', '\n', bizServiceDataOnly,'\n', upsell);
|
|
|
|
|
const mapByDate = new Map();
|
|
|
|
|
for (const item of [...bizTotalOnly, ...bizServiceDataOnly, ...upsell]) {
|
|
|
|
|
const dateRange = item.dateRangeStr;
|
|
|
|
|
|
|
|
|
|
if (acc[dateRange]) {
|
|
|
|
|
acc[dateRange].data.push(currentItem.data);
|
|
|
|
|
|
|
|
|
|
for (const key in currentItem) {
|
|
|
|
|
if (key !== 'dateRange' && key !== 'data') {
|
|
|
|
|
acc[dateRange][key] = currentItem[key];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (mapByDate.has(dateRange)) {
|
|
|
|
|
const existingItem = mapByDate.get(dateRange);
|
|
|
|
|
if (!isEmpty(item.total)) existingItem.total.push(item.total);
|
|
|
|
|
existingItem.data.push(...item.data);
|
|
|
|
|
} else {
|
|
|
|
|
acc[dateRange] = {
|
|
|
|
|
...currentItem,
|
|
|
|
|
data: [currentItem.data],
|
|
|
|
|
};
|
|
|
|
|
mapByDate.set(dateRange, {
|
|
|
|
|
...item,
|
|
|
|
|
data: item.data,
|
|
|
|
|
total: [item.total],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return acc;
|
|
|
|
|
}, {});
|
|
|
|
|
return Object.values(mergedMap);
|
|
|
|
|
// return groupBy([...trains, ...upsell], 'dateRangeStr');
|
|
|
|
|
}
|
|
|
|
|
// console.log('🔰0', Array.from(mapByDate.values()));
|
|
|
|
|
return Array.from(mapByDate.values());
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|