From b0db30fd2d415a9694c2370370607bf36b588511 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 12 Nov 2025 17:17:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=95=86=E6=97=85:=20=E5=B8=82?= =?UTF-8?q?=E5=9C=BA-=E8=AE=A2=E5=8D=95=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 50 ++++- package.json | 3 +- src/App.jsx | 32 +-- src/libs/ht.js | 2 +- src/views/biz/BizOrder.jsx | 412 +++++++++++++++++++++++++++++++++++++ src/zustand/BizOrder.js | 170 +++++++++++++++ 6 files changed, 646 insertions(+), 23 deletions(-) create mode 100644 src/views/biz/BizOrder.jsx create mode 100644 src/zustand/BizOrder.js diff --git a/package-lock.json b/package-lock.json index 99e66d5..0e4daec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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": {} } } } diff --git a/package.json b/package.json index 2e46f5a..36097d2 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/App.jsx b/src/App.jsx index d6c2687..31721b2 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -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: GH区域数据, // GH例会数据-2024 }, - ] + ], }, { key: 2, @@ -104,6 +100,12 @@ const App = () => { }, ], }, + { + key: 20, label: '商旅市场', icon: , + children: [ + { key: 201, label: 订单数据 }, + ] + }, { key: 5, label: '销售', @@ -118,7 +120,7 @@ const App = () => { { key: 3, label: '客运', - icon: , + icon: , children: [ { key: 31, @@ -151,7 +153,7 @@ const App = () => { { key: 6, label: '客服', - icon: , + icon: , children: [ { key: 61, @@ -253,6 +255,8 @@ const App = () => { } /> } /> } /> + } /> + ToDo} /> }> } /> diff --git a/src/libs/ht.js b/src/libs/ht.js index bca157c..a31a071 100644 --- a/src/libs/ht.js +++ b/src/libs/ht.js @@ -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: [] }, diff --git a/src/views/biz/BizOrder.jsx b/src/views/biz/BizOrder.jsx new file mode 100644 index 0000000..263f2e7 --- /dev/null +++ b/src/views/biz/BizOrder.jsx @@ -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: ( + +
+ {result.ordercountTotal1?.groups} +
+ {showDiff ? ( +
+ {result.ordercountTotal2?.groups} +
+ ) : null} +
+ ), + 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) => {text}, + }, + ], + }, + { + 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 ( + <> +
+ + + { + setSearchValues(obj, form); + getBizOrderCount(obj); + onTabChange(activeTab); + }} + /> + + + + + + + + + + + + + + onTabChange(active_key)} + items={[ + { + key: 'Form', + label: ( + + + 来源类型 + + ), + }, + // { + // key: 'Product', + // label: ( + // + // + // 产品类型 + // + // ), + // }, + { + key: 'Country', + label: ( + + + 国籍 + + ), + }, + // { + // key: 'line', + // label: ( + // + // + // 线路 + // + // ), + // }, + // { + // key: 'city', + // label: ( + // + // + // 目的地 + // + // ), + // }, + { + key: 'LineClass', + label: ( + + + 页面类型 + + ), + }, + { + key: 'ordersource', + label: ( + + + 来源设备 + + ), + }, + // { + // key: 'GuestGroupType', + // label: ( + // + // + // 客群类别 + // + // ), + // }, + // { + // key: 'TravelMotivation', + // label: ( + // + // + // 出行动机 + // + // ), + // }, + // { + // key: 'ToB', + // label: ( + // + // + // 客运类别 + // + // ), + // }, + // { + // key: 'FoodRequirement', + // label: ( + // + // + // 饮食要求 + // + // ), + // }, + // { + // key: 'hobbies', + // label: ( + // + // + // 兴趣爱好 + // + // ), + // }, + // { + // key: 'ages', + // label: ( + // + // + // 年龄段 + // + // ), + // }, + ].map((ele) => { + return { + ...ele, + children: ( + <> + + + + + + ), + }; + })} + /> + + + {/* */} + + + {/* */} + + + + + + + ); +}); +export default BizOrder; diff --git a/src/zustand/BizOrder.js b/src/zustand/BizOrder.js new file mode 100644 index 0000000..4f8ed6f --- /dev/null +++ b/src/zustand/BizOrder.js @@ -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;