You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
8.9 KiB
JavaScript
242 lines
8.9 KiB
JavaScript
import { create } from 'zustand';
|
|
import { devtools } from 'zustand/middleware';
|
|
import { immer } from 'zustand/middleware/immer';
|
|
import { groupsMappedByCode } from '../libs/ht';
|
|
import { fetchJSON } from '@haina/utils-request';
|
|
import { HT_HOST } from '../config';
|
|
import { resultDataCb } from '../components/DateGroupRadio/date';
|
|
import { isEmpty, price_to_number } from '@haina/utils-commons';
|
|
|
|
/**
|
|
* 分销(ToB)订单
|
|
*/
|
|
|
|
const defaultParams = {};
|
|
|
|
export const fetchToBOrderCount = async (params, type = '', typeVal = '') => {
|
|
const { errcode, errmsg, ...result } = await fetchJSON(HT_HOST + '/service-web/QueryData/GetOrderCount_FX', {
|
|
...defaultParams,
|
|
...params,
|
|
COLI_ApplyDate1: params.Date1,
|
|
COLI_ApplyDate2: params.Date2,
|
|
COLI_ApplyDateOld1: params.DateDiff1 || '',
|
|
COLI_ApplyDateOld2: params.DateDiff2 || '',
|
|
OrderType: type,
|
|
OrderType_val: typeVal,
|
|
});
|
|
return errcode !== 0 ? {} : (result || {});
|
|
};
|
|
|
|
const _typeRes = {
|
|
'ordercount1': [],
|
|
'ordercount2': [],
|
|
'ordercountTotal1': {
|
|
'OrderType': '合计',
|
|
'OrderCount': 0,
|
|
'CJCount': 0,
|
|
'CJPersonNum': 0,
|
|
'YJLY': '',
|
|
'CJrate': '0%',
|
|
'Ordervalue': '',
|
|
'groups': '',
|
|
'key': 1,
|
|
},
|
|
'ordercountTotal2': {},
|
|
};
|
|
export const fetchToBOrderCountByType = async (type, params) => {
|
|
const { errcode, errmsg, ...result } = await fetchJSON(HT_HOST + '/service-web/QueryData/GetOrderCountByType_FX', {
|
|
...defaultParams,
|
|
...params,
|
|
COLI_ApplyDate1: params.Date1,
|
|
COLI_ApplyDate2: params.Date2,
|
|
COLI_ApplyDateOld1: params.DateDiff1 || '',
|
|
COLI_ApplyDateOld2: params.DateDiff2 || '',
|
|
OrderType: type,
|
|
});
|
|
const res = errcode !== 0 ? _typeRes : (result || _typeRes);
|
|
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, 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, ordercount2: res.ordercount2.map((row1) => ({ ...row1, YJLYx: price_to_number(row1.YJLY), })) };
|
|
};
|
|
|
|
const _detailRes = { ordercount1: [], ordercount2: [] };
|
|
export const fetchToBOrderDetailByType = async (params, type = '', typeVal = '', orderContent = 'detail') => {
|
|
const { errcode, errmsg, ...result } = await fetchJSON(HT_HOST + '/service-web/QueryData/GetOrderCountByType_Sub_FX', {
|
|
...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 dateDiffStr = isEmpty(params.DateDiff1) ? '' : [params.DateDiff1, params.DateDiff2].map((d) => d.substring(0, 10)).join('~');
|
|
const ret = [
|
|
{ dateRangeStr: dateStr, data: res.ordercount1 },
|
|
{ dateRangeStr: dateDiffStr, data: res.ordercount2 },
|
|
];
|
|
return ret;
|
|
};
|
|
|
|
const calculateLineData = (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 }));
|
|
return { lines: _data, dateRadioValue: value, avgLineValue: avg1 };
|
|
};
|
|
|
|
export const orderCountDataMapper = { 'data1': 'ordercount1', data2: 'ordercount2' };
|
|
export const orderCountDataFieldMapper = { 'dateKey': 'ApplyDate', 'valueKey': 'orderCount', 'seriesKey': 'id', _f: 'sum' };
|
|
|
|
/**
|
|
* --------------------------------------------------------------------------------------------------------
|
|
*/
|
|
const initialState = {
|
|
loading: false,
|
|
typeLoading: false,
|
|
searchValues: {
|
|
DateType: { key: 'applyDate', label: '提交日期' },
|
|
WebCode: { key: 'all', label: '所有来源' },
|
|
IncludeTickets: { key: '1', label: '含门票' },
|
|
DepartmentList: groupsMappedByCode.GH, // { key: 'All', label: '所有来源' }, //
|
|
},
|
|
searchValuesToSub: {
|
|
DateType: 'applyDate',
|
|
WebCode: 'all',
|
|
IncludeTickets: '1',
|
|
DepartmentList: -1, // -1: All
|
|
},
|
|
|
|
activeTab: 'customer_types',
|
|
activeDateGroupRadio: 'day',
|
|
|
|
orderCountDataRaw: {},
|
|
orderCountDataLines: [],
|
|
avgLineValue: 0,
|
|
|
|
orderCountDataByType: {},
|
|
|
|
// 二级页面
|
|
orderCountDataRawSub: {},
|
|
orderCountDataLinesSub: [],
|
|
avgLineValueSub: 0,
|
|
activeDateGroupRadioSub: 'day',
|
|
orderDetails: [],
|
|
};
|
|
|
|
const useToBOrderStore = create(
|
|
devtools(
|
|
immer((set, get) => ({
|
|
...initialState,
|
|
reset: () => set(initialState),
|
|
|
|
setLoading: (loading) => set({ loading }),
|
|
setTypeLoading: (typeLoading) => set({ typeLoading }),
|
|
|
|
setSearchValues: (obj, values) => set((state) => ({ searchValues: values, searchValuesToSub: obj })),
|
|
setSearchValuesToSub: (values) => set((state) => ({ searchValuesToSub: values })),
|
|
setActiveTab: (tab) => set({ activeTab: tab }),
|
|
|
|
setOrderCountDataLines: (data) => set({ orderCountDataLines: data }),
|
|
setOrderCountDataByType: (type, data) =>
|
|
set((state) => {
|
|
state.orderCountDataByType[type] = data;
|
|
}),
|
|
|
|
// data ----
|
|
onChangeDateGroup: (value, data, avg1) => {
|
|
const { lines, dateRadioValue, avgLineValue } = calculateLineData(value, data, avg1);
|
|
set({ orderCountDataLines: lines, avgLineValue, activeDateGroupRadio: dateRadioValue });
|
|
},
|
|
onChangeDateGroupSub: (value, data, avg1) => {
|
|
const { lines, dateRadioValue, avgLineValue } = calculateLineData(value, data, avg1);
|
|
set({ orderCountDataLinesSub: lines, avgLineValueSub: avgLineValue, activeDateGroupRadioSub: dateRadioValue });
|
|
},
|
|
|
|
// site effects
|
|
getToBOrderCount: async (params, type, typeVal) => {
|
|
const { setLoading } = get();
|
|
setLoading(true);
|
|
try {
|
|
const res = await fetchToBOrderCount(params, type, typeVal);
|
|
// 第一次得到数据
|
|
const { lines, dateRadioValue, avgLineValue } = resultDataCb(res, 'day', orderCountDataMapper, orderCountDataFieldMapper, calculateLineData);
|
|
if (isEmpty(type)) {
|
|
// index page
|
|
set({ orderCountDataRaw: res });
|
|
set({ orderCountDataLines: lines, avgLineValue, activeDateGroupRadio: dateRadioValue });
|
|
} else {
|
|
// sub page
|
|
set({ orderCountDataRawSub: res });
|
|
set({ orderCountDataLinesSub: lines, avgLineValueSub: avgLineValue, activeDateGroupRadioSub: dateRadioValue });
|
|
}
|
|
} catch (error) {
|
|
console.error(error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
},
|
|
|
|
getToBOrderCount_type: async (type) => {
|
|
const { setTypeLoading, searchValuesToSub, setOrderCountDataByType } = get();
|
|
setTypeLoading(true);
|
|
try {
|
|
const res = await fetchToBOrderCountByType(type, searchValuesToSub);
|
|
setOrderCountDataByType(type, res);
|
|
} catch (error) {
|
|
console.error(error);
|
|
} finally {
|
|
setTypeLoading(false);
|
|
}
|
|
},
|
|
|
|
onTabChange: async (tab) => {
|
|
const { setActiveTab, getToBOrderCount_type } = get();
|
|
setActiveTab(tab);
|
|
await getToBOrderCount_type(tab);
|
|
},
|
|
|
|
// sub
|
|
getToBOrderDetailByType: async (params, type, typeVal) => {
|
|
const { setTypeLoading } = get();
|
|
try {
|
|
setTypeLoading(true);
|
|
const res = await fetchToBOrderDetailByType(params, type, typeVal, 'detail');
|
|
set({ orderDetails: res });
|
|
} catch (error) {
|
|
console.error(error);
|
|
} finally {
|
|
setTypeLoading(false);
|
|
}
|
|
},
|
|
})),
|
|
{ name: 'ToBOrder' }
|
|
)
|
|
);
|
|
export default useToBOrderStore;
|