perf: 商务数据: 火车票Upsell: 各站

main
Lei OT 5 months ago
parent fcf449dd01
commit 16d5591921

@ -51,12 +51,14 @@ const TrainsUpsell = observer(({ ...props }) => {
const { date_picker_store: searchFormStore } = useContext(stores_Context);
const [searchValues, setSearchValues] = useTrainsStore(useShallow((state) => [state.searchValues, state.setSearchValues]));
const [loading] = useTrainsStore(useShallow((state) => [state.loading]));
const [loading, typeLoading] = useTrainsStore(useShallow((state) => [state.loading, state.typeLoading]));
const [trainsOrdersSummary, compareData] = useTrainsStore((state) => state.trainsOrdersSummary);
const trainsUpsellOrdersDetail = useTrainsStore((state) => state.trainsUpsellOrdersDetail);
// const showDiff = !comm.isEmpty(searchValuesToSub.DateDiff2);
const showDiff = !comm.isEmpty(compareData);
const getTrainsWithUpsell = useTrainsStore((state) => state.getTrainsWithUpsell);
const getTrainsOrderDetail = useTrainsStore((state) => state.getTrainsOrderDetail);
const data0 = buildFunnelData(trainsOrdersSummary, compareData);
const chartConfig = {
@ -126,12 +128,13 @@ const TrainsUpsell = observer(({ ...props }) => {
const tableProps = {
title: () => `${trainsOrdersSummary?.dateRangeStr || ''}` + (showDiff ? ` vs ${compareData?.dateRangeStr}` : ''),
dataSource: trainsOrdersSummary?.data || [],
columns: [
{
title: '#',
fixed: 'left',
dataIndex: 'OrderType',
},
// columns: [],
size: 'small',
pagination: false,
scroll: { x: 100 * 7 },
loading,
};
const tableCols = [
{
title: '数量',
dataIndex: 'OrderCount',
@ -163,12 +166,7 @@ const TrainsUpsell = observer(({ ...props }) => {
dataIndex: 'Ordervalue',
render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.Ordervalue_vs, r.Ordervalue_diff, r.Ordervalue, r.diff?.Ordervalue)),
},
],
size: 'small',
pagination: false,
scroll: { x: 100 * 7 },
loading,
};
];
return (
<>
<div>
@ -190,12 +188,13 @@ const TrainsUpsell = observer(({ ...props }) => {
onSubmit={(_err, obj, form, str) => {
setSearchValues(obj, form);
getTrainsWithUpsell(obj);
getTrainsOrderDetail(obj);
}}
/>
</Col>
</Row>
<Space direction={'vertical'}>
<Table sticky key={`table_1`} {...tableProps} />
<Table sticky key={`table_1`} {...tableProps} columns={[{ title: '#', fixed: 'left', dataIndex: 'OrderType' }, ...tableCols]} />
<Spin spinning={loading}>
<Row gutter={[16, { sm: 16, lg: 32 }]}>
@ -230,6 +229,16 @@ const TrainsUpsell = observer(({ ...props }) => {
</Col>
</Row>
</Spin>
<Table
sticky
key={`table_2`}
{...tableProps}
dataSource={trainsUpsellOrdersDetail[0]?.byWebCode || []}
loading={typeLoading}
columns={[{ title: '#', fixed: 'left', dataIndex: 'COLI_WebCode' }, ...tableCols]}
title={() => `火车票Upsell: 各站`}
/>
</Space>
</div>
</>

@ -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' }

Loading…
Cancel
Save