diff --git a/src/views/Orders.jsx b/src/views/Orders.jsx
index 703a470..e80e4f6 100644
--- a/src/views/Orders.jsx
+++ b/src/views/Orders.jsx
@@ -254,8 +254,12 @@ class Orders extends Component {
const table_data = orders_store.orderCountData_Form ? this.format_data(orders_store.orderCountData_Form) : [];
const data_source = orders_store.orderCountData ? orders_store.orderCountData : [];
const avg_line_y = Math.round(orders_store.avgLine1);
- const pie_data = comm.empty(orders_store.orderCountData_Form) ? [] : orders_store.orderCountData_Form.ordercount1.filter(ele => ele.OrderTypeSN); // 饼图的显示
- const pie_data2 = comm.empty(orders_store.orderCountData_Form) ? [] : orders_store.orderCountData_Form.ordercount2.filter(ele => ele.OrderTypeSN);
+ const pie_data = comm.empty(orders_store.orderCountData_Form)
+ ? []
+ : orders_store.orderCountData_Form.ordercount1.map((ele) => ({ ...ele, YJLYx: comm.price_to_number(ele.YJLY) })); // 饼图的显示
+ const pie_data2 = comm.empty(orders_store.orderCountData_Form)
+ ? []
+ : orders_store.orderCountData_Form.ordercount2.map((ele) => ({ ...ele, YJLYx: comm.price_to_number(ele.YJLY) }));
const config = {
data: data_source,
@@ -327,7 +331,7 @@ class Orders extends Component {
colorField: "OrderType",
radius: 0.8,
label: {
- type: "spider",
+ type: "outer",
content: "{name} {value} \t {percentage}",
},
legend: false, // 不显示图例
@@ -497,10 +501,12 @@ class Orders extends Component {
/>
-
+
+
-
+
+
diff --git a/src/views/biz/BizOrder.jsx b/src/views/biz/BizOrder.jsx
index f3b7078..ee4d320 100644
--- a/src/views/biz/BizOrder.jsx
+++ b/src/views/biz/BizOrder.jsx
@@ -1,6 +1,6 @@
import { useContext } from 'react';
import { Row, Col, Tabs, Table, Divider, Spin, Checkbox, Space } from 'antd';
-import { ContainerOutlined, BlockOutlined, SmileOutlined, MobileOutlined, CustomerServiceOutlined } from '@ant-design/icons';
+import { ContainerOutlined, BlockOutlined, SmileOutlined, MobileOutlined, CustomerServiceOutlined, IeOutlined } from '@ant-design/icons';
import { Line, Pie } from '@ant-design/charts';
import { NavLink } from 'react-router-dom';
import * as comm from '../../utils/commons';
@@ -19,7 +19,7 @@ const BizOrder = observer(() => {
const [searchValues, setSearchValues] = useBizOrderStore(useShallow((state) => [state.searchValues, state.setSearchValues]));
const [activeTab, setActiveTab] = useBizOrderStore(useShallow((state) => [state.activeTab, state.setActiveTab]));
- const [loading, onTabChange] = useBizOrderStore(useShallow((state) => [state.loading, state.onTabChange]));
+ const [loading, typeLoading, onTabChange] = useBizOrderStore(useShallow((state) => [state.loading, state.typeLoading,state.onTabChange]));
const orderCountDataRaw = useBizOrderStore((state) => state.orderCountDataRaw);
const [orderCountDataLines, avgLineValue] = useBizOrderStore(useShallow((state) => [state.orderCountDataLines, state.avgLineValue]));
@@ -104,7 +104,7 @@ const BizOrder = observer(() => {
radius: 0.8,
label: {
type: 'outer',
- content: '{name} {value} \n {percentage}',
+ content: '{name} {value} \t {percentage}',
},
legend: false, // 不显示图例
interactions: [
@@ -291,6 +291,15 @@ const BizOrder = observer(() => {
),
},
+ {
+ key: 'webcode',
+ label: (
+
+
+ 来源站点
+
+ ),
+ },
// {
// key: 'Product',
// label: (
@@ -404,7 +413,7 @@ const BizOrder = observer(() => {
...ele,
children: (
<>
-
+
@@ -425,14 +434,17 @@ const BizOrder = observer(() => {
包含空值
*/}
-
+
-
-
-
-
+
+
+
+ {showDiff &&
+
+
+ }
diff --git a/src/views/biz/reports/TrainsUpsell.jsx b/src/views/biz/reports/TrainsUpsell.jsx
index eb32443..c89c158 100644
--- a/src/views/biz/reports/TrainsUpsell.jsx
+++ b/src/views/biz/reports/TrainsUpsell.jsx
@@ -1,6 +1,6 @@
import { useContext } from 'react';
import { Row, Col, Table, Spin, Space, Divider } from 'antd';
-import { Funnel, Pie } from '@ant-design/charts';
+import { Funnel, Pie, Sunburst } from '@ant-design/charts';
import * as comm from '../../../utils/commons';
import SearchForm from '../../../components/search/SearchForm';
@@ -9,22 +9,37 @@ import { observer } from 'mobx-react';
import { toJS } from 'mobx';
import { stores_Context } from '../../../config';
import { useShallow } from 'zustand/shallow';
-import useTrainsStore from '../../../zustand/Trains';
+import useTrainsStore, { SERVICETYPE_TRAINSBOOKING, FORM_TRAINSUPSELL } from '../../../zustand/Trains';
+const buildSunburstData = (data1) => {
+ const total1 = (data1?.total || []).map((item) => {
+ return { ...item, name: item.label, value: item.YJLYx, children: data1?.data?.filter((child) => child.label === item.label).map((c2) => ({ ...c2, value: c2.YJLYx, name: c2.OrderType })) };
+ });
+ const ret1 = {
+ name: '预计利润',
+ // OrderType: 'xUpsell',
+ children: total1, // .sort((a, b) => a.name.localeCompare(b.name)), // .reverse(),
+ };
+ // if(data1) console.log('🉑', ret1);
+ return ret1;
+};
+
+const _getTrainService = (arr = []) => arr.find((item) => item.OrderTypeSN === SERVICETYPE_TRAINSBOOKING) || {};
+const _getTrainUpsell = (arr = []) => arr.find((item) => item.OrderTypeSN === FORM_TRAINSUPSELL) || {};
const buildFunnelData = (data1, data2) => {
// const key = 'OrderCount';
const data01 = [
- { stage: '火车票服务', number: data1?.data?.[0]?.OrderCount, dateRange: data1?.dateRangeStr },
- { stage: '成行出票', number: data1?.data?.[0]?.CJCount, dateRange: data1?.dateRangeStr },
- { stage: '火车票Upsell', number: (data1?.data?.[1]?.OrderCount || 0) + 0, dateRange: data1?.dateRangeStr },
- { stage: 'Upsell成行', number: data1?.data?.[1]?.CJCount, dateRange: data1?.dateRangeStr },
+ { stage: '火车票服务', number: _getTrainService(data1?.data)?.OrderCount, dateRange: data1?.dateRangeStr },
+ { stage: '成行出票', number: _getTrainService(data1?.data)?.CJCount, dateRange: data1?.dateRangeStr },
+ { stage: '火车票Upsell', number: (_getTrainUpsell(data1?.data)?.OrderCount || 0) + 0, dateRange: data1?.dateRangeStr },
+ { stage: 'Upsell成行', number: _getTrainUpsell(data1?.data)?.CJCount, dateRange: data1?.dateRangeStr },
];
const data02 = !comm.isEmpty(data2)
? [
- { stage: '火车票服务', number: data2?.data?.[0]?.OrderCount, dateRange: data2?.dateRangeStr },
- { stage: '成行出票', number: data2?.data?.[0]?.CJCount, dateRange: data2?.dateRangeStr },
- { stage: '火车票Upsell', number: data2?.data?.[1]?.OrderCount, dateRange: data2?.dateRangeStr },
- { stage: 'Upsell成行', number: data2?.data?.[1]?.CJCount, dateRange: data2?.dateRangeStr },
+ { stage: '火车票服务', number: _getTrainService(data2?.data)?.OrderCount || 0, dateRange: data2?.dateRangeStr },
+ { stage: '成行出票', number: _getTrainService(data2?.data)?.CJCount || 0, dateRange: data2?.dateRangeStr },
+ { stage: '火车票Upsell', number: _getTrainUpsell(data2?.data)?.OrderCount || 0, dateRange: data2?.dateRangeStr },
+ { stage: 'Upsell成行', number: _getTrainUpsell(data2?.data)?.CJCount || 0, dateRange: data2?.dateRangeStr },
]
: [];
return data01.concat(data02);
@@ -96,77 +111,91 @@ const TrainsUpsell = observer(({ ...props }) => {
},
};
- const pieData = buildPieData(trainsOrdersSummary);
- const pieData2 = buildPieData(compareData);
- // console.log('🟠', pieData, pieData2);
- const pieConfig = {
- appendPadding: 0,
- // data: pieData,
- angleField: 'number',
- colorField: 'stage',
- radius: 0.8,
- innerRadius: 0.6,
- // startAngle: Math.PI ,
- // endAngle: Math.PI * 1.5,
- label: {
- type: 'spider',
- // content: '{name} {value} \n {percentage}',
- content: '{name}\n{percentage}',
+ const sunburstData = buildSunburstData(trainsOrdersSummary, compareData);
+ const sunburstData2 = buildSunburstData(compareData);
+ const sunburstConfig = {
+ innerRadius: 0.3,
+ radius: 1,
+ colorField: 'name',
+ hierarchyConfig: {
+ // field: 'YJLYx',
+ ignoreParentValue: false,
+ sort: (a, b) => (a.name || '').localeCompare(b.name),
},
- statistic: false,
- legend: false, // 不显示图例
- interactions: [
- {
- type: 'element-selected',
- },
- {
- type: 'element-active',
- },
- ],
+ label: { layout: [{ type: 'limit-in-shape' }] },
+ interactions: [{ type: 'element-selected' }, { type: 'element-active' }],
};
+ // const pieData = buildPieData(trainsOrdersSummary);
+ // const pieData2 = buildPieData(compareData);
+ // console.log('🟠', pieData, pieData2);
+ // const pieConfig = {
+ // appendPadding: 0,
+ // // data: pieData,
+ // angleField: 'number',
+ // colorField: 'stage',
+ // radius: 0.8,
+ // innerRadius: 0.6,
+ // // startAngle: Math.PI ,
+ // // endAngle: Math.PI * 1.5,
+ // label: {
+ // type: 'spider',
+ // // content: '{name} {value} \n {percentage}',
+ // content: '{name}\n{percentage}',
+ // },
+ // statistic: false,
+ // legend: false, // 不显示图例
+ // interactions: [
+ // {
+ // type: 'element-selected',
+ // },
+ // {
+ // type: 'element-active',
+ // },
+ // ],
+ // };
+
const tableProps = {
title: () => `${trainsOrdersSummary?.dateRangeStr || ''}` + (showDiff ? ` vs ${compareData?.dateRangeStr}` : ''),
- dataSource: trainsOrdersSummary?.data || [],
// columns: [],
size: 'small',
pagination: false,
- scroll: { x: 100 * 7 },
+ // scroll: { x: 100 * 7 },
loading,
};
const tableCols = [
- {
- title: '数量',
- dataIndex: 'OrderCount',
- render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.OrderCount_vs, r.OrderCount_diff, r.OrderCount, r.diff?.OrderCount)),
- },
- {
- title: '成交数',
- dataIndex: 'CJCount',
- render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.CJCount_vs, r.CJCount_diff, r.CJCount, r.diff?.CJCount)),
- },
- {
- title: '成交人数',
- dataIndex: 'CJPersonNum',
- render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.CJPersonNum_vs, r.CJPersonNum_diff, r.CJPersonNum, r.diff?.CJPersonNum)),
- },
- {
- title: '成交率',
- dataIndex: 'CJrate',
- render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.CJrate_vs, r.CJrate_diff, r.CJrate, r.diff?.CJrate)),
- },
- {
- title: '成交毛利(预计)',
- dataIndex: 'YJLY',
- render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.YJLY_vs, r.YJLY_diff, r.YJLY, r.diff?.YJLY)),
- },
+ {
+ title: '数量',
+ dataIndex: 'OrderCount',
+ render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.OrderCount_vs, r.OrderCount_diff, r.OrderCount, r.diff?.OrderCount)),
+ },
+ {
+ title: '成交数',
+ dataIndex: 'CJCount',
+ render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.CJCount_vs, r.CJCount_diff, r.CJCount, r.diff?.CJCount)),
+ },
+ {
+ title: '成交人数',
+ dataIndex: 'CJPersonNum',
+ render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.CJPersonNum_vs, r.CJPersonNum_diff, r.CJPersonNum, r.diff?.CJPersonNum)),
+ },
+ {
+ title: '成交率',
+ dataIndex: 'CJrate',
+ render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.CJrate_vs, r.CJrate_diff, r.CJrate, r.diff?.CJrate)),
+ },
+ {
+ title: '成交毛利(预计)',
+ dataIndex: 'YJLY',
+ render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.YJLY_vs, r.YJLY_diff, r.YJLY, r.diff?.YJLY)),
+ },
- {
- title: '单个订单价值',
- dataIndex: 'Ordervalue',
- render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.Ordervalue_vs, r.Ordervalue_diff, r.Ordervalue, r.diff?.Ordervalue)),
- },
- ];
+ {
+ title: '单个订单价值',
+ dataIndex: 'Ordervalue',
+ render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.Ordervalue_vs, r.Ordervalue_diff, r.Ordervalue, r.diff?.Ordervalue)),
+ },
+ ];
return (
<>
@@ -194,8 +223,18 @@ const TrainsUpsell = observer(({ ...props }) => {
-
+
+
+
+ 火车票
@@ -205,7 +244,22 @@ const TrainsUpsell = observer(({ ...props }) => {
预计利润
-
+ {showDiff && (
+
+ )}
+ {/*
{
color={['#61DDAA', '#5B8FF9']}
pattern={{ type: 'line' }}
/>
- )}
+ )} */}
@@ -238,7 +292,10 @@ const TrainsUpsell = observer(({ ...props }) => {
loading={typeLoading}
columns={[{ title: '#', fixed: 'left', dataIndex: 'COLI_WebCode' }, ...tableCols]}
title={() => `火车票Upsell: 各站`}
+ rowKey={'COLI_WebCode'}
/>
+
+ {/* 外联营销 */}
>
diff --git a/src/zustand/BizOrder.js b/src/zustand/BizOrder.js
index 433a593..a683eb8 100644
--- a/src/zustand/BizOrder.js
+++ b/src/zustand/BizOrder.js
@@ -5,7 +5,7 @@ import { groupsMappedByCode } from '../libs/ht';
import { fetchJSON } from '../utils/request';
import { HT_HOST } from '../config';
import { resultDataCb } from '../components/DateGroupRadio/date';
-import { isEmpty } from '../utils/commons';
+import { isEmpty, price_to_number } from '../utils/commons';
const defaultParams = { WebCode: 'all', IncludeTickets: 1, IncludeInternal: 1 };
@@ -50,15 +50,15 @@ export const fetchBizOrderCountByType = async (type, params) => {
OrderType: type,
});
const res = errcode !== 0 ? _typeRes : (result || _typeRes);
- const rows1Map = res.ordercount1.reduce((a, row1) => ({ ...a, [row1.OrderTypeSN]: row1 }), {});
- const rows2Map = res.ordercount2.reduce((a, row2) => ({ ...a, [row2.OrderTypeSN]: row2 }), {});
+ const rows1Map = res.ordercount1.reduce((a, row1) => ({ ...a, [row1.OrderTypeSN]: {...row1, YJLYx: price_to_number(row1.YJLY)} }), {});
+ const rows2Map = res.ordercount2.reduce((a, row2) => ({ ...a, [row2.OrderTypeSN]: {...row2, YJLYx: price_to_number(row2.YJLY)} }), {});
- const mixRow1 = res.ordercount1.map((row1) => ({ ...row1, diff: rows2Map[row1.OrderTypeSN] || {} }));
+ const mixRow1 = res.ordercount1.map((row1) => ({ ...row1, YJLYx: price_to_number(row1.YJLY), diff: rows2Map[row1.OrderTypeSN] || {} }));
// Diff: elements in rows2 but not in rows1
const diff = [...new Set(Object.keys(rows2Map).filter((x) => !new Set(Object.keys(rows1Map)).has(x)))];
mixRow1.push(...diff.map((sn) => ({ diff: rows2Map[sn], OrderType: rows2Map[sn].OrderType, OrderTypeSN: rows2Map[sn].OrderTypeSN })));
- return { ...res, ordercount1: mixRow1 };
+ return { ...res, ordercount1: mixRow1, ordercount2: res.ordercount2.map((row1) => ({ ...row1, YJLYx: price_to_number(row1.YJLY), })) };
};
const _detailRes = { ordercount1: [], ordercount2: [] };
diff --git a/src/zustand/Trains.js b/src/zustand/Trains.js
index 6cbea43..70ca367 100644
--- a/src/zustand/Trains.js
+++ b/src/zustand/Trains.js
@@ -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());
};
/**