|
|
|
|
@ -5,7 +5,7 @@ import { groupsCTplus, groupsMappedByCode } from '../libs/ht';
|
|
|
|
|
import { fetchJSON } from '../utils/request';
|
|
|
|
|
import { HT_HOST } from '../config';
|
|
|
|
|
import { resultDataCb } from '../components/DateGroupRadio/date';
|
|
|
|
|
import { groupBy, isEmpty } from '../utils/commons';
|
|
|
|
|
import { fixTo2Decimals, fixTo4Decimals, groupBy, isEmpty } from '../utils/commons';
|
|
|
|
|
|
|
|
|
|
const SERVICETYPE_TRAINSBOOKING = '2'; // 火车票服务
|
|
|
|
|
const FORM_TRAINSBOOKING = 32024; // 火车票预定
|
|
|
|
|
@ -63,6 +63,114 @@ export const fetchTrainsUpsellTSummaryByType = async (params, type = 'Form', typ
|
|
|
|
|
return ret;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const calcSummary = (arr, keepKeys = []) => {
|
|
|
|
|
const s = arr.reduce(
|
|
|
|
|
(acc, cur) => {
|
|
|
|
|
acc.CJCount += cur.COLI_Success === 1 ? 1 : 0;
|
|
|
|
|
acc.CJPersonNum += cur.COLI_Success === 1 ? cur.COLI_PersonNum + cur.COLI_ChildNum + cur.COLI_BabyNum : 0;
|
|
|
|
|
acc.OrderCount += 1;
|
|
|
|
|
acc.YJLY += cur.CGI_YJLY;
|
|
|
|
|
keepKeys.forEach((key) => {
|
|
|
|
|
acc[key] = cur[key];
|
|
|
|
|
});
|
|
|
|
|
return acc;
|
|
|
|
|
},
|
|
|
|
|
{ CJCount: 0, CJPersonNum: 0, CJrate: 0, OrderCount: 0, YJLY: 0 }
|
|
|
|
|
);
|
|
|
|
|
s.CJrate = s.OrderCount ? (fixTo2Decimals(s.CJCount / s.OrderCount * 100)) : 0;
|
|
|
|
|
s.YJLY = fixTo2Decimals(s.YJLY);
|
|
|
|
|
return s;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const _detailRes = { ordercount1: [], ordercount2: [] };
|
|
|
|
|
export const fetchUpsellOrderDetailByType = async (params, type = 'Form', typeVal = FORM_TRAINSUPSELL, orderContent = 'detail') => {
|
|
|
|
|
const { errcode, errmsg, ...result } = await fetchJSON(HT_HOST + '/service-web/QueryData/GetOrderCountByType_Sub', {
|
|
|
|
|
...defaultParams,
|
|
|
|
|
SubOrderType: orderContent,
|
|
|
|
|
...params,
|
|
|
|
|
COLI_ApplyDate1: params.Date1,
|
|
|
|
|
COLI_ApplyDate2: params.Date2,
|
|
|
|
|
COLI_ApplyDateOld1: params.DateDiff1 || '',
|
|
|
|
|
COLI_ApplyDateOld2: params.DateDiff2 || '',
|
|
|
|
|
OrderType: type,
|
|
|
|
|
OrderType_val: typeVal,
|
|
|
|
|
});
|
|
|
|
|
const res = errcode !== 0 ? _detailRes : (result || _detailRes);
|
|
|
|
|
const dateStr = [params.Date1, params.Date2].map((d) => d.substring(0, 10)).join('~');
|
|
|
|
|
const ret = [
|
|
|
|
|
{ dateRangeStr: dateStr, data: res.ordercount1 },
|
|
|
|
|
// { dateRangeStr: dateDiffStr, data: res.ordercount2 },
|
|
|
|
|
];
|
|
|
|
|
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 });
|
|
|
|
|
}
|
|
|
|
|
const retS = ret.map(({ dateRangeStr, data }) => {
|
|
|
|
|
const byWebCode = (Object.values(groupBy(data, 'COLI_WebCode'))).map((group) => calcSummary(group, ['COLI_WebCode']));
|
|
|
|
|
const summary = calcSummary(data);
|
|
|
|
|
return { dateRangeStr, data , summary, byWebCode };
|
|
|
|
|
});
|
|
|
|
|
// diff
|
|
|
|
|
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 || {};
|
|
|
|
|
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;
|
|
|
|
|
row.YJLY_vs = row2.YJLY ? fixTo2Decimals(((row.YJLY - row2.YJLY) / row2.YJLY) * 100) : 0;
|
|
|
|
|
row.OrderCount_vs = row2.OrderCount ? fixTo2Decimals(((row.OrderCount - row2.OrderCount) / row2.OrderCount) * 100) : 0;
|
|
|
|
|
row.CJCount_diff = row2.CJCount ? row.CJCount - row2.CJCount : 0;
|
|
|
|
|
row.CJPersonNum_diff = row2.CJPersonNum ? row.CJPersonNum - row2.CJPersonNum : 0;
|
|
|
|
|
row.CJrate_diff = row2.CJrate ? fixTo2Decimals(row.CJrate - row2.CJrate) : 0;
|
|
|
|
|
row.YJLY_diff = row2.YJLY ? fixTo2Decimals(row.YJLY - row2.YJLY) : 0;
|
|
|
|
|
row.OrderCount_diff = row2.OrderCount ? row.OrderCount - row2.OrderCount : 0;
|
|
|
|
|
return row;
|
|
|
|
|
});
|
|
|
|
|
//
|
|
|
|
|
const rows1Map = byWebCode1.reduce((a, row1) => ({ ...a, [row1.COLI_WebCode]: row1 }), {});
|
|
|
|
|
const rows2Map = byWebCode2.reduce((a, row2) => ({ ...a, [row2.COLI_WebCode]: row2 }), {});
|
|
|
|
|
// Diff: elements in rows2 but not in rows1
|
|
|
|
|
const diffKey = [...new Set(Object.keys(rows2Map).filter((x) => !new Set(Object.keys(rows1Map)).has(x)))];
|
|
|
|
|
withDiff1.push(
|
|
|
|
|
...diffKey.map((key) => ({
|
|
|
|
|
diff: rows2Map[key],
|
|
|
|
|
CJrate: 0,
|
|
|
|
|
COLI_WebCode: rows2Map[key].COLI_WebCode,
|
|
|
|
|
CJCount_vs: -100,
|
|
|
|
|
CJPersonNum_vs: -100,
|
|
|
|
|
CJrate_vs: -100,
|
|
|
|
|
YJLY_vs: -100,
|
|
|
|
|
OrderCount_vs: -100,
|
|
|
|
|
CJCount_diff: -rows2Map[key].CJCount,
|
|
|
|
|
CJPersonNum_diff: -rows2Map[key].CJPersonNum,
|
|
|
|
|
CJrate_diff: -rows2Map[key].CJrate,
|
|
|
|
|
YJLY_diff: -rows2Map[key].YJLY,
|
|
|
|
|
OrderCount_diff: -rows2Map[key].OrderCount,
|
|
|
|
|
}))
|
|
|
|
|
);
|
|
|
|
|
retS[0].byWebCode = withDiff1;
|
|
|
|
|
}
|
|
|
|
|
// %
|
|
|
|
|
retS.forEach(({ summary, byWebCode }, i) => {
|
|
|
|
|
summary.CJrate = `${summary.CJrate}%`;
|
|
|
|
|
if (i !== 0) {
|
|
|
|
|
} else {
|
|
|
|
|
byWebCode.forEach((row) => {
|
|
|
|
|
row.CJrate = `${row.CJrate}%`;
|
|
|
|
|
row.CJrate_vs = `${row.CJrate_vs}%`;
|
|
|
|
|
row.CJrate_diff = `${row.CJrate_diff}%`;
|
|
|
|
|
row.CJCount_vs = `${row.CJCount_vs}%`;
|
|
|
|
|
row.CJPersonNum_vs = `${row.CJPersonNum_vs}%`;
|
|
|
|
|
row.OrderCount_vs = `${row.OrderCount_vs}%`;
|
|
|
|
|
row.YJLY_vs = `${row.YJLY_vs}%`;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return retS;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const fetchTrainsWithUpsellSummary = async (params) => {
|
|
|
|
|
const [trains, upsell] = await Promise.all([
|
|
|
|
|
// fetchBizTrainsOrderSummaryByType(params, 'Form', FORM_TRAINSBOOKING), // todo: 换成servicetype=2
|
|
|
|
|
@ -117,6 +225,7 @@ const initialState = {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
trainsOrdersSummary: [],
|
|
|
|
|
trainsUpsellOrdersDetail: [],
|
|
|
|
|
|
|
|
|
|
activeTab: 'Form',
|
|
|
|
|
activeDateGroupRadio: 'day',
|
|
|
|
|
@ -170,6 +279,19 @@ const useTrainsStore = create(
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getTrainsOrderDetail: async (params) => {
|
|
|
|
|
const { setTypeLoading } = get();
|
|
|
|
|
setTypeLoading(true);
|
|
|
|
|
set({ trainsUpsellOrdersDetail: [] });
|
|
|
|
|
try {
|
|
|
|
|
const res = await fetchUpsellOrderDetailByType(params);
|
|
|
|
|
set({ trainsUpsellOrdersDetail: res });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
} finally {
|
|
|
|
|
setTypeLoading(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// sub
|
|
|
|
|
})),
|
|
|
|
|
{ name: 'trains' }
|
|
|
|
|
|