diff --git a/src/App.jsx b/src/App.jsx
index 4a04b1c..9e22aee 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -14,7 +14,7 @@ import {
FlagOutlined,
PieChartOutlined,
BarChartOutlined,
- CoffeeOutlined,
+ CoffeeOutlined, DesktopOutlined
} from '@ant-design/icons';
import { Layout, Menu, Image, Badge, Button } from 'antd';
import { BrowserRouter, Route, Routes, NavLink } from 'react-router-dom';
@@ -46,6 +46,7 @@ import ServicePersonNum from './views/ServicePersonNum';
import DataPivot from './views/DataPivot';
import Welcome from './views/Welcome';
import Meeting2024GH from './views/Meeting2024-GH';
+import Meeting2025GH from './views/Meeting2025-GH';
import SalesCustomerCareRegular from './views/SalesCustomerCareRegular';
import { stores_Context, APP_VERSION } from './config';
import { WaterMark } from '@ant-design/pro-components';
@@ -58,7 +59,22 @@ const App = () => {
const menu_items = [
{ key: 1, label: 欢迎, icon: },
- { key: 'annual', label: 综合看板, icon: },
+ { key: 'annual', label: 综合年度, icon: },
+ {
+ key: 'mixed',
+ label: '报告',
+ icon: ,
+ children: [
+ {
+ key: 'meeting-2025-GH',
+ label: GH例会数据-2025, // GH例会数据-2024
+ },
+ {
+ key: 'meeting-2024-GH',
+ label: GH区域数据, // GH例会数据-2024
+ },
+ ]
+ },
{
key: 2,
label: '市场',
@@ -78,10 +94,6 @@ const App = () => {
key: 'orders-pivot',
label: 数据透视,
},
- {
- key: 'meeting-2024-GH',
- label: 例会数据2024-GH,
- },
],
},
{
@@ -218,6 +230,7 @@ const App = () => {
} />
} />
} />
+ } />
}>
} />
diff --git a/src/components/Data.jsx b/src/components/Data.jsx
index d067a63..7b433f0 100644
--- a/src/components/Data.jsx
+++ b/src/components/Data.jsx
@@ -81,7 +81,7 @@ export const TableExportBtn = (props) => {
};
return (
- }
size="small"
diff --git a/src/libs/ht.js b/src/libs/ht.js
index d591b05..e821323 100644
--- a/src/libs/ht.js
+++ b/src/libs/ht.js
@@ -67,6 +67,7 @@ export const sites = [
{ value: '2', key: '2', label: 'CHT', code: 'CHT' },
{ value: '8', key: '8', label: 'AH', code: 'AH' },
{ value: '163', key: '163', label: 'GH', code: 'GH' },
+ { value: '184', key: '184', label: '站外渠道', code: 'ZWQD' },
{ value: '28', key: '28', label: '客运中国', code: 'GHKYZG' },
{ value: '7', key: '7', label: '客运海外', code: 'GHKYHW' },
{ value: '172', key: '172', label: 'GHToB 海外', code: 'GHTOBHW' },
@@ -74,7 +75,6 @@ export const sites = [
{ value: '11,12,20,21,10,18', key: '11,12,20,21,10,18', label: '国际(入境)', code: 'JP,VAC,IT,GM,RU,VC' },
{ value: '122,200,211,100,188', key: '122,200,211,100,188', label: '国际(海外)', code: 'VACHW,ITHW,GMHW,RUHW,VCHW' },
{ value: '178,179,180,181,182,183', key: '178,179,180,181,182,183', label: '国际(GH)', code: 'gh_gm,gh_jp,gh_vc,gh_vac,gh_ru,gh_it'},
- { value: '184', key: '184', label: '站外渠道', code: 'ZWQD' },
{ value: '11', key: '11', label: '日语', code: 'JP' },
{ value: '179', key: '179', label: 'GH-日语', code: 'gh_jp'}, // www.globalhighlights.jp
{ value: '12', key: '12', label: '西语', code: 'VAC' },
diff --git a/src/stores/Index.js b/src/stores/Index.js
index d8161f6..0579adc 100644
--- a/src/stores/Index.js
+++ b/src/stores/Index.js
@@ -15,7 +15,8 @@ import KPI from "./KPI";
import DictData from "./DictData";
import Distribution from "./Distribution";
import DataPivot from './DataPivot';
-import MeetingData from './MeetingData';
+import MeetingData from './MeetingData2024';
+import MeetingData2025 from './MeetingData2025';
class Index {
constructor() {
this.dashboard_store = new DashboardStore(this);
@@ -35,6 +36,7 @@ class Index {
this.DistributionStore = new Distribution(this);
this.DataPivotStore = new DataPivot(this);
this.MeetingDataStore = new MeetingData(this);
+ this.MeetingData2025Store = new MeetingData2025(this);
makeAutoObservable(this);
}
diff --git a/src/stores/MeetingData.js b/src/stores/MeetingData2024.js
similarity index 98%
rename from src/stores/MeetingData.js
rename to src/stores/MeetingData2024.js
index eac0551..ce91927 100644
--- a/src/stores/MeetingData.js
+++ b/src/stores/MeetingData2024.js
@@ -1,7 +1,7 @@
import { makeAutoObservable, runInAction } from 'mobx';
import { fetchJSON } from '../utils/request';
import { objectMapper, pick, price_to_number, } from '../utils/commons';
-import { pivotBy } from './../libs/ht';
+import { pivotBy } from '../libs/ht';
import moment from "moment";
import { DATE_FORMAT, DATETIME_FORMAT, SMALL_DATETIME_FORMAT } from '../config';
diff --git a/src/stores/MeetingData2025.js b/src/stores/MeetingData2025.js
new file mode 100644
index 0000000..29640a5
--- /dev/null
+++ b/src/stores/MeetingData2025.js
@@ -0,0 +1,474 @@
+import { makeAutoObservable, runInAction } from 'mobx';
+import { fetchJSON } from '../utils/request';
+import { objectMapper, pick, price_to_number, } from '../utils/commons';
+import { pivotBy } from './../libs/ht';
+import moment from "moment";
+import { DATE_FORMAT, DATETIME_FORMAT, SMALL_DATETIME_FORMAT } from '../config';
+
+/**
+ * 用于透视的数据
+ */
+const getDetailData = async (param) => {
+ const json = await fetchJSON('/service-Analyse2/GetTradeApartDetail', param);
+ return json.errcode === 0 ? json.result : [];
+};
+/**
+ *
+ */
+const getOrderCountByType = async (param) => {
+ const paramBody = objectMapper(param, {
+ WebCode: 'WebCode',
+ OrderType: 'OrderType',
+ IncludeTickets: 'IncludeTickets',
+ DateType: 'DateType',
+ DepartmentList: 'DepartmentList', // { key: 'DepartmentList', transform: (v) => v.join(',') },
+ Date1: 'COLI_ApplyDate1',
+ Date2: 'COLI_ApplyDate2',
+ });
+ const url = '/service-web/QueryData/GetOrderCountByType';
+ const json = await fetchJSON(url, paramBody);
+ return json.errcode === 0 ? json : {};
+};
+const getAgentGroupInfoALL = async (param) => {
+ const paramBody = objectMapper(param, {
+ DateType: 'DateType',
+ DepartmentList: 'DepList', // { key: 'DepartmentList', transform: (v) => v.join(',') },
+ Date1: 'OldDate1',
+ Date2: 'OldDate2',
+ });
+ const url = '/service-web/QueryData/GetAgentGroupInfoALL';
+ const json = await fetchJSON(url, paramBody);
+ return json.errcode === 0 ? json : {};
+};
+const getDepartmentOrderMLByType = async (param) => {
+ const paramBody = objectMapper(param, {
+ DateType: 'DateType',
+ DepartmentList: 'DepartmentList', // { key: 'DepartmentList', transform: (v) => v.join(',') },
+ OrderType: 'OrderType', // 总览, 产品类型
+ });
+ const url = '/service-web/QueryData/GetDepartmentOrderMLByType';
+ const json = await fetchJSON(url, paramBody);
+ const { result1 } = json.errcode === 0 ? json : { result1: [] };
+ const total1 = ['COLI_CJCount', 'COLI_ML2',].reduce(
+ (r, col) => ({
+ ...r,
+ [col]: result1.reduce((rr, row) => rr + row[col], 0),
+ }),
+ {}
+ );
+ return { total1, result1 };
+};
+const GHproductTypeListSetting = {
+ ja: ['日本', '东亚跨国'],
+ se: ['东南亚跨国', '泰国', '越南', '印度尼西亚', '水灯节', '柬埔寨', '老挝'],
+ in: ['印度', '印度次大陆跨国', '尼泊尔', '不丹', '斯里兰卡'],
+};
+const GHCountryListSetting = {
+ ja: ['日本', ],
+ se: ['泰国', '越南', '印度尼西亚', '水灯节', '柬埔寨', '老挝', '新加坡', '马来西亚', '菲律宾'],
+ in: ['印度', '印度次大陆跨国', '尼泊尔', '不丹', '斯里兰卡'],
+};
+
+const rowItem = (filterData) => {
+ const { data: dataByLineClass, summaryMix: summaryByLineClass } = pivotBy(filterData, [['COLI_LineClass'], [], []]);
+ const LineClass_Origin = dataByLineClass.filter((ele) => ele.COLI_LineClass.toLocaleLowerCase().indexOf('网前自然订单') !== -1).reduce((r, c) => r + c.SumOrder, 0);
+ const LineClass_PPC = dataByLineClass.filter((ele) => ele.COLI_LineClass.toLocaleLowerCase().indexOf('ppc') !== -1).reduce((r, c) => r + c.SumOrder, 0);
+
+ const { data: dataByWebCode, summaryMix: summaryByWebCode } = pivotBy(filterData, [['WebCode'], [], []]);
+ const toB = dataByWebCode.filter((ele) => ele.WebCode.toLocaleLowerCase().indexOf('to b') !== -1).reduce((r, c) => r + c.SumOrder, 0);
+ const external = dataByWebCode.filter((ele) => ele.WebCode.toLocaleLowerCase().indexOf("站外渠道") !== -1).reduce((r, c) => r + c.SumOrder, 0);
+
+ const filterIsOldC = filterData.filter((ele) => ele.WebCode.toLocaleLowerCase().indexOf('to b') === -1);
+ const { data: dataByIsOld, summaryMix: summaryByIsOld } = pivotBy(filterIsOldC, [['IsOld', 'isCusCommend'], [], []]);
+ const isOld1 = dataByIsOld.filter((ele) => ele.rowLabel.indexOf('1') !== -1).reduce((r, c) => r + c.SumOrder, 0);
+
+ const total = LineClass_Origin + LineClass_PPC + toB + isOld1 + external;
+ return { LineClass_Origin, LineClass_PPC, toB, external, isOld1, total };
+};
+// 日本+: 日本+东亚跨国
+const dataJA = (rawData, yearData) => {
+ const productTypeList = GHproductTypeListSetting.ja;
+ const filterData = rawData.filter((ele) => productTypeList.some((item) => ele.productType.toLocaleLowerCase().indexOf(item) !== -1));
+ const filterDataYear = yearData.filter((ele) => productTypeList.some((item) => ele.OrderType.toLocaleLowerCase().indexOf(item) !== -1));
+ const rowYear = filterDataYear.reduce((r, c) => r + c.OrderCount, 0);
+ return { ...rowItem(filterData), rowYear };
+};
+
+// 东南亚+: 东南亚跨国+泰国+越南+印尼+水灯节线路
+const dataSE = (rawData, yearData) => {
+ const productTypeList = GHproductTypeListSetting.se;
+ const filterData = rawData.filter((ele) => productTypeList.some((item) => ele.productType.toLocaleLowerCase().indexOf(item) !== -1));
+ const filterDataYear = yearData.filter((ele) => productTypeList.some((item) => ele.OrderType.toLocaleLowerCase().indexOf(item) !== -1));
+ const rowYear = filterDataYear.reduce((r, c) => r + c.OrderCount, 0);
+ return { ...rowItem(filterData), rowYear };
+};
+
+// 印度+: 印度+次大陆跨国+尼泊尔+不丹+斯里兰卡
+const dataIN = (rawData, yearData) => {
+ const productTypeList = GHproductTypeListSetting.in;
+ const exceptProduct = ['印度尼西亚'];
+ const filterData = rawData
+ .filter((ele) => productTypeList.some((item) => ele.productType.toLocaleLowerCase().indexOf(item) !== -1))
+ .filter((ele) => exceptProduct.every((item) => ele.productType.toLocaleLowerCase().indexOf(item) === -1));
+ const filterDataYear = yearData
+ .filter((ele) => productTypeList.some((item) => ele.OrderType.toLocaleLowerCase().indexOf(item) !== -1))
+ .filter((ele) => exceptProduct.every((item) => ele.OrderType.toLocaleLowerCase().indexOf(item) === -1));
+ const rowYear = filterDataYear.reduce((r, c) => r + c.OrderCount, 0);
+ return { ...rowItem(filterData), rowYear };
+};
+
+// 其他GH
+const dataGHOther = (rawData, yearData) => {
+ const exceptProduct = Object.values(GHproductTypeListSetting).reduce((r, c) => r.concat(c), []);
+ const filterData = rawData.filter((ele) => exceptProduct.every((item) => ele.productType.toLocaleLowerCase().indexOf(item) === -1));
+ const filterDataYear = yearData.filter((ele) => exceptProduct.every((item) => ele.OrderType.toLocaleLowerCase().indexOf(item) === -1));
+ const rowYear = filterDataYear.reduce((r, c) => r + c.OrderCount, 0);
+ return { ...rowItem(filterData), rowYear };
+};
+
+const dataSales = (tKey, rawData, yearData, yearData2) => {
+ const targetList = GHCountryListSetting[tKey];
+ const tIndex = Object.keys(GHCountryListSetting).indexOf(tKey);
+ const exceptTargetList = Object.keys(GHCountryListSetting).reduce((r, c, i) => r.concat(i < tIndex ? GHCountryListSetting[c] : []), []);
+ // console.log(tIndex, tKey, 'exceptTargetList', exceptTargetList, 'targetList', targetList);
+
+ const filterRaw1 = rawData.filter((ele) => exceptTargetList.every((item) => !ele.destinationCountry_AsJOSN.includes(item)));
+ // console.log(tKey, 'filterRaw1', filterRaw1);
+ const filterDataC = filterRaw1.filter((ele) => targetList.some((item) => ele.destinationCountry_AsJOSN.includes(item)));
+ const filterDataT = tKey === 'se' ? filterRaw1.filter((ele) => ['泰国水灯节'].some((item) => ele.productType.toLocaleLowerCase().indexOf(item) !== -1)) : [];
+ const filterData = filterDataC.concat(filterDataT);
+ const CJCount = filterData.length; // filterData.reduce((r, c) => r + c.CJCount, 0);
+ const YJLY = filterData.reduce((r, c) => r + price_to_number(c.ML), 0);
+
+ const filterRaw2 = yearData.filter((ele) => exceptTargetList.every((item) => !ele.destinationCountry_AsJOSN.includes(item)));
+ const filterDataYearC = filterRaw2.filter((ele) => targetList.some((item) => ele.destinationCountry_AsJOSN.includes(item)));
+ const filterDataYearT = tKey === 'se' ? filterRaw2.filter((ele) => ['泰国水灯节'].some((item) => ele.productType.toLocaleLowerCase().indexOf(item) !== -1)) : [];
+ const filterDataYear = filterDataYearC.concat(filterDataYearT);
+ const rowYearData = { CJCount: filterDataYear.length, YJLY: filterDataYear.reduce((r, c) => r + price_to_number(c.ML), 0) };
+ // console.log(tKey, filterDataYear.map(ee => ee.destinationCountry_AsJOSN), filterDataYear.map(ee => ee.productType), filterDataYear);
+
+ const filterDataYearRaw2 = yearData2.filter((ele) => exceptTargetList.every((item) => !ele.destinationCountry_AsJOSN.includes(item)));
+ const filterDataYear2C = filterDataYearRaw2.filter((ele) => targetList.some((item) => ele.destinationCountry_AsJOSN.includes(item)));
+ const filterDataYear2T = tKey === 'se' ? filterDataYearRaw2.filter((ele) => ['泰国水灯节'].some((item) => ele.productType.toLocaleLowerCase().indexOf(item) !== -1)) : [];
+ const filterDataYear2 = filterDataYear2C.concat(filterDataYear2T);
+ const rowYearData2 = { CJCount: filterDataYear2.length, YJLY: filterDataYear2.reduce((r, c) => r + price_to_number(c.ML), 0) };
+ const rowYear = {
+ YJLY: price_to_number(rowYearData.YJLY), CJCount: rowYearData.CJCount, GroupCount: rowYearData.CJCount,
+ YJLY2: price_to_number(rowYearData2.YJLY), CJCount2: rowYearData2.CJCount, GroupCount2: rowYearData2.CJCount,
+ };
+
+ const cols = ['YJLY', 'CJCount'].reduce((r, key) => ({ ...r, [key]: filterData.reduce((a, c) => a + price_to_number(c[key]), 0) }), {});
+ // console.log(tKey, filterData, filterDataYear, filterDataYear2);
+ return { ...cols, GroupCount:CJCount, CJCount, YJLY, rowYear, rawData: filterData, rawYearData: filterDataYear, rawYearData2: filterDataYear2 };
+};
+const dataSalesGHOther = (rawData, yearData, yearData2) => {
+ const exceptContry = Object.values(GHCountryListSetting).reduce((r, c) => r.concat(c), []);
+ // console.log('exceptContry', exceptContry);
+ // console.log('OOoo rawData', rawData.map(e => e.destinationCountry_AsJOSN));
+ const filterData = rawData
+ .filter((ele) => ['泰国水灯节'].every((item) => ele.productType.toLocaleLowerCase().indexOf(item) === -1))
+ .filter((ele) => exceptContry.every((item) => !ele.destinationCountry_AsJOSN.includes(item)));
+ // console.log('OOoo', filterData.map(e => e.destinationCountry_AsJOSN), filterData.map(e => e.productType));
+ const CJCount = filterData.length; // filterData.reduce((r, c) => r + c.CJCount, 0);
+ const YJLY = filterData.reduce((r, c) => r + price_to_number(c.ML), 0);
+
+ const filterDataYear = yearData
+ .filter((ele) => ['泰国水灯节'].every((item) => ele.productType.toLocaleLowerCase().indexOf(item) === -1))
+ .filter((ele) => exceptContry.every((item) => !ele.destinationCountry_AsJOSN.includes(item)));
+ const rowYearData = { CJCount: filterDataYear.length, YJLY: filterDataYear.reduce((r, c) => r + price_to_number(c.ML), 0) };
+ // console.log('OOoo year', filterDataYear.map(e => e.destinationCountry_AsJOSN), filterDataYear.map(e => e.productType));
+
+ const filterDataYear2 = yearData2
+ .filter((ele) => ['泰国水灯节'].every((item) => ele.productType.toLocaleLowerCase().indexOf(item) === -1))
+ .filter((ele) => exceptContry.every((item) => !ele.destinationCountry_AsJOSN.includes(item)));
+ const rowYearData2 = { CJCount: filterDataYear2.length, YJLY: filterDataYear2.reduce((r, c) => r + price_to_number(c.ML), 0) };
+ // console.log('Oo', filterDataYear2.map(e => e.destinationCountry_AsJOSN), filterDataYear2);
+ // console.log('Oo row', rowYearData2);
+
+ const rowYear = {
+ YJLY: price_to_number(rowYearData.YJLY), CJCount: rowYearData.CJCount, GroupCount: rowYearData.CJCount,
+ YJLY2: price_to_number(rowYearData2.YJLY), CJCount2: rowYearData2.CJCount, GroupCount2: rowYearData2.CJCount,
+ };
+
+ return { GroupCount:CJCount, CJCount, YJLY, rowYear, rawData: filterData, rawYearData: filterDataYear, rawYearData2: filterDataYear2 };
+};
+
+class MeetingData {
+ constructor(rootStore) {
+ this.rootStore = rootStore;
+ makeAutoObservable(this);
+ }
+
+ searchValues = {
+ DateType: { key: 'applyDate', value: 'applyDate', label: '提交日期' },
+ };
+
+ setSearchValues(body) {
+ this.searchValues = body;
+ }
+
+ GHTableData = [];
+ GHTableLoading = false;
+ /**
+ * 获取市场订单数据 ---------------------------------------------------------------------------------------------------
+ */
+ dataGHOrder = async (param) => {
+ // console.log('dataGH', param);
+ this.GHTableLoading = true;
+ const defaultParam = { DateType: 'applyDate' };
+ // 本周
+ const CHData = await getDetailData({ ...param, ...defaultParam, 'DepartmentList': '1', 'WebCode': 'All' });
+ const exceptCHData = await getDetailData({ ...param, ...defaultParam, 'DepartmentList': '28,33', 'WebCode': 'All' });
+
+ const yearStart = moment().startOf("year").format(DATE_FORMAT);
+ /** 截至今年 - 行 */
+ const [
+ { ordercountTotal1: CHDataYear },
+ { ordercount1: exceptCHDataYear },
+ ] = await Promise.all([
+ getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '1', 'WebCode': 'All', OrderType: 'LineClass' }),
+ getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '28,33', 'WebCode': 'All', OrderType: 'Product' }),
+ ]);
+ // const { ordercountTotal1: CHDataYear } = await getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '1', 'WebCode': 'All', OrderType: 'LineClass' });
+ // const { ordercount1: exceptCHDataYear } = await getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '28,33', 'WebCode': 'All', OrderType: 'Product' });
+ /** 截至今年 - 列 */
+ const [
+ { ordercount1: ColLineClassDataYear },
+ { ordercountTotal1: ColToBDataYear },
+ { ordercountTotal1: ColExternalDataYear },
+ ] = await Promise.all([
+ getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '1,2,28,7,33', 'WebCode': 'All', OrderType: 'LineClass' }),
+ getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '1,2,28,7,33', 'WebCode': 'GHTOBHW,GHTOBZG', OrderType: 'LineClass'}),
+ getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '1,2,28,7,33', 'WebCode': 'ZWQD', OrderType: 'LineClass'}),
+ ]);
+ // const { ordercount1: ColLineClassDataYear } = await getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '1,2,28,7,33', 'WebCode': 'All', OrderType: 'LineClass' });
+ // const { ordercountTotal1: ColToBDataYear } = await getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '1,2,28,7,33', 'WebCode': 'GHTOBHW,GHTOBZG', OrderType: 'LineClass' });
+ // const { ordercountTotal1: ColExternalDataYear } = await getOrderCountByType({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '1,2,28,7,33', 'WebCode': 'ZWQD', OrderType: 'LineClass' });
+ // 老客户
+ const yearDetail = await getDetailData({ ...param, ...defaultParam, Date1: yearStart, 'DepartmentList': '1,2,28,7,33', 'WebCode': 'All' });
+ const { isOld1: isOld1Year } = rowItem(yearDetail);
+
+ const colYearRow = {
+ LineClass_Origin: ColLineClassDataYear.filter((ele) => ele.OrderType.toLocaleLowerCase().indexOf('网前自然订单') !== -1).reduce((r, c) => r + c.OrderCount, 0),
+ LineClass_PPC: ColLineClassDataYear.filter((ele) => ele.OrderType.toLocaleLowerCase().indexOf('ppc') !== -1).reduce((r, c) => r + c.OrderCount, 0),
+ toB: ColToBDataYear.OrderCount,
+ isOld1: isOld1Year,
+ external: ColExternalDataYear.OrderCount,
+ };
+
+ const rows = [
+ { key: 'ch', label: '中国', ...rowItem(CHData), rowYear: CHDataYear.OrderCount },
+ { key: 'ja', label: '日本+', ...dataJA(exceptCHData, exceptCHDataYear) },
+ { key: 'se', label: '东南亚+', ...dataSE(exceptCHData, exceptCHDataYear) },
+ { key: 'in', label: '印度+', ...dataIN(exceptCHData, exceptCHDataYear) },
+ { key: 'other', label: '其他GH', ...dataGHOther(exceptCHData, exceptCHDataYear) },
+ ];
+ const columnsSum = ['LineClass_Origin', 'LineClass_PPC', 'toB', 'external', 'isOld1', 'total', 'rowYear'].reduce(
+ (r, col) => ({
+ ...r,
+ [col]: rows.reduce((rr, row) => rr + row[col], 0),
+ }),
+ {}
+ );
+ rows.push({ key: 'columnSum', label: '合计', ...columnsSum });
+ rows.push({ key: 'colYearRow', label: '截至', ...colYearRow });
+ runInAction(() => {
+ this.GHTableData = rows;
+ this.GHTableLoading = false;
+ });
+ };
+
+ GHSalesTableData = [];
+ GHSalesLoading = false;
+ /**
+ * 获取GH销售数据 ---------------------------------------------------------------------------------------------------
+ */
+ dataGHSales = async (param) => {
+ this.GHSalesLoading = true;
+ const salesParam = { ...param, DateType: 'confirmDate', WebCode: 'CHT,AH,GH,GHKYZG,GHKYHW,ZWQD', OrderType:'ALL', }; // WebCode: 不含分销
+ const [
+ { total1: CHSalesData }, // 不含分销
+ { total1: AHSalesData }, // 不含分销
+ { total1: GHSalesData }, // 不含分销
+ { total1: partnerSalesData },
+ { total1: totalSalesData },
+ ] = await Promise.all([
+ getDepartmentOrderMLByType({...salesParam, DepartmentList: '1,2', }),
+ getDepartmentOrderMLByType({...salesParam, DepartmentList: '28', }),
+ getDepartmentOrderMLByType({...salesParam, DepartmentList: '33', }),
+ getDepartmentOrderMLByType({...salesParam, DepartmentList: '1,2,28,33',WebCode: 'GHTOBHW,GHTOBZG',}),
+ getDepartmentOrderMLByType({...salesParam, DepartmentList: '1,2,28,33',WebCode: 'ALL',})
+ ]);
+ // const { total1: CHSalesDataTotal } = await getDepartmentOrderMLByType({...salesParam, DepartmentList: '1,2', WebCode: 'ALL',});
+ // const { total1: CHPartnerSalesData } = await getDepartmentOrderMLByType({...salesParam, DepartmentList: '1,2', WebCode: 'GHTOBHW,GHTOBZG', });
+ // const { total1: AHSalesDataTotal } = await getDepartmentOrderMLByType({...salesParam, DepartmentList: '28',WebCode: 'ALL',});
+ // const { total1: AHpartnerSalesData } = await getDepartmentOrderMLByType({...salesParam, DepartmentList: '28', WebCode: 'GHTOBHW,GHTOBZG', });
+ // const { total1: GHSalesDataTotal } = await getDepartmentOrderMLByType({...salesParam, DepartmentList: '33',WebCode: 'ALL',});
+ // const { total1: GHpartnerSalesData } = await getDepartmentOrderMLByType({...salesParam, DepartmentList: '33', WebCode: 'GHTOBHW,GHTOBZG', });
+ // 分销
+ // const CHSalesData0 = {'COLI_CJCount': CHSalesDataTotal.COLI_CJCount-CHPartnerSalesData.COLI_CJCount, 'COLI_ML2': CHSalesDataTotal.COLI_ML2-CHPartnerSalesData.COLI_ML2};
+ // const AHSalesData0 = {'COLI_CJCount': AHSalesDataTotal.COLI_CJCount-AHpartnerSalesData.COLI_CJCount, 'COLI_ML2': AHSalesDataTotal.COLI_ML2-AHpartnerSalesData.COLI_ML2};
+ // const GHSalesData0 = {'COLI_CJCount': GHSalesDataTotal.COLI_CJCount-GHpartnerSalesData.COLI_CJCount, 'COLI_ML2': GHSalesDataTotal.COLI_ML2-GHpartnerSalesData.COLI_ML2};
+ // const partnerSalesData0 = {'COLI_CJCount': CHPartnerSalesData.COLI_CJCount+AHpartnerSalesData.COLI_CJCount, 'COLI_ML2': CHPartnerSalesData.COLI_ML2+AHpartnerSalesData.COLI_ML2};
+ // const totalSalesData0 = {
+ // 'COLI_CJCount': CHSalesDataTotal.COLI_CJCount + AHSalesDataTotal.COLI_CJCount + GHSalesDataTotal.COLI_CJCount,
+ // 'COLI_ML2': CHSalesDataTotal.COLI_ML2 + AHSalesDataTotal.COLI_ML2 + GHSalesDataTotal.COLI_ML2,
+ // };
+
+ const yearStart = moment().startOf("year").format(DATE_FORMAT);
+ const yearEnd = moment().endOf("year").format(SMALL_DATETIME_FORMAT);
+ /** 截至今年 - 成交 */
+ const [
+ { total1: CHDataYear },
+ { total1: AHDataYear },
+ { total1: GHDataYear },
+ { total1: partnerDataYear },
+ { total1: totalDataYear },
+ ] = await Promise.all([
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '1,2', }),
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '28', }),
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '33', }),
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '1,2,28,7,33',WebCode: 'GHTOBHW,GHTOBZG',}),
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '1,2,28,7,33',WebCode: 'ALL',})
+ ]);
+ // const { total1: CHDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '1,2', });
+ // const { total1: AHDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '28', });
+ // const { total1: GHDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '33', });
+ // const { total1: partnerDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '1,2,28,7,33', WebCode: 'GHTOBHW,GHTOBZG', });
+ // const { total1: totalDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '1,2,28,7,33', WebCode: 'ALL', });
+ /** 截至今年 - 走团 */
+ const [
+ { total1: CHStartDataYear },
+ { total1: AHStartDataYear },
+ { total1: GHStartDataYear },
+ { total1: partnerStartDataYear },
+ { total1: totalStartDataYear },
+ ] = await Promise.all([
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '1,2', DateType: 'startDate' }),
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '28', DateType: 'startDate' }),
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart,DepartmentList: '33', DateType: 'startDate' }),
+ /** 截至今年 - 走团 - 分销 */
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '1,2,28,7,33',WebCode: 'GHTOBHW,GHTOBZG', DateType: 'startDate',}),
+ getDepartmentOrderMLByType({...salesParam, Date1: yearStart, DepartmentList: '1,2,28,7,33',WebCode: 'ALL', DateType: 'startDate',})
+ ]);
+ // const { total1: CHStartDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart,DepartmentList: '1,2', DateType: 'startDate' });
+ // const { total1: AHStartDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart,DepartmentList: '28', DateType: 'startDate' });
+ // const { total1: GHStartDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart,DepartmentList: '33', DateType: 'startDate' });
+ /** 截至今年 - 走团 - 分销 */
+ // const { total1: partnerStartDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart,DepartmentList: '1,2,28,7,33', WebCode: 'GHTOBHW,GHTOBZG', DateType: 'startDate' });
+ // const { total1: totalStartDataYear } = await getDepartmentOrderMLByType({...salesParam, Date1: yearStart,DepartmentList: '1,2,28,7,33', WebCode: 'ALL', DateType: 'startDate' });
+
+ const rows = [
+ {
+ key: 'ch',
+ label: 'CH(不含分销)',
+ YJLY: price_to_number(CHSalesData.COLI_ML2),
+ CJCount: (CHSalesData.COLI_CJCount),
+ rowYear: { YJLY: price_to_number(CHDataYear.COLI_ML2), CJCount: CHDataYear.COLI_CJCount, YJLY2: price_to_number(CHStartDataYear.COLI_ML2) },
+ },
+ {
+ key: 'ah',
+ label: 'AH(不含分销)',
+ YJLY: price_to_number(AHSalesData.COLI_ML2),
+ CJCount: (AHSalesData.COLI_CJCount),
+ rowYear: { YJLY: price_to_number(AHDataYear.COLI_ML2), CJCount: AHDataYear.COLI_CJCount, YJLY2: price_to_number(AHStartDataYear.COLI_ML2) },
+ },
+ {
+ key: 'partner',
+ label: '分销',
+ YJLY: price_to_number(partnerSalesData.COLI_ML2),
+ CJCount: (partnerSalesData.COLI_CJCount),
+ rowYear: { YJLY: price_to_number(partnerDataYear.COLI_ML2), CJCount: partnerDataYear.COLI_CJCount, YJLY2: price_to_number(partnerStartDataYear.COLI_ML2) },
+ },
+ {
+ key: 'gh',
+ label: 'GH(不含分销)',
+ YJLY: price_to_number(GHSalesData.COLI_ML2),
+ CJCount: (GHSalesData.COLI_CJCount),
+ rowYear: { YJLY: price_to_number(GHDataYear.COLI_ML2), CJCount: GHDataYear.COLI_CJCount, YJLY2: price_to_number(GHStartDataYear.COLI_ML2) },
+ },
+ {
+ key: 'total',
+ label: '合计',
+ YJLY: price_to_number(totalSalesData.COLI_ML2),
+ CJCount: (totalSalesData.COLI_CJCount),
+ rowYear: { YJLY: price_to_number(totalDataYear.COLI_ML2), CJCount: totalDataYear.COLI_CJCount, YJLY2: price_to_number(totalStartDataYear.COLI_ML2) },
+ },
+ ];
+ runInAction(() => {
+ this.GHSalesTableData = rows;
+ this.GHSalesLoading = false;
+ });
+ };
+
+
+ GHServiceTableData = [];
+ GHServiceLoading = false;
+ /**
+ * 获取GH服务数据 ---------------------------------------------------------------------------------------------------
+ */
+ dataGHService = async (param) => {
+ this.GHServiceLoading = true;
+ const serviceParam = { ...param, DateType: 'startDate', 'WebCode': 'All' };
+ // 走团数
+ const [
+ { ordercountTotal1: { OrderCount: CHGroupCount } },
+ { ordercountTotal1: { OrderCount: AHGroupCount } },
+ { ordercountTotal1: { OrderCount: GHGroupCount } },
+ ] = await Promise.all([
+ getOrderCountByType({ ...serviceParam, 'DepartmentList': '1,2', OrderType: 'Form'}),
+ getOrderCountByType({ ...serviceParam, 'DepartmentList': '28', OrderType: 'Form'}),
+ getOrderCountByType({ ...serviceParam, 'DepartmentList': '33', OrderType: 'Form'}),
+ ]);
+ // 走团数 - 年
+ // * 走团: 整团数, 而非各地接社/目的地的总和
+ const yearStart = moment().startOf("year").format(DATE_FORMAT);
+ const [
+ { ordercountTotal1: { OrderCount: CHGroupCountYear } },
+ { ordercountTotal1: { OrderCount: AHGroupCountYear } },
+ { ordercountTotal1: { OrderCount: GHGroupCountYear } },
+ ] = await Promise.all([
+ getOrderCountByType({ ...serviceParam, 'DepartmentList': '1,2', OrderType: 'Form', Date1: yearStart, }),
+ getOrderCountByType({ ...serviceParam, 'DepartmentList': '28', OrderType: 'Form', Date1: yearStart, }),
+ getOrderCountByType({ ...serviceParam, 'DepartmentList': '33', OrderType: 'Form', Date1: yearStart, }),
+ ]);
+ // 好评数
+ const [
+ { total1: { GoodCount: CHGoodCount } },
+ { total1: { GoodCount: AHGoodCount } },
+ { total1: { GoodCount: GHGoodCount } },
+ ] = await Promise.all([
+ getAgentGroupInfoALL({ ...serviceParam, 'DepartmentList': '1,2', }),
+ getAgentGroupInfoALL({ ...serviceParam, 'DepartmentList': '28', }),
+ getAgentGroupInfoALL({ ...serviceParam, 'DepartmentList': '33', }),
+ ]);
+ // 好评数 - 年
+ const [
+ { total1: { GoodCount: CHGoodCountYear, } },
+ { total1: { GoodCount: AHGoodCountYear, } },
+ { total1: { GoodCount: GHGoodCountYear, } },
+ ] = await Promise.all([
+ getAgentGroupInfoALL({ ...serviceParam, Date1: yearStart, 'DepartmentList': '1,2', }),
+ getAgentGroupInfoALL({ ...serviceParam, Date1: yearStart, 'DepartmentList': '28', }),
+ getAgentGroupInfoALL({ ...serviceParam, Date1: yearStart, 'DepartmentList': '33', }),
+ ]);
+
+ const rows = [
+ { key: 'ch', label: 'CH', GoodCount: CHGoodCount, GroupCount: CHGroupCount, rowYear: { GroupCount: CHGroupCountYear, GoodCount: CHGoodCountYear } },
+ { key: 'ah', label: 'AH', GoodCount: AHGoodCount, GroupCount: AHGroupCount, rowYear: { GroupCount: AHGroupCountYear, GoodCount: AHGoodCountYear } },
+ { key: 'Gh', label: 'GH', GoodCount: GHGoodCount, GroupCount: GHGroupCount, rowYear: { GroupCount: GHGroupCountYear, GoodCount: GHGoodCountYear } },
+ ];
+ // const GHRowWeek = { GoodCount: GHGoodCountWeek, GroupCount: 0 };
+ // const columnsSum = ['GoodCount', 'GroupCount'].reduce((r, col) => ({ ...r, [col]: [...rows, GHRowWeek].reduce((rr, row) => rr + (row[col] || 0), 0) }), {});
+ // const allYearData = rows.map((row) => row.rowYear).concat([{ GoodCount: GHGoodCountYear, GroupCount: 0 }]);
+ // // console.log(allYearData);
+ // const rowYear = ['GoodCount', 'GroupCount', ].reduce((r, col) => ({ ...r, [col]: allYearData.reduce((rr, row) => rr + (row[col] || 0), 0) }), {});
+ // rows.push({ key: 'columnSum', label: '合计', ...columnsSum, rowYear });
+ // console.log(rows);
+ runInAction(() => {
+ this.GHServiceTableData = rows;
+ this.GHServiceLoading = false;
+ });
+ };
+}
+export default MeetingData;
diff --git a/src/views/Meeting2025-GH.jsx b/src/views/Meeting2025-GH.jsx
new file mode 100644
index 0000000..119e2d1
--- /dev/null
+++ b/src/views/Meeting2025-GH.jsx
@@ -0,0 +1,134 @@
+import { useContext } from 'react';
+import { observer } from 'mobx-react';
+import { stores_Context } from '../config';
+import { Table, Row, Col, Divider, Tooltip } from 'antd';
+import { InfoCircleOutlined } from '@ant-design/icons';
+import SearchForm from '../components/search/SearchForm';
+import { TableExportBtn } from './../components/Data';
+import { fixTo2Decimals } from './../utils/commons';
+
+const numberConvert10K = (number, scale = 10) => {
+ return fixTo2Decimals(number / (1000 * scale)) + '';
+};
+// 注意TdCell要提到DataTable作用域外声明
+const TdCell = (tdprops) => {
+ // onMouseEnter, onMouseLeave在数据量多的时候,会严重阻塞表格单元格渲染,严重影响性能
+ const { onMouseEnter, onMouseLeave, ...restProps } = tdprops;
+ return
| ;
+};
+
+export default observer((props) => {
+ const { date_picker_store: searchFormStore, MeetingData2025Store: MeetingDataStore } = useContext(stores_Context);
+ const { formValues, formValuesToSub, siderBroken } = searchFormStore;
+
+ const dataRefresh = async (obj) => {
+ MeetingDataStore.dataGHOrder({ ...(obj || formValuesToSub) });
+ MeetingDataStore.dataGHSales({ ...(obj || formValuesToSub) });
+ MeetingDataStore.dataGHService({ ...(obj || formValuesToSub) });
+ };
+
+ const targetTableProps = {
+ loading: MeetingDataStore.GHLoading,
+ // sticky: true,
+ scroll: { x: 1000, y: 400 },
+ pagination: false,
+ components: { body: { cell: TdCell } },
+ orderColumns: [
+ { key: 'label', title: '市场:', dataIndex: 'label', width: 150 },
+ {
+ key: 'LineClass_Origin',
+ titleX: '网站',
+ title: () => (
+ <>
+ 网站{' '}
+
+
+
+ >
+ ),
+ dataIndex: 'LineClass_Origin',
+ },
+ {
+ key: 'external',
+ titleX: '站外渠道',
+ title: () => (
+ <>
+ 站外渠道{' '}
+
+
+
+ >
+ ),
+ dataIndex: 'external',
+ },
+ { key: 'LineClass_PPC', title: 'PPC', dataIndex: 'LineClass_PPC' },
+ { key: 'toB', title: 'To B', dataIndex: 'toB' },
+ { key: 'isOld1', title: 'C老客户', dataIndex: 'isOld1' },
+ { key: 'total', title: '合计', dataIndex: 'total' },
+ { key: 'rowYear', title: '截至年订单数', dataIndex: 'rowYear' },
+ // { key: 'groupsLabel2', title: '年订单目标', dataIndex: 'groupsLabel2' },
+ // { key: 'groupsLabel2', title: '进度', dataIndex: 'groupsLabel2' },
+ ],
+ salesColumns: [
+ { key: 'label', title: '顾问:', dataIndex: 'label', width: 150 },
+ { key: 'CJCount', title: '成交个数', dataIndex: 'CJCount' },
+ { key: 'YJLY', title: '成交毛利(万)', dataIndex: 'YJLY', render: (text) => numberConvert10K(text) },
+ { key: 'CJCount1', title: '年成交个数', dataIndex: ['rowYear', 'CJCount'] },
+ { key: 'YJLY1', title: '年成交毛利(万)', dataIndex: ['rowYear', 'YJLY'], render: (text) => numberConvert10K(text) },
+ { key: 'YJLY2', title: '年走团毛利(万)', dataIndex: ['rowYear', 'YJLY2'], render: (text) => numberConvert10K(text) },
+ ],
+ serviceColumns: [
+ { key: 'label', title: '客服:', dataIndex: 'label', width: 150 },
+ { key: 'GroupCount', title: '走团个数', dataIndex: 'GroupCount' },
+ { key: 'GoodCount', title: '好评个数', dataIndex: 'GoodCount' },
+ { key: 'GroupCount1', title: '年走团个数', dataIndex: ['rowYear', 'GroupCount'] },
+ { key: 'GoodCount2', title: '年好评个数', dataIndex: ['rowYear', 'GoodCount'] },
+ ],
+ };
+
+ return (
+ <>
+
+
+ {
+ MeetingDataStore.setSearchValues(form);
+ dataRefresh(obj);
+ }}
+ />
+
+
+
+ GH例会数据 2025
+
+ GH: 市场
+
+
+
+
+
+ GH: 顾问成交
+
+
+
+
+
+ GH: 客服
+
+
+
+
+ >
+ );
+});
diff --git a/src/views/Sale.jsx b/src/views/Sale.jsx
index 030e4cc..c2381ff 100644
--- a/src/views/Sale.jsx
+++ b/src/views/Sale.jsx
@@ -48,6 +48,10 @@ const Sale = () => {
...config_data,
...{
//seriesField: "OPI_Name",//分组
+ columnWidthRatio: 0.28,
+ // dodgePadding: 1,
+ // minColumnWidth: 5,
+ // maxColumnWidth: 15,
label: {
position: 'top',
},