feat: 商旅: 市场-订单数据

main
Lei OT 5 months ago
parent fab4f74653
commit b0db30fd2d

50
package-lock.json generated

@ -20,7 +20,8 @@
"react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1",
"web-vitals": "^2.1.4",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.18.11/xlsx-0.18.11.tgz"
"xlsx": "https://cdn.sheetjs.com/xlsx-0.18.11/xlsx-0.18.11.tgz",
"zustand": "^5.0.8"
},
"devDependencies": {
"@types/react": "^18.2.20",
@ -5477,7 +5478,7 @@
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true
"devOptional": true
},
"node_modules/@types/q": {
"version": "1.5.5",
@ -5498,7 +5499,7 @@
"version": "18.2.20",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz",
"integrity": "sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==",
"dev": true,
"devOptional": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@ -5536,7 +5537,7 @@
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
"dev": true
"devOptional": true
},
"node_modules/@types/semver": {
"version": "7.3.13",
@ -21314,6 +21315,35 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zustand": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz",
"integrity": "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==",
"license": "MIT",
"engines": {
"node": ">=12.20.0"
},
"peerDependencies": {
"@types/react": ">=18.0.0",
"immer": ">=9.0.6",
"react": ">=18.0.0",
"use-sync-external-store": ">=1.2.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"immer": {
"optional": true
},
"react": {
"optional": true
},
"use-sync-external-store": {
"optional": true
}
}
}
},
"dependencies": {
@ -25409,7 +25439,7 @@
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true
"devOptional": true
},
"@types/q": {
"version": "1.5.5",
@ -25430,7 +25460,7 @@
"version": "18.2.20",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz",
"integrity": "sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==",
"dev": true,
"devOptional": true,
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@ -25468,7 +25498,7 @@
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
"dev": true
"devOptional": true
},
"@types/semver": {
"version": "7.3.13",
@ -37049,6 +37079,12 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
},
"zustand": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz",
"integrity": "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==",
"requires": {}
}
}
}

@ -15,7 +15,8 @@
"react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1",
"web-vitals": "^2.1.4",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.18.11/xlsx-0.18.11.tgz"
"xlsx": "https://cdn.sheetjs.com/xlsx-0.18.11/xlsx-0.18.11.tgz",
"zustand": "^5.0.8"
},
"scripts": {
"start": "react-scripts start",

@ -1,28 +1,24 @@
import './App.css';
import React, { useContext, useState } from 'react';
import Icon, {
HomeOutlined,
TeamOutlined,
import { useContext, useState } from 'react';
import {
DashboardOutlined,
FileProtectOutlined,
CustomerServiceTwoTone,
SnippetsTwoTone,
DollarOutlined,
AreaChartOutlined,
WechatOutlined,
UserOutlined,
FlagOutlined,
PieChartOutlined,
BarChartOutlined,
CoffeeOutlined, DesktopOutlined,
WhatsAppOutlined
WhatsAppOutlined,
ShoppingCartOutlined,
GiftOutlined
} from '@ant-design/icons';
import { Layout, Menu, Image, Badge, Button } from 'antd';
import { Layout, Menu, Button } from 'antd';
import { BrowserRouter, Route, Routes, NavLink } from 'react-router-dom';
import Home from './views/Home';
import Dashboard from './views/Dashboard';
import Orders from './views/Orders';
import Orders_sub from './views/Orders_sub';
import BizOrder from './views/biz/BizOrder';
import ProtectedRoute from './views/ProtectedRoute';
import Customer_care_inchina from './charts/Customer_care_inchina';
import Customer_care_potential from './charts/Customer_care_potential';
@ -81,7 +77,7 @@ const App = () => {
key: 'meeting-2024-GH',
label: <NavLink to="/orders/meeting-2024-GH">GH区域数据</NavLink>, // GH-2024
},
]
],
},
{
key: 2,
@ -104,6 +100,12 @@ const App = () => {
},
],
},
{
key: 20, label: '商旅市场', icon: <ShoppingCartOutlined />,
children: [
{ key: 201, label: <NavLink to="/biz_orders">订单数据</NavLink> },
]
},
{
key: 5,
label: '销售',
@ -118,7 +120,7 @@ const App = () => {
{
key: 3,
label: '客运',
icon: <WechatOutlined />,
icon: <GiftOutlined />,
children: [
{
key: 31,
@ -151,7 +153,7 @@ const App = () => {
{
key: 6,
label: '客服',
icon: <CooperationIcon/>,
icon: <CooperationIcon />,
children: [
{
key: 61,
@ -253,6 +255,8 @@ const App = () => {
<Route path="/:page/pivot" element={<DataPivot />} />
<Route path="/orders/meeting-2024-GH" element={<Meeting2024GH />} />
<Route path="/orders/meeting-2025-GH" element={<Meeting2025GH />} />
<Route path="/biz_orders" element={<BizOrder />} />
<Route path="/biz_orders_sub/:ordertype/:ordertype_sub/:ordertype_title" element={<h1>ToDo</h1>} />
</Route>
<Route element={<ProtectedRoute auth={['admin', 'director_bu', 'customer_care']} />}>
<Route path="/customer_care_inchina" element={<Customer_care_inchina />} />

@ -39,7 +39,7 @@ export const deptUnits = [
export const groups = [
{ value: '1,2,28,7,33', key: '1,2,28,7,33', label: 'GH事业部', code: 'GH', children: [1, 2, 28, 7, 33] },
{ value: '8,9,11,12,20,21', key: '8,9,11,12,20,21', label: '国际事业部', code: 'INT', children: [8, 9, 11, 12, 20, 21] },
{ value: '10,18,16,30', key: '10,18,16,30', label: '孵化学院', code: '', children: [10, 18, 16, 30] },
{ value: '10,18,16,30', key: '10,18,16,30', label: '孵化学院', code: 'CTX', children: [10, 18, 16, 30] },
{ value: '1', key: '1', label: 'CH直销', code: '', children: [] },
{ value: '2', key: '2', label: 'CH大客户', code: '', children: [] },
{ value: '28', key: '28', label: 'HT项目组(前AH)', code: 'HT', children: [] },

@ -0,0 +1,412 @@
import { useContext } from 'react';
import { Row, Col, Tabs, Table, Divider, Spin } from 'antd';
import {
ContainerOutlined,
BlockOutlined,
SmileOutlined,
MobileOutlined,
} from '@ant-design/icons';
import { Line } from '@ant-design/charts';
import { NavLink } from 'react-router-dom';
import * as comm from '../../utils/commons';
import DateGroupRadio from '../../components/DateGroupRadio';
import SearchForm from '../../components/search/SearchForm';
import { TableExportBtn } from '../../components/Data';
import { observer } from 'mobx-react';
import { stores_Context } from '../../config';
import { useShallow } from 'zustand/shallow';
import useBizOrderStore, { orderCountDataMapper, orderCountDataFieldMapper } from '../../zustand/BizOrder';
const BizOrder = observer(() => {
const { date_picker_store: searchFormStore } = useContext(stores_Context);
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 orderCountDataRaw = useBizOrderStore((state) => state.orderCountDataRaw);
const [orderCountDataLines, avgLineValue ] = useBizOrderStore(useShallow((state) => [state.orderCountDataLines, state.avgLineValue]));
const [onChangeDateGroup, activeDateGroupRadio ] = useBizOrderStore(useShallow((state) => [state.onChangeDateGroup, state.activeDateGroupRadio]));
const orderCountDataByType = useBizOrderStore((state) => state.orderCountDataByType);
const result = orderCountDataByType[activeTab] || {};
const getBizOrderCount = useBizOrderStore((state) => state.getBizOrderCount);
const showDiff = !comm.isEmpty(searchFormStore.start_date_cp);
const avg_line_y = Math.round(avgLineValue);
const config = {
data: orderCountDataLines,
padding: "auto",
xField: "xField",
yField: "yField",
seriesField: "seriesField",
// xAxis: {
// type: "timeCat",
// },
point: {
size: 4,
shape: "cicle",
},
annotations: [
{
type: "text",
position: ["start", avg_line_y],
content: avg_line_y,
offsetX: -15,
style: {
fill: "#F4664A",
textBaseline: "bottom",
},
},
{
type: "line",
start: [-10, avg_line_y],
end: ["max", avg_line_y],
style: {
stroke: "#F4664A",
lineDash: [2, 2],
},
},
],
label: {}, //
legend: {
itemValue: {
formatter: (text, item) => {
const items = orderCountDataLines.filter(d => d.seriesField === item.value); //
return items.length ? items.reduce((a, b) => a + b.yField, 0) : ""; //
},
},
},
tooltip: {
customItems: (originalItems) => {
// process originalItems,
return originalItems.map(ele => ({...ele, name: ele.data?.seriesField || ele.data?.xField}));
},
title: (title, datum) => {
let ret = title;
switch (activeDateGroupRadio) {
case 'day':
ret = `${title} ${comm.getWeek(datum.xField)}`; //
break;
default:
break;
}
return ret;
},
},
// smooth: true,
};
const tableProps = {
dataSource: result?.ordercount1 || [], // table_data.dataSource,
columns: [
{
title: '#',
fixed: 'left',
children: [
{
title: (
<span>
<div>
{result.ordercountTotal1?.groups}
</div>
{showDiff ? (
<div>
{result.ordercountTotal2?.groups}
</div>
) : null}
</span>
),
titleX:
`${searchFormStore.start_date.format(config.DATE_FORMAT)}~${searchFormStore.end_date.format(config.DATE_FORMAT)}` +
(showDiff ? ` vs ${searchFormStore.start_date_cp.format(config.DATE_FORMAT)}~${searchFormStore.end_date_cp.format(config.DATE_FORMAT)}` : ''),
dataIndex: 'OrderType',
fixed: 'left',
render: (text, record) => <NavLink to={`/biz_orders_sub/${activeTab}/${record.OrderTypeSN}/${encodeURIComponent(record.OrderType)}`}>{text}</NavLink>,
},
],
},
{
title: '数量',
children: [
{
title: !showDiff
? result.ordercountTotal1?.OrderCount
: comm.show_vs_tag(result.ordercountTotal1?.OrderCount_vs, result.ordercountTotal1?.OrderCount_diff, result.ordercountTotal1?.OrderCount, result.ordercountTotal2?.OrderCount),
titleX: [result.ordercountTotal1?.OrderCount, result.ordercountTotal2?.OrderCount].join(' vs '),
dataIndex: 'OrderCount',
render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.OrderCount_vs, r.OrderCount_diff, r.OrderCount, r.diff?.OrderCount)),
},
],
},
{
title: '成交数',
children: [
{
title: !showDiff
? result.ordercountTotal1?.CJCount
: comm.show_vs_tag(result.ordercountTotal1?.CJCount_vs, result.ordercountTotal1?.CJCount_diff, result.ordercountTotal1?.CJCount, result.ordercountTotal2?.CJCount),
titleX: [result.ordercountTotal1?.CJCount, result.ordercountTotal2?.CJCount].join(' vs '),
dataIndex: 'CJCount',
render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.CJCount_vs, r.CJCount_diff, r.CJCount, r.diff?.CJCount)),
},
],
},
{
title: '成交人数',
children: [
{
title: !showDiff
? result.ordercountTotal1?.CJPersonNum
: comm.show_vs_tag(result.ordercountTotal1?.CJPersonNum_vs, result.ordercountTotal1?.CJPersonNum_diff, result.ordercountTotal1?.CJPersonNum, result.ordercountTotal2?.CJPersonNum),
titleX: [result.ordercountTotal1?.CJPersonNum, result.ordercountTotal2?.CJPersonNum].join(' vs '),
dataIndex: 'CJPersonNum',
render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.CJPersonNum_vs, r.CJPersonNum_diff, r.CJPersonNum, r.diff?.CJPersonNum)),
},
],
},
{
title: '成交率',
children: [
{
title: !showDiff
? result.ordercountTotal1?.CJrate
: comm.show_vs_tag(result.ordercountTotal1?.CJrate_vs, result.ordercountTotal1?.CJrate_diff, result.ordercountTotal1?.CJrate, result.ordercountTotal2?.CJrate),
titleX: [result.ordercountTotal1?.CJrate, result.ordercountTotal2?.CJrate].join(' vs '),
dataIndex: 'CJrate',
render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.CJrate_vs, r.CJrate_diff, r.CJrate, r.diff?.CJrate)),
},
],
},
{
title: '成交毛利(预计)',
children: [
{
title: !showDiff
? result.ordercountTotal1?.YJLY
: comm.show_vs_tag(result.ordercountTotal1?.YJLY_vs, result.ordercountTotal1?.YJLY_diff, result.ordercountTotal1?.YJLY, result.ordercountTotal2?.YJLY),
titleX: [result.ordercountTotal1?.YJLY, result.ordercountTotal2?.YJLY].join(' vs '),
dataIndex: 'YJLY',
render: (text, r) => (!showDiff ? text : comm.show_vs_tag(r.YJLY_vs, r.YJLY_diff, r.YJLY, r.diff?.YJLY)),
},
],
},
{
title: '单个订单价值',
children: [
{
title: !showDiff
? result.ordercountTotal1?.Ordervalue
: comm.show_vs_tag(result.ordercountTotal1?.Ordervalue_vs, result.ordercountTotal1?.Ordervalue_diff, result.ordercountTotal1?.Ordervalue, result.ordercountTotal2?.Ordervalue),
titleX: [result.ordercountTotal1?.Ordervalue, result.ordercountTotal2?.Ordervalue].join(' vs '),
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>
<Row gutter={16} className={searchFormStore.siderBroken ? '' : 'sticky-top'}>
<Col className="gutter-row" span={24}>
<SearchForm
defaultValue={{
initialValue: {
...searchFormStore.formValues,
...searchValues,
},
shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'dates'],
fieldProps: {
DepartmentList: { show_all: false, mode: 'multiple' },
WebCode: { show_all: false, mode: 'multiple' },
years: { hide_vs: true },
},
}}
onSubmit={(_err, obj, form, str) => {
setSearchValues(obj, form);
getBizOrderCount(obj);
onTabChange(activeTab);
}}
/>
</Col>
</Row>
<Row gutter={[16, { sm: 16, lg: 32 }]}>
<Col span={24} style={{ textAlign: 'right' }}>
<DateGroupRadio
visible={orderCountDataLines.length !== 0}
dataRaw={orderCountDataRaw}
onChange={onChangeDateGroup}
value={activeDateGroupRadio}
dataMapper={orderCountDataMapper}
fieldMapper={orderCountDataFieldMapper}
/>
</Col>
<Col span={24}>
<Spin spinning={loading}>
<Line {...config} />
</Spin>
</Col>
<Col span={24}>
<Tabs
activeKey={activeTab}
onChange={(active_key) => onTabChange(active_key)}
items={[
{
key: 'Form',
label: (
<span>
<ContainerOutlined />
来源类型
</span>
),
},
// {
// key: 'Product',
// label: (
// <span>
// <CarryOutOutlined />
//
// </span>
// ),
// },
{
key: 'Country',
label: (
<span>
<SmileOutlined />
国籍
</span>
),
},
// {
// key: 'line',
// label: (
// <span>
// <TagsOutlined />
// 线
// </span>
// ),
// },
// {
// key: 'city',
// label: (
// <span>
// <GlobalOutlined />
//
// </span>
// ),
// },
{
key: 'LineClass',
label: (
<span>
<BlockOutlined />
页面类型
</span>
),
},
{
key: 'ordersource',
label: (
<span>
<MobileOutlined />
来源设备
</span>
),
},
// {
// key: 'GuestGroupType',
// label: (
// <span>
// <FullscreenOutlined />
//
// </span>
// ),
// },
// {
// key: 'TravelMotivation',
// label: (
// <span>
// <DingtalkOutlined />
//
// </span>
// ),
// },
// {
// key: 'ToB',
// label: (
// <span>
// <ContactsOutlined />
//
// </span>
// ),
// },
// {
// key: 'FoodRequirement',
// label: (
// <span>
// <CoffeeOutlined />
//
// </span>
// ),
// },
// {
// key: 'hobbies',
// label: (
// <span>
// <HeartOutlined />
//
// </span>
// ),
// },
// {
// key: 'ages',
// label: (
// <span>
// <IdcardOutlined />
//
// </span>
// ),
// },
].map((ele) => {
return {
...ele,
children: (
<>
<Table sticky key={`table_to_xlsx_${ele.key}`} {...tableProps} />
<Divider orientation="right" plain>
<TableExportBtn label={ele.key} {...{ columns: tableProps.columns, dataSource: tableProps.dataSource }} />
</Divider>
</>
),
};
})}
/>
<Row>
<Col sm={24} lg={12}>
{/* <Pie {...pie_config} data={pie_data} /> */}
</Col>
<Col sm={24} lg={12}>
{/* <Pie {...pie_config} data={pie_data2} /> */}
</Col>
</Row>
</Col>
</Row>
</div>
</>
);
});
export default BizOrder;

@ -0,0 +1,170 @@
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
import { groupsMappedByCode } from '../libs/ht';
import { fetchJSON } from '../utils/request';
import { HT_HOST } from '../config';
import { resultDataCb } from '../components/DateGroupRadio/date';
export const fetchBizOrderCount = async (params) => {
const { errcode, errmsg, ...result } = await fetchJSON(HT_HOST + '/service-web/QueryData/GetOrderCount_biz', {
...params,
COLI_ApplyDate1: params.Date1,
COLI_ApplyDate2: params.Date2,
COLI_ApplyDateOld1: params.DateDiff1 || '',
COLI_ApplyDateOld2: params.DateDiff2 || '',
});
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 fetchBizOrderCountByType = async (type, params) => {
const { errcode, errmsg, ...result } = await fetchJSON(HT_HOST + '/service-web/QueryData/GetOrderCountByType_biz', {
...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 }), {});
const rows2Map = res.ordercount2.reduce((a, row2) => ({ ...a, [row2.OrderTypeSN]: row2 }), {});
const mixRow1 = res.ordercount1.map((row1) => ({ ...row1, 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 };
};
/**
* --------------------------------------------------------------------------------------------------------
*/
const initialState = {
loading: false,
typeLoading: false,
searchValues: {
DateType: { key: 'applyDate', label: '提交日期' },
WebCode: { key: 'all', label: '所有来源' },
IncludeTickets: { key: '1', label: '含门票' },
DepartmentList: groupsMappedByCode.CTX, // { key: 'All', label: '所有来源' }, //
},
searchValuesToSub: {
DateType: 'applyDate',
WebCode: 'all',
IncludeTickets: '1',
DepartmentList: -1, // -1: All
},
activeTab: 'Form',
activeDateGroupRadio: 'day',
orderCountDataRaw: {},
orderCountDataLines: [],
avgLineValue: 0,
orderCountDataByType: {},
};
export const orderCountDataMapper = { 'data1': 'ordercount1', data2: 'ordercount2' };
export const orderCountDataFieldMapper = { 'dateKey': 'ApplyDate', 'valueKey': 'orderCount', 'seriesKey': 'WebCode', _f: 'sum' };
const useBizOrderStore = create(
devtools(
(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({ orderCountDataByType: { ...get().orderCountDataByType, [type]: data } }),
// data parser
onChangeDateGroup: (value, data, avg1) => {
const { setOrderCountDataLines } = get();
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 }));
setOrderCountDataLines(_data);
set({ activeDateGroupRadio: value, avgLineValue: avg1 });
},
parseOrderCount: (orderCountData, dateGroup) => {
const { onChangeDateGroup } = get();
resultDataCb(orderCountData, dateGroup, orderCountDataMapper, orderCountDataFieldMapper, onChangeDateGroup);
},
// site effects
getBizOrderCount: async (params) => {
const { setLoading, parseOrderCount } = get();
setLoading(true);
try {
const res = await fetchBizOrderCount(params);
set({ orderCountDataRaw: res });
// 第一次得到数据
parseOrderCount(res, 'day');
} catch (error) {
} finally {
setLoading(false);
}
},
getBizOrderCount_type: async (type) => {
const { setTypeLoading, searchValuesToSub, setOrderCountDataByType } = get();
setTypeLoading(true);
try {
const res = await fetchBizOrderCountByType(type, searchValuesToSub);
setOrderCountDataByType(type, res);
} catch (error) {
} finally {
setTypeLoading(false);
}
},
onTabChange: async (tab) => {
const { setActiveTab, getBizOrderCount_type } = get();
setActiveTab(tab);
await getBizOrderCount_type(tab);
},
}),
{ name: 'bizOrder' }
)
);
export default useBizOrderStore;
Loading…
Cancel
Save