diff --git a/package-lock.json b/package-lock.json
index a57720e..31d28f8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,9 @@
"dependencies": {
"@ant-design/charts": "^1.4.2",
"@ant-design/pro-components": "^2.6.16",
+ "@haina/utils-commons": "https://research.hainatravel.com/npm/utils-commons-0.1.1.tgz",
+ "@haina/utils-pagespy": "https://research.hainatravel.com/npm/utils-pagespy-0.1.1.tgz",
+ "@haina/utils-request": "https://research.hainatravel.com/npm/utils-request-0.1.1.tgz",
"antd": "^4.22.6",
"dingtalk-jsapi": "^3.0.9",
"docx": "^9.5.1",
@@ -3843,6 +3846,24 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
+ "node_modules/@haina/utils-commons": {
+ "version": "0.1.1",
+ "resolved": "https://research.hainatravel.com/npm/utils-commons-0.1.1.tgz",
+ "integrity": "sha512-I3Ll5iNLtrnOCzs0IB3OXGQa0l75aQT740NKCUFwR1DHRx9vjeoqestS/PamZN1fuiodxWHkOao3JXOPRwSSfw==",
+ "hasInstallScript": true
+ },
+ "node_modules/@haina/utils-pagespy": {
+ "version": "0.1.1",
+ "resolved": "https://research.hainatravel.com/npm/utils-pagespy-0.1.1.tgz",
+ "integrity": "sha512-aMyp8QPDM1URGOn0Bw1z1zUM7MDUDuHiPT8U5Zmusb6EIka+7XVmunQGy7HMPSgrfByD5DlNFkF/l5ej45PRtA==",
+ "hasInstallScript": true
+ },
+ "node_modules/@haina/utils-request": {
+ "version": "0.1.1",
+ "resolved": "https://research.hainatravel.com/npm/utils-request-0.1.1.tgz",
+ "integrity": "sha512-p+0ApwEf+lcSOr7tS9kdgZmW+vZc0Gol6+8IejNv/qfMk6cmuBJYn5khvcSR1mblBPMag+464YpoBI32R9OMDQ==",
+ "hasInstallScript": true
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
@@ -24391,6 +24412,18 @@
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz",
"integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA=="
},
+ "@haina/utils-commons": {
+ "version": "https://research.hainatravel.com/npm/utils-commons-0.1.1.tgz",
+ "integrity": "sha512-I3Ll5iNLtrnOCzs0IB3OXGQa0l75aQT740NKCUFwR1DHRx9vjeoqestS/PamZN1fuiodxWHkOao3JXOPRwSSfw=="
+ },
+ "@haina/utils-pagespy": {
+ "version": "https://research.hainatravel.com/npm/utils-pagespy-0.1.1.tgz",
+ "integrity": "sha512-aMyp8QPDM1URGOn0Bw1z1zUM7MDUDuHiPT8U5Zmusb6EIka+7XVmunQGy7HMPSgrfByD5DlNFkF/l5ej45PRtA=="
+ },
+ "@haina/utils-request": {
+ "version": "https://research.hainatravel.com/npm/utils-request-0.1.1.tgz",
+ "integrity": "sha512-p+0ApwEf+lcSOr7tS9kdgZmW+vZc0Gol6+8IejNv/qfMk6cmuBJYn5khvcSR1mblBPMag+464YpoBI32R9OMDQ=="
+ },
"@humanwhocodes/config-array": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
diff --git a/package.json b/package.json
index 97e4712..7493481 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,9 @@
"dependencies": {
"@ant-design/charts": "^1.4.2",
"@ant-design/pro-components": "^2.6.16",
+ "@haina/utils-commons": "https://research.hainatravel.com/npm/utils-commons-0.1.1.tgz",
+ "@haina/utils-pagespy": "https://research.hainatravel.com/npm/utils-pagespy-0.1.1.tgz",
+ "@haina/utils-request": "https://research.hainatravel.com/npm/utils-request-0.1.1.tgz",
"antd": "^4.22.6",
"dingtalk-jsapi": "^3.0.9",
"docx": "^9.5.1",
diff --git a/src/components/Data.jsx b/src/components/Data.jsx
index 7b2ae3f..bfd2d52 100644
--- a/src/components/Data.jsx
+++ b/src/components/Data.jsx
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import { Tag, Button, message } from 'antd';
import { CaretUpOutlined, CaretDownOutlined, DownloadOutlined } from '@ant-design/icons';
import { utils, writeFile } from "xlsx";
-import { isEmpty, getNestedValue } from "../utils/commons";
+import { isEmpty, getNestedValue, fixTo2Decimals } from "@haina/utils-commons";
/**
* @property diffPercent
@@ -28,6 +28,36 @@ export const VSTag = (props) => {
);
};
+/**
+ * @property {number} [diffPercent=0]
+ * @property {number} diffData
+ * @property {number} data1
+ * @property {number} data2
+ * @property {string} dataSuffix
+ */
+export const VSDataTag = ({ diffPercent=0, diffData=0, data1=0, data2=0, dataSuffix='' }) => {
+ const _diffPercent = diffPercent || (data2) ? fixTo2Decimals((data1-data2)/data2*100) : 100;
+ const _diffData = diffData || isNaN(data2) ? fixTo2Decimals(data1-0) : (fixTo2Decimals(data1-data2));
+ const CaretIcon = parseInt(_diffPercent) < 0 ? CaretDownOutlined : CaretUpOutlined;
+ const tagColor = parseInt(_diffPercent) < 0 ? 'gold' : 'lime';
+ // parseInt(_diffPercent) === 0 ? (
+ // '-'
+ // ) :
+ return (
+
+
+ {data1}{dataSuffix} VS {data2}{dataSuffix}
+
+ {_diffData !== 0 && (
+ } color={tagColor}>
+ {_diffPercent}
+ % {_diffData}{dataSuffix}
+
+ )}
+
+ );
+};
+
/**
* 导出表格数据存为xlsx
* @property label 文件名字
diff --git a/src/stores/CustomerServices.js b/src/stores/CustomerServices.js
index 22a643e..f37af87 100644
--- a/src/stores/CustomerServices.js
+++ b/src/stores/CustomerServices.js
@@ -37,6 +37,9 @@ class CustomerServices {
});
}
+ /**
+ * @deprecated 已迁移到zustand
+ */
fetchAgentGroupCount() {
this.inProgress = true;
const fetchUrl = prepareUrl(config.HT_HOST + '/service-web/QueryData/GetAgentGroupInfoALL')
@@ -327,6 +330,9 @@ class CustomerServices {
});
}
+ /**
+ * @deprecated 已迁移到zustand
+ */
fetchGroupListByAgentId(agentId) {
this.inProgress = true;
this.agentCompany = '...';
diff --git a/src/views/AgentGroupCount.jsx b/src/views/AgentGroupCount.jsx
index 8d7dc5d..999e297 100644
--- a/src/views/AgentGroupCount.jsx
+++ b/src/views/AgentGroupCount.jsx
@@ -1,32 +1,245 @@
-import { useContext, useEffect } from 'react';
+import { useContext } from 'react';
+import { NavLink } from "react-router-dom";
import { Row, Col, Typography, Space, Table, Divider } from 'antd';
import { stores_Context } from '../config';
import { observer } from 'mobx-react';
+import { toJS } from 'mobx';
import 'moment/locale/zh-cn';
-import { utils, writeFileXLSX } from 'xlsx';
import SearchForm from './../components/search/SearchForm';
-import { TableExportBtn } from './../components/Data';
+import { TableExportBtn, VSDataTag } from './../components/Data';
+import useCustomerServicesStore from '../zustand/CustomerServices';
+import { useShallow } from 'zustand/shallow';
+import { fixTo2Decimals } from "@haina/utils-commons";
+
+const sorter = (a, b, key) => a[key] - b[key];
+// 注意TdCell要提到DataTable作用域外声明
+const TdCell = (tdprops) => {
+ // onMouseEnter, onMouseLeave在数据量多的时候,会严重阻塞表格单元格渲染,严重影响性能
+ const { onMouseEnter, onMouseLeave, ...restProps } = tdprops;
+ return
| ;
+};
+
+const DataRenderCell = ({ data1, data2, dataSuffix = '', showDiffData }) => {
+ if (showDiffData) {
+ return ;
+ }
+ return {data1}{dataSuffix}
;
+};
const AgentGroupCount = () => {
const { customerServicesStore, date_picker_store } = useContext(stores_Context);
- const agentGroupList = customerServicesStore.agentGroupList;
- const agentGroupListColumns = customerServicesStore.agentGroupListColumns;
- const { inProgress } = customerServicesStore;
+ const [loading, searchValues, setSearchValues, searchValuesToSub] = useCustomerServicesStore(useShallow((state) => [state.loading, state.searchValues, state.setSearchValues, state.searchValuesToSub]));
+
+ const [agentGroupList, total1] = useCustomerServicesStore(useShallow((state) => [state.agentCountList, state.agentCountTotal]));
+ const getAgentGroupCount = useCustomerServicesStore((state) => state.getAgentGroupCount);
- useEffect(() => {
- customerServicesStore.fetchAllAgent();
- }, []);
+ const columns = [
+ {
+ title: '地接社名称',
+ dataIndex: 'VendorName',
+ fixed: 'left',
+ children: [
+ {
+ // title: this.startDate.format(config.DATE_FORMAT) + '~' + this.endDate.format(config.DATE_FORMAT),
+ dataIndex: 'VendorName',
+ fixed: 'left',
+ render: (text, record) => {record.VendorName},
+ },
+ ],
+ },
+ {
+ title: '团数',
+ dataIndex: 'GroupCount',
+ sorter: (a, b) => sorter(a, b, 'GroupCount'),
+ children: [
+ {
+ title: , // total1.GroupCount,
+ dataIndex: 'GroupCount',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '人数',
+ dataIndex: 'PersonNum',
+ sorter: (a, b) => sorter(a, b, 'PersonNum'),
+ children: [
+ {
+ title: , // total1.PersonNum,
+ dataIndex: 'PersonNum',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '团天数',
+ dataIndex: 'GroupDays',
+ sorter: (a, b) => sorter(a, b, 'GroupDays'),
+ children: [
+ {
+ title: , // total1.GroupDays,
+ dataIndex: 'GroupDays',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '交易额',
+ dataIndex: 'totalcost',
+ sorter: (a, b) => sorter(a, b, 'totalcost'),
+ children: [
+ {
+ title: , // total1.totalcost,
+ dataIndex: 'totalcost',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '反馈表团数',
+ dataIndex: 'FKBTS',
+ sorter: (a, b) => sorter(a, b, 'FKBTS'),
+ children: [
+ {
+ title: , // total1.FKBTS,
+ dataIndex: 'FKBTS',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '东道主团数',
+ dataIndex: 'DDZTS',
+ sorter: (a, b) => sorter(a, b, 'DDZTS'),
+ children: [
+ {
+ title: , // total1.DDZTS,
+ dataIndex: 'DDZTS',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '东道主案例数',
+ dataIndex: 'DDZCases',
+ sorter: (a, b) => sorter(a, b, 'DDZCases'),
+ children: [
+ {
+ title: , // total1.DDZCases,
+ dataIndex: 'DDZCases',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '东道主案例比例',
+ dataIndex: 'DDZRate',
+ sorter: (a, b) => sorter(a, b, 'DDZRate'),
+ children: [
+ {
+ title: , // total1.DDZRate,
+ dataIndex: 'DDZRate',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '站外好评团数',
+ dataIndex: 'ZWHP',
+ sorter: (a, b) => sorter(a, b, 'ZWHP'),
+ children: [
+ {
+ title: , // total1.ZWHP,
+ dataIndex: 'ZWHP',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '站外好评数',
+ dataIndex: 'ZWHPCases',
+ sorter: (a, b) => sorter(a, b, 'ZWHPCases'),
+ children: [
+ {
+ title: , // total1.ZWHPCases,
+ dataIndex: 'ZWHPCases',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '站外好评率',
+ dataIndex: 'ZWHPRate',
+ sorter: (a, b) => sorter(a, b, 'ZWHPRate'), // parseInt(a.ZWHPRate) - parseInt(b.ZWHPRate),
+ children: [
+ {
+ title: , // total1.ZWHPRate,
+ dataIndex: 'ZWHPRate',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '不满数',
+ dataIndex: 'BMS',
+ sorter: (a, b) => sorter(a, b, 'BMS'),
+ children: [
+ {
+ title: , // total1.BMS,
+ dataIndex: 'BMS',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '不满率',
+ dataIndex: 'BMRate',
+ sorter: (a, b) => sorter(a, b, 'BMRate'), // parseInt(a.BMRate) - parseInt(b.BMRate),
+ children: [
+ {
+ title: , // total1.BMRate,
+ dataIndex: 'BMRate',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '投诉数',
+ dataIndex: 'TS',
+ sorter: (a, b) => sorter(a, b, 'TS'),
+ children: [
+ {
+ title: , // total1.TS,
+ dataIndex: 'TS',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ {
+ title: '投诉率',
+ dataIndex: 'TSRate',
+ sorter: (a, b) => sorter(a, b, 'TSRate'), // parseInt(a.TSRate) - parseInt(b.TSRate),
+ children: [
+ {
+ title: , // total1.TSRate,
+ dataIndex: 'TSRate',
+ render: (text, r) => ,
+ },
+ ],
+ },
+ ];
return (
<>
-
+
{
}}
onSubmit={(_err, obj, form) => {
customerServicesStore.setSearchValues(obj, form);
- customerServicesStore.fetchAgentGroupCount();
+ setSearchValues(obj, form);
+ getAgentGroupCount(obj);
}}
/>
@@ -47,18 +261,19 @@ const AgentGroupCount = () => {
地接社团信息
-
+
record.key}
- loading={inProgress}
+ rowKey={(record) => record.EOI_ObjSN}
+ loading={loading}
pagination={false}
- scroll={{ x: 1000 }}
+ scroll={{ x: 2000 }}
/>
diff --git a/src/views/AgentGroupList.jsx b/src/views/AgentGroupList.jsx
index 545c8ac..57dbe77 100644
--- a/src/views/AgentGroupList.jsx
+++ b/src/views/AgentGroupList.jsx
@@ -1,22 +1,161 @@
-import { useContext, useEffect } from 'react';
+import { useContext, useEffect, useMemo } from 'react';
import { Row, Col, Typography, Space, Table, List } from 'antd';
import { stores_Context } from '../config';
import { observer } from 'mobx-react';
import { NavLink, useParams } from 'react-router-dom';
import 'moment/locale/zh-cn';
import SearchForm from './../components/search/SearchForm';
+import useCustomerServicesStore from '../zustand/CustomerServices';
+import { useShallow } from 'zustand/shallow';
+import { isEmpty } from '@haina/utils-commons';
+import { toJS } from 'mobx';
+
+const buildColumns = (total) => [
+ {
+ title: '团名',
+ dataIndex: 'GRI_Name',
+ children: [
+ {
+ title: '',
+ dataIndex: 'GRI_Name',
+ },
+ ],
+ },
+ {
+ title: '人数',
+ dataIndex: 'COLI_PersonNum',
+ sorter: (a, b) => a.COLI_PersonNum - b.COLI_PersonNum,
+ children: [
+ {
+ title: total.COLI_PersonNum,
+ dataIndex: 'COLI_PersonNum',
+ },
+ ],
+ },
+ {
+ title: '天数',
+ dataIndex: 'COLI_Days',
+ sorter: (a, b) => a.COLI_Days - b.COLI_Days,
+ children: [
+ {
+ title: total.COLI_Days,
+ dataIndex: 'COLI_Days',
+ },
+ ],
+ },
+ {
+ title: '交易额',
+ dataIndex: 'totalcost',
+ sorter: (a, b) => a.totalcost - b.totalcost,
+ children: [
+ {
+ title: total.totalcost,
+ dataIndex: 'totalcost',
+ },
+ ],
+ },
+ {
+ title: '导游',
+ dataIndex: 'GuideName',
+ children: [
+ {
+ title: '-',
+ dataIndex: 'GuideName',
+ },
+ ],
+ },
+ {
+ title: '反馈表',
+ dataIndex: 'FKB',
+ sorter: (a, b) => a.FKB - b.FKB,
+ children: [
+ {
+ title: total.FKB,
+ dataIndex: 'FKB',
+ },
+ ],
+ },
+ {
+ title: '东道主',
+ dataIndex: 'DDZCases',
+ sorter: (a, b) => a.DDZCases - b.DDZCases,
+ children: [
+ {
+ title: total.DDZCases,
+ dataIndex: 'DDZCases',
+ },
+ ],
+ },
+ {
+ title: '前勤分',
+ dataIndex: 'qianqin',
+ children: [
+ {
+ title: total.qianqin,
+ dataIndex: 'qianqin',
+ },
+ ],
+ },
+ {
+ title: '好评',
+ dataIndex: 'Good',
+ sorter: (a, b) => a.Good - b.Good,
+ children: [
+ {
+ title: total.Good,
+ dataIndex: 'Good',
+ },
+ ],
+ },
+ {
+ title: '差评',
+ dataIndex: 'Bad',
+ sorter: (a, b) => a.Bad - b.Bad,
+ children: [
+ {
+ title: total.Bad,
+ dataIndex: 'Bad',
+ },
+ ],
+ },
+ {
+ title: '投诉',
+ dataIndex: 'TS',
+ sorter: (a, b) => a.TS - b.TS,
+ children: [
+ {
+ title: total.TS,
+ dataIndex: 'TS',
+ },
+ ],
+ },
+ {
+ title: '不满',
+ dataIndex: 'BM',
+ sorter: (a, b) => a.BM - b.BM,
+ children: [
+ {
+ title: total.BM,
+ dataIndex: 'BM',
+ },
+ ],
+ },
+];
const AgentGroupList = () => {
const { agentId } = useParams();
const { customerServicesStore, date_picker_store } = useContext(stores_Context);
+ const [loading, searchValues, setSearchValues] = useCustomerServicesStore(useShallow((state) => [state.loading, state.searchValues, state.setSearchValues]));
+
+ const [{ result1, result2, total1, total2, title1, title2 }, agencyName] = useCustomerServicesStore(useShallow((state) => [state.agencyGroups, state.agencyName]));
+ const getGroupListByAgentId = useCustomerServicesStore((state) => state.getGroupListByAgentId);
useEffect(() => {
- customerServicesStore.fetchGroupListByAgentId(agentId);
+ getGroupListByAgentId(agentId);
}, []);
- const groupList = customerServicesStore.groupList;
- const groupListColumns = customerServicesStore.groupListColumns;
- const { startDate, endDate, dateType, inProgress } = customerServicesStore;
+ const columns1 = useMemo(() => buildColumns(total1), [total1]);
+ const columns2 = useMemo(() => buildColumns(total2), [total2]);
return (
<>
@@ -29,34 +168,37 @@ const AgentGroupList = () => {
{
customerServicesStore.setSearchValues(obj, form);
- customerServicesStore.fetchGroupListByAgentId(agentId);
+ setSearchValues(obj, form);
+ getGroupListByAgentId(agentId);
}}
/>
- {customerServicesStore.agentCompany}
+ {agencyName}
title1}
sticky
- dataSource={groupList}
- columns={groupListColumns}
+ dataSource={result1}
+ columns={columns1}
size="small"
- rowKey={(record) => record.key}
- loading={inProgress}
+ rowKey={(record) => record.GRI_SN}
+ loading={loading}
pagination={false}
scroll={{ x: 1000 }}
expandable={{
@@ -72,6 +214,31 @@ const AgentGroupList = () => {
),
}}
/>
+ {isEmpty(result2) ? null : (
+ title2}
+ sticky
+ dataSource={result2}
+ columns={columns2}
+ size="small"
+ rowKey={(record) => record.GRI_SN}
+ loading={loading}
+ pagination={false}
+ scroll={{ x: 1000 }}
+ expandable={{
+ expandedRowRender: (record) => (
+
+
+
+
+
+
+
+
+ ),
+ }}
+ />
+ )}