diff --git a/package-lock.json b/package-lock.json
index 99e66d5..ab23224 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,7 @@
"@ant-design/pro-components": "^2.6.16",
"antd": "^4.22.6",
"dingtalk-jsapi": "^3.0.9",
+ "immer": "^10.2.0",
"insert-css": "^2.0.0",
"mobx": "^6.6.1",
"mobx-react": "^7.5.2",
@@ -20,7 +21,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",
@@ -1521,6 +1523,16 @@
"react-dom": "^16.8.0 || ^17.0.0"
}
},
+ "node_modules/@antv/xflow-core/node_modules/immer": {
+ "version": "9.0.21",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
+ "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/immer"
+ }
+ },
"node_modules/@antv/xflow-extension": {
"version": "1.0.51",
"resolved": "https://registry.npmmirror.com/@antv/xflow-extension/-/xflow-extension-1.0.51.tgz",
@@ -5477,7 +5489,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 +5510,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 +5548,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",
@@ -11457,9 +11469,14 @@
}
},
"node_modules/immer": {
- "version": "9.0.15",
- "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.15.tgz",
- "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ=="
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz",
+ "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/immer"
+ }
},
"node_modules/import-fresh": {
"version": "3.3.0",
@@ -17826,6 +17843,16 @@
"node": ">=8"
}
},
+ "node_modules/react-dev-utils/node_modules/immer": {
+ "version": "9.0.21",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
+ "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/immer"
+ }
+ },
"node_modules/react-dev-utils/node_modules/loader-utils": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz",
@@ -21314,6 +21341,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": {
@@ -22652,6 +22708,13 @@
"mana-syringe": "^0.2.2",
"reflect-metadata": "^0.1.13",
"rxjs": "^6.6.7"
+ },
+ "dependencies": {
+ "immer": {
+ "version": "9.0.21",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
+ "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA=="
+ }
}
},
"@antv/xflow-extension": {
@@ -25409,7 +25472,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 +25493,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 +25531,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",
@@ -29901,9 +29964,9 @@
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ=="
},
"immer": {
- "version": "9.0.15",
- "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.15.tgz",
- "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ=="
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz",
+ "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw=="
},
"import-fresh": {
"version": "3.3.0",
@@ -34399,6 +34462,11 @@
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
+ "immer": {
+ "version": "9.0.21",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
+ "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA=="
+ },
"loader-utils": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz",
@@ -37049,6 +37117,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..82c8302 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
"@ant-design/pro-components": "^2.6.16",
"antd": "^4.22.6",
"dingtalk-jsapi": "^3.0.9",
+ "immer": "^10.2.0",
"insert-css": "^2.0.0",
"mobx": "^6.6.1",
"mobx-react": "^7.5.2",
@@ -15,7 +16,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..fd78c86 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,28 +1,26 @@
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,
+ RocketOutlined
} 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 BizOrderSub from './views/biz/BizOrderSub';
import ProtectedRoute from './views/ProtectedRoute';
import Customer_care_inchina from './charts/Customer_care_inchina';
import Customer_care_potential from './charts/Customer_care_potential';
@@ -58,6 +56,7 @@ import OPRisk from './views/sales-crm/Risk';
import Cruise from './views/Cruise';
import Hotel from './views/Hotel';
import HostCaseCount from './views/HostCaseCount';
+import TrainsUpsell from './views/biz/reports/TrainsUpsell';
const App = () => {
const { Content, Footer, Sider, } = Layout;
@@ -81,7 +80,7 @@ const App = () => {
key: 'meeting-2024-GH',
label: GH区域数据, // GH例会数据-2024
},
- ]
+ ],
},
{
key: 2,
@@ -104,6 +103,13 @@ const App = () => {
},
],
},
+ {
+ key: 20, label: '商务市场', icon: ,
+ children: [
+ { key: 201, label: 订单数据 },
+ { key: 202, label: TrainsUpsell },
+ ]
+ },
{
key: 5,
label: '销售',
@@ -118,7 +124,7 @@ const App = () => {
{
key: 3,
label: '客运',
- icon: ,
+ icon: ,
children: [
{
key: 31,
@@ -151,7 +157,7 @@ const App = () => {
{
key: 6,
label: '客服',
- icon: ,
+ icon: ,
children: [
{
key: 61,
@@ -253,6 +259,9 @@ const App = () => {
} />
} />
} />
+ } />
+ } />
+ } />
}>
} />
diff --git a/src/components/DateGroupRadio/date.js b/src/components/DateGroupRadio/date.js
index 9bd9d15..be91eab 100644
--- a/src/components/DateGroupRadio/date.js
+++ b/src/components/DateGroupRadio/date.js
@@ -161,5 +161,5 @@ export const resultDataCb = (dataRaw, dateGroup, { data1, data2 }, fieldMapper,
// '\ndata1KeyMappedStr', data1KeyMappedStr,
// '\ndata2KeyMappedStr', data2KeyMappedStr
// );
- cb(dateGroup, retData, avg1, parse2.avgVal);
+ return cb(dateGroup, retData, avg1, parse2.avgVal);
};
diff --git a/src/components/search/SearchForm.jsx b/src/components/search/SearchForm.jsx
index b6ee01a..3f94fcc 100644
--- a/src/components/search/SearchForm.jsx
+++ b/src/components/search/SearchForm.jsx
@@ -92,6 +92,11 @@ export default observer((props) => {
transform: (value) => value?.key || '',
default: '',
},
+ 'IncludeInternal': {
+ key: 'IncludeInternal',
+ transform: (value) => value?.key || '',
+ default: '',
+ },
'operator': {
key: 'operator',
// transform: (value) => value?.key || '',
@@ -379,6 +384,21 @@ function getFields(props) {
,
3
),
+ item(
+ 'IncludeInternal',
+ 99,
+
+
+ ,
+ 3
+ ),
item(
'countryArea',
99,
diff --git a/src/libs/ht.js b/src/libs/ht.js
index bca157c..d584d37 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: [] },
@@ -61,6 +61,11 @@ export const groupsMappedByCode = groups.reduce((a, c) => ({ ...a, [String(c.cod
export const groupsMappedByKey = groups.reduce((a, c) => ({ ...a, [String(c.key)]: c }), {});
export const leafGroup = groups.slice(3);
export const overviewGroup = groups.slice(0, 3); // todo: 花梨鹰 APP Trippest
+export const groupsCTplus = [
+ // { value: '10,18', key: '10,18', label: 'CT商旅', code: 'CT+', children: [10, 18,] };
+ { value: '18', key: '18', label: 'CT', code: 'CT', children: [] },
+ { value: '10', key: '10', label: '商旅', code: '', children: [] },
+];
/**
* 来源
*/
diff --git a/src/views/Orders.jsx b/src/views/Orders.jsx
index 39c799e..703a470 100644
--- a/src/views/Orders.jsx
+++ b/src/views/Orders.jsx
@@ -327,8 +327,8 @@ class Orders extends Component {
colorField: "OrderType",
radius: 0.8,
label: {
- type: "outer",
- content: "{name} {value} \n {percentage}",
+ type: "spider",
+ content: "{name} {value} \t {percentage}",
},
legend: false, // 不显示图例
interactions: [
diff --git a/src/views/biz/BizOrder.jsx b/src/views/biz/BizOrder.jsx
new file mode 100644
index 0000000..f3b7078
--- /dev/null
+++ b/src/views/biz/BizOrder.jsx
@@ -0,0 +1,442 @@
+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 { Line, Pie } 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 { toJS } from 'mobx';
+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 lineConfig = {
+ 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 pieConfig = {
+ appendPadding: 10,
+ data: [],
+ angleField: 'OrderCount',
+ colorField: 'OrderType',
+ radius: 0.8,
+ label: {
+ type: 'outer',
+ content: '{name} {value} \n {percentage}',
+ },
+ legend: false, // 不显示图例
+ interactions: [
+ {
+ type: 'element-selected',
+ },
+ {
+ type: 'element-active',
+ },
+ ],
+ };
+
+ const tableProps = {
+ dataSource: result?.ordercount1 || [], // table_data.dataSource,
+ columns: [
+ {
+ title: '#',
+ fixed: 'left',
+ children: [
+ {
+ title: (
+
+ {result.ordercountTotal1?.groups}
+ {showDiff ? {result.ordercountTotal2?.groups}
: null}
+
+ ),
+ titleX: `${result.ordercountTotal1?.groups}` + (showDiff ? ` vs ${result.ordercountTotal2?.groups}` : ''),
+ 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: 'servicetype',
+ label: (
+
+
+ 服务类型
+
+ ),
+ },
+ {
+ 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: (
+ <>
+
+
+
+
+ >
+ ),
+ };
+ })}
+ />
+
+
+
+
+
各项占比
+ {/* setIsShowEmpty(e.target.checked)}
+ >
+ 包含空值
+ */}
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+});
+export default BizOrder;
diff --git a/src/views/biz/BizOrderSub.jsx b/src/views/biz/BizOrderSub.jsx
new file mode 100644
index 0000000..40df6ea
--- /dev/null
+++ b/src/views/biz/BizOrderSub.jsx
@@ -0,0 +1,280 @@
+import { useContext, useEffect } from 'react';
+import { Row, Col, Tabs, Table, Divider, Spin, Space } from 'antd';
+import { ContainerOutlined, BlockOutlined, SmileOutlined, MobileOutlined } from '@ant-design/icons';
+import { Line } from '@ant-design/charts';
+import { NavLink, useParams } 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 addLineBreaksAtCommas = (text) => {
+ if (!text) return '';
+ return text.replace(/&/g, '&').replace(/,/g, ',\n').replace(/,/g, ',\n').replace(/;/g, ';\n').replace(/;/g, ';\n');
+};
+
+const OrderDetailTable = ({ caption, dataSource, loading, ...props }) => {
+ const columns = [
+ {
+ title: '订单号',
+ dataIndex: 'COLI_ID',
+ key: 'COLI_ID',
+ },
+ {
+ title: '网站',
+ dataIndex: 'COLI_WebCode',
+ key: 'COLI_WebCode',
+ },
+ {
+ title: '成行',
+ dataIndex: 'COLI_Success',
+ key: 'COLI_Success',
+ render: (text, record) => {text == 1 ? '是' : '否'},
+ sorter: (a, b) => b.COLI_Success - a.COLI_Success,
+ },
+ // {
+ // title: "人数(成/童/婴)",
+ // dataIndex: "COLI_PersonNum",
+ // key: "COLI_PersonNum",
+ // render: (text, record) => (
+ //
+ // {record.COLI_PersonNum}/{record.COLI_ChildNum}/{record.COLI_BabyNum}
+ //
+ // ),
+ // },
+ {
+ title: '预计利润',
+ dataIndex: 'CGI_YJLY',
+ key: 'CGI_YJLY',
+ },
+ {
+ title: '预定时间',
+ dataIndex: 'COLI_ApplyDate',
+ key: 'COLI_ApplyDate',
+ },
+ {
+ title: '出发日期',
+ dataIndex: 'CGI_ArriveDate',
+ key: 'CGI_ArriveDate',
+ },
+ // {
+ // title: '客人需求',
+ // dataIndex: 'COLI_CustomerRequest',
+ // key: 'COLI_CustomerRequest',
+ // ellipsis: true,
+ // },
+ {
+ title: '订单内容',
+ dataIndex: 'COLI_OrderDetailText',
+ key: 'COLI_OrderDetailText',
+ ellipsis: true,
+ },
+ Table.EXPAND_COLUMN,
+ ];
+ return (
+