Преглед на файлове

reactor:甄别重新发起修改为班长办理对象不必选;

zhangchong преди 4 месеца
родител
ревизия
3ac0b9fb47

+ 69 - 24
src/views/statistics/order/acceptTopTen.vue

@@ -14,21 +14,9 @@
 					</el-form-item>
 				</el-form>
 			</div>
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
-				@updateTable="queryList"
-				:loading="state.loading"
-				show-summary
-				border
-				:pagination="false"
-				:toolButton="['refresh', 'setting', 'exportAll']"
-				:exportMethod="departmentTopTenExport"
-				:exportParams="requestParams"
-				:key="Math.random()"
-			>
-			</ProTable>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-grid v-bind="gridOptions"> </vxe-grid>
+			</div>
 		</div>
 	</div>
 </template>
@@ -38,20 +26,18 @@ import { FormInstance } from 'element-plus';
 import { departmentTopTenExport, departmentTopTenNew } from '@/api/statistics/order';
 import { defaultDate } from '@/utils/constants';
 import Other from '@/utils/other';
+import XEUtils from 'xe-utils';
 
 const StatisticalTime = defineAsyncComponent(() => import('@/components/StatisticalTime/index.vue')); // 日期类型选择组件
-// 表格配置项
-const columns = ref<any[]>([]);
 // 定义变量内容
 const ruleFormRef = ref<RefType>(); // 表单ref
 const state = reactive<any>({
 	queryParams: {
 		// 查询条件
 		crTime: defaultDate,
-		StartTime:null,
-		EndTime:null
+		StartTime: null,
+		EndTime: null,
 	},
-	tableData: [], //表单
 	loading: false, // 加载
 });
 /** 搜索按钮操作 */
@@ -59,44 +45,103 @@ const handleQuery = () => {
 	// state.queryParams.PageIndex = 1;
 	queryList();
 };
-/** 获取列表 */
 const requestParams = ref<EmptyObjectType>({});
+const gridOptions = reactive<any>({
+	loading: false,
+	border: true,
+	showOverflow: true,
+	printConfig: {},
+	columnConfig: {
+		resizable: true,
+	},
+	scrollY: {
+		enabled: true,
+		gt: 20,
+		mode: 'wheel',
+	},
+	toolbarConfig: {
+		zoom: true,
+		custom: true,
+		refresh: {
+			queryMethod: () => {
+				queryList();
+			},
+		},
+		tools: [{ toolRender: { name: 'exportAll' } }],
+	},
+	customConfig: {
+		storage: true,
+	},
+	id: 'statisticsOrderAcceptTop10',
+	rowConfig: { isHover: true, height: 30, isCurrent: true,useKey:true },
+	height: 'auto',
+	columns: [],
+	data: [],
+	showFooter: true,
+	footerMethod: ({ columns, data }) => {
+		return [
+			columns.map((column: any, columnIndex: number) => {
+				if (columnIndex === 0) {
+					return '合计';
+				}
+				return XEUtils.sum(data, column.property);
+			}),
+		];
+	},
+	params: {
+		exportMethod: departmentTopTenExport,
+		exportParams: requestParams,
+	},
+});
+/** 获取列表 */
 const queryList = () => {
 	state.loading = true;
+	gridOptions.loading = true;
 	requestParams.value = Other.deepClone(state.queryParams);
 	requestParams.value.StartTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[0]; // 生成时间
 	requestParams.value.EndTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[1];
 	Reflect.deleteProperty(requestParams.value, 'crTime'); // 删除无用的参数
 	departmentTopTenNew(requestParams.value)
 		.then((res: any) => {
-			columns.value = res.result.list?.map((item: any) => {
+			let columns = res.result.list?.map((item: any) => {
 				return {
 					prop: item.dicDataName,
 					label: item.dicDataName,
 					align: 'center',
+					field: item.dicDataName,
+					title: item.dicDataName,
 					minWidth: 90,
+					sortable: true,
 				};
 			});
-			columns.value.unshift(
+			columns.unshift(
 				{
 					prop: '省一级热点名称',
 					label: '省一级热点名称',
+					field: '省一级热点名称',
+					title: '省一级热点名称',
 					minWidth: 90,
 					align: 'center',
 				},
 				{
 					prop: '有效受理量',
 					label: '有效受理量',
+					field: '有效受理量',
+					title: '有效受理量',
 					minWidth: 90,
+					sortable: true,
 					align: 'center',
 				}
 			);
+			gridOptions.columns = columns;
 			// 计算横轴小计
-			state.tableData = res.result?.data;
+			gridOptions.data = res.result?.data;
 			state.loading = false;
+			gridOptions.loading = false;
 		})
 		.catch(() => {
 			state.loading = false;
+			gridOptions.loading = false;
 		});
 };
 /** 重置按钮操作 */

+ 58 - 46
src/views/statistics/order/detailDispatch.vue

@@ -1,39 +1,72 @@
 <template>
   <div class="statistics-order-detail-dispatch-container layout-padding">
     <div class="layout-padding-auto layout-padding-view pd20">
-      <ProTable
-        ref="proTableRef"
-        :columns="columns"
-        :data="state.tableData"
-        @updateTable="queryList"
-        :loading="state.loading"
-        :total="state.total"
-        v-model:page-index="state.queryParams.PageIndex"
-        v-model:page-size="state.queryParams.PageSize"
-      >
-        <template #isProvince="{ row }">
-          <span>{{ row.order?.isProvince ? '省工单' : '市工单' }}</span>
-        </template>
-        <template #title="{ row }">
-          <order-detail :order="row" @updateList="queryList">{{ row?.title }}</order-detail>
-        </template>
-      </ProTable>
+			<vxe-toolbar
+				ref="toolbarRef"
+				:loading="state.loading"
+				custom
+				:refresh="{
+					queryMethod: handleQuery,
+				}"
+			>
+			</vxe-toolbar>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-table
+					border
+					:loading="state.loading"
+					:data="state.tableData"
+					:column-config="{ resizable: true }"
+					:row-config="{ isCurrent: true, isHover: true, height: 30, useKey: true }"
+					ref="tableRef"
+					height="auto"
+					auto-resize
+					show-overflow
+					:scrollY="{ enabled: true, gt: 20, mode: 'wheel' }"
+					id="statisticsOrderDetailDispatch"
+					:custom-config="{ storage: true }"
+				>
+					<vxe-column field="no" title="工单编码" width="140"></vxe-column>
+					<vxe-column field="isProvinceText" title="省/市工单" width="100"></vxe-column>
+					<vxe-column field="currentStepName" title="当前节点" width="120"></vxe-column>
+					<vxe-column field="statusText" title="工单状态" width="100"></vxe-column>
+					<vxe-column field="title" title="工单标题" min-width="200">
+						<template #default="{ row }">
+							<order-detail :order="row" @updateList="queryList">{{ row.title }}</order-detail>
+						</template>
+					</vxe-column>
+					<vxe-column field="creationTime" title="受理时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column field="acceptType" title="受理类型" width="100"></vxe-column>
+					<vxe-column field="sourceChannel" title="来源渠道" width="110"></vxe-column>
+					<vxe-column field="hotspotName" title="热点分类" width="150"></vxe-column>
+					<vxe-column field="acceptorName" title="受理人" width="120"></vxe-column>
+				</vxe-table>
+			</div>
+			<pagination
+				@pagination="queryList"
+				:total="state.total"
+				v-model:current-page="state.queryParams.PageIndex"
+				v-model:page-size="state.queryParams.PageSize"
+				:disabled="state.loading"
+			/>
     </div>
   </div>
 </template>
 
 <script setup lang="tsx" name="statisticsOrderDetailDispatch">
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
-import { FormInstance } from "element-plus";
 import { formatDate } from '@/utils/formatTime';
-import { departmentDispatchDetail } from "@/api/statistics/order";
+import {  departmentDispatchDetail } from '@/api/statistics/order';
 import {useRoute} from "vue-router";
 
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
 
 // 定义变量内容
-const ruleFormRef = ref<RefType>(); // 表单ref
 const state = reactive({
   queryParams: {
     // 查询条件
@@ -47,25 +80,6 @@ const state = reactive({
   total: 0, // 总数
 });
 
-const proTableRef = ref<RefType>(); // 表格ref
-// 表格配置项
-const columns = ref<any[]>([
-  { prop: 'no', label: '工单编码', minWidth: 140 },
-  { prop: 'isProvince', label: '省/市工单', minWidth: 90 },
-  { prop: 'title', label: '工单标题', minWidth: 200 },
-  { prop: 'currentStepName', label: '当前节点', minWidth: 120 },
-  {
-    prop: 'startTime',
-    label: '受理时间',
-    width: 160,
-    render: (scope) => {
-      return <span>{formatDate(scope.row.startTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-    },
-  },
-  { prop: 'acceptType', label: '受理类型', minWidth: 100 },
-  { prop: 'sourceChannel', label: '来源渠道', minWidth: 100  },
-  { prop: 'hotspotName', label: '热点分类', minWidth: 150 }
-]);
 /** 搜索按钮操作 */
 const handleQuery = () => {
   state.queryParams.PageIndex = 1;
@@ -95,14 +109,12 @@ const queryList = () => {
       state.loading = false;
     });
 };
-
-/** 重置按钮操作 */
-const resetQuery = (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  formEl.resetFields();
-  queryList();
-};
+const toolbarRef = ref<RefType>();
+const tableRef = ref<RefType>();
 onMounted(() => {
   queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
 });
 </script>

+ 82 - 53
src/views/statistics/order/detailSource.vue

@@ -22,37 +22,22 @@
           </el-form-item>
         </el-form>
       </div>
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
-				@updateTable="queryList"
-				:loading="state.loading"
-				border
-				:pagination="false"
-				:toolButton="['refresh', 'setting', 'exportAll']"
-				:exportMethod="orderSourceListExport"
-				:exportParams="requestParams"
-				show-summary
-				isSpecialExport
-				:key="Math.random()"
-				@updateColSetting="updateColSetting"
-			>
-			</ProTable>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-grid v-bind="gridOptions"> </vxe-grid>
+			</div>
 		</div>
 	</div>
 </template>
 <script setup lang="tsx" name="statisticsOrderDetailSource">
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import { FormInstance } from 'element-plus';
-import { orderSourceList, orderSourceListExport } from '@/api/statistics/order';
+import { departmentUnsatisfiedExport, orderSourceList, orderSourceListExport } from '@/api/statistics/order';
 import { defaultDate } from '@/utils/constants';
 import { useRouter } from 'vue-router';
 import Other from '@/utils/other';
+import XEUtils from 'xe-utils';
 
 const StatisticalTime = defineAsyncComponent(() => import('@/components/StatisticalTime/index.vue')); // 日期类型选择组件
-// 表格配置项
-const columns = ref<any[]>([]);
 // 定义变量内容
 const ruleFormRef = ref<RefType>(); // 表单ref
 const state = reactive<any>({
@@ -70,33 +55,85 @@ const handleQuery = () => {
 	// state.queryParams.PageIndex = 1;
 	queryList();
 };
+const requestParams = ref<EmptyObjectType>({});
+const gridOptions = reactive<any>({
+	loading: false,
+	border: true,
+	showOverflow: true,
+	printConfig: {},
+	columnConfig: {
+		resizable: true,
+	},
+	scrollY: {
+		enabled: true,
+		gt: 20,
+		mode: 'wheel',
+	},
+	toolbarConfig: {
+		zoom: true,
+		custom: true,
+		refresh: {
+			queryMethod: () => {
+				queryList();
+			},
+		},
+		tools:[
+			{ toolRender: { name: 'exportAll' } }
+		]
+	},
+	customConfig: {
+		storage: true
+	},
+	id: 'statisticsOrderDetailSource',
+	rowConfig: { isHover: true, height: 30,isCurrent:true,useKey:true },
+	height: 'auto',
+	columns: [],
+	data: [],
+	showFooter: true,
+	footerMethod: ({ columns, data }) => {
+		return [
+			columns.map((column: any, columnIndex: number) => {
+				if (columnIndex === 0) {
+					return '合计';
+				}
+				return XEUtils.sum(data, column.property);
+			}),
+		];
+	},
+	params:{
+		exportMethod: orderSourceListExport, exportParams: requestParams,isSpecialExport:true
+	}
+});
 /** 获取列表 */
-const requestParams = ref({});
 const queryList = async () => {
 	state.loading = true;
+	gridOptions.loading = true;
 	try {
 		requestParams.value = Other.deepClone(state.queryParams);
 		requestParams.value.StartTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[0];
 		requestParams.value.EndTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[1];
 		Reflect.deleteProperty(requestParams.value, 'crTime');
 		const res = await orderSourceList(requestParams.value);
-		columns.value = res.result.titleData?.map((item: any) => {
+		let columns = res.result.titleData?.map((item: any) => {
 			return {
-				prop: item.key,
-				label: item.value,
+				field: item.key,
+				title: item.value,
 				align: 'center',
-				minWidth: 90,
-				render: (scope) => {
-					return (
-						<el-button type="primary" link onClick={() => linkDetail(scope)}>
-							{scope.row[item.key]}
-						</el-button>
-					);
-				},
+				minWidth: 125,
+				sortable:true,
+				slots: {
+					default (scope:any) {
+						return (
+							<el-button type="primary" onClick={() => linkDetail(scope)} link>
+								{scope.row[item.key]}
+							</el-button>
+						)
+					}
+				}
 			};
 		});
 		// 计算横轴小计
-		state.tableData = res.result?.item.map((item: any) => {
+	let tableData = res.result?.item.map((item: any) => {
 			let subtotal = 0;
 			for (let i of res.result.titleData) {
 				subtotal += item[i.key];
@@ -106,41 +143,33 @@ const queryList = async () => {
 				subtotal,
 			};
 		});
-		columns.value.unshift(
+		columns.unshift(
 			{
-				prop: 'Hour',
-				label: '日期',
 				align: 'center',
 				minWidth: 120,
 				fixed: 'left',
+				field: 'Hour',
+				title: '日期',
 			},
 			{
-				prop: 'subtotal',
-				label: '小计',
 				align: 'center',
+				field: 'subtotal',
+				title: '小计',
+				minWidth: 120,
+				fixed: 'left',
+				sortable:true
 			}
 		);
-		state.tableData = state.tableData.filter((item) => item.Hour !== '0');
+		gridOptions.columns = columns;
+		gridOptions.data = tableData.filter((item) => item.Hour !== '0');
 		state.loading = false;
+		gridOptions.loading = false;
 	} catch (e) {
 		state.loading = false;
+		gridOptions.loading = false;
 		console.log(e);
 	}
 };
-// 列设置更新 列更新后需要重新计算小计
-const updateColSetting = () => {
-	// 更新列设置后 需要计算展示的列的小计
-	// 获取columns.value中isShow为true的行 并且计算小计
-	/*	for (let i of state.tableData) {
-		i.subtotal = 0;
-		for (let j of columns.value) {
-			if (j.isShow && !['Hour', 'subtotal'].includes(j.prop)) {
-				// 计算的时候不计算日期和小计
-				i.subtotal += i[j.prop];
-			}
-		}
-	}*/
-};
 /** 重置按钮操作 */
 const statisticalTimeRef = ref<RefType>();
 const resetQuery = (formEl: FormInstance | undefined) => {

+ 91 - 89
src/views/statistics/order/dispatch.vue

@@ -1,40 +1,21 @@
 <template>
   <div class="statistics-order-dispatch-container layout-padding">
     <div class="layout-padding-auto layout-padding-view pd20">
-      <ProTable
-        ref="proTableRef"
-        :columns="columns"
-        :data="state.tableData"
-        @updateTable="queryList"
-        :loading="state.loading"
-        show-summary
-        border
-        :pagination="false"
-        :summary-method="getSummaries"
-				:toolButton="['refresh', 'setting', 'exportAll']"
-				:exportMethod="departmentDispatchExport"
-				:exportParams="requestParams"
-      >
-        <template #table-search>
-          <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent inline>
-						<el-form-item prop="crTime">
-							<statistical-time v-model="state.queryParams.crTime" @change="handleQuery" ref="statisticalTimeRef" :disabled="state.loading"/>
-						</el-form-item>
-            <el-form-item label="派单员" prop="UserName">
-              <el-input v-model="state.queryParams.UserName" placeholder="派单员姓名" clearable @keyup.enter="handleQuery" class="keyword-input" />
-            </el-form-item>
-            <el-form-item>
-              <el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
-              <el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.loading">
-                <SvgIcon name="ele-Refresh" class="mr5" />重置
-              </el-button>
-            </el-form-item>
-          </el-form>
-        </template>
-				<template #description>
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent inline>
+				<el-form-item prop="crTime">
+					<statistical-time v-model="state.queryParams.crTime" @change="handleQuery" ref="statisticalTimeRef" :disabled="state.loading"/>
+				</el-form-item>
+				<el-form-item label="派单员" prop="UserName">
+					<el-input v-model="state.queryParams.UserName" placeholder="派单员姓名" clearable @keyup.enter="handleQuery" class="keyword-input" />
+				</el-form-item>
+				<el-form-item>
+					<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+					<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.loading">
+						<SvgIcon name="ele-Refresh" class="mr5" />重置
+					</el-button>
 					<el-popover :width="500" trigger="click">
 						<template #reference>
-							<el-button circle title="口径说明"><SvgIcon name="ele-QuestionFilled" /></el-button>
+							<el-button type="primary" title="口径说明"><SvgIcon name="ele-QuestionFilled" class="mr5"/>口径说明</el-button>
 						</template>
 						<el-descriptions title="" :column="1" border style="max-height: 400px; overflow: auto">
 							<el-descriptions-item label="派单人员">已向部门派单的工作人员</el-descriptions-item>
@@ -43,8 +24,65 @@
 							<el-descriptions-item label="重办信件量">重办的工单数量</el-descriptions-item>
 						</el-descriptions>
 					</el-popover>
-				</template>
-      </ProTable>
+				</el-form-item>
+			</el-form>
+			<vxe-toolbar
+				ref="toolbarRef"
+				:loading="state.loading"
+				custom
+				:refresh="{
+					queryMethod: handleQuery,
+				}"
+				:tools="[{ toolRender: { name: 'exportAll' } }]"
+			>
+			</vxe-toolbar>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-table
+					border
+					:loading="state.loading"
+					:data="state.tableData"
+					:column-config="{ resizable: true }"
+					:row-config="{ isCurrent: true, isHover: true, height: 30,useKey:true }"
+					ref="tableRef"
+					height="auto"
+					auto-resize
+					show-overflow
+					:scrollY="{ enabled: true, gt: 20 ,mode: 'wheel' }"
+					id="statisticsOrderDispatch"
+					:custom-config="{
+						storage: true,
+					}"
+					showHeaderOverflow
+					:params="{ exportMethod: departmentDispatchExport, exportParams: requestParams }"
+					show-footer
+					:footer-method="footerMethod"
+				>
+					<vxe-column field="userName" title="派单人员"></vxe-column>
+					<vxe-column field="sendOrderNum" title="派单量" sortable>
+						<template #default="scope">
+							<el-button type="primary" link @click="linkDetail(scope)">
+								{{ scope.row.sendOrderNum }}
+							</el-button>
+						</template>
+					</vxe-column>
+					<vxe-column field="noSendOrderNum" title="待派单件" sortable>
+						<template #default="scope">
+							<el-button type="primary" link @click="linkDetail(scope)">
+								{{ scope.row.noSendOrderNum }}
+							</el-button>
+						</template>
+					</vxe-column>
+					<vxe-column field="reSendOrderNum" title="重办信件" sortable>
+						<template #default="scope">
+							<el-button type="primary" link @click="linkDetail(scope)">
+								{{ scope.row.reSendOrderNum }}
+							</el-button>
+						</template>
+					</vxe-column>
+					<vxe-column field="chainRate" title="派单准确率">
+					</vxe-column>
+				</vxe-table>
+			</div>
     </div>
   </div>
 </template>
@@ -54,34 +92,9 @@ import { FormInstance } from 'element-plus';
 import { departmentDispatch, departmentDispatchExport } from '@/api/statistics/order';
 import { defaultDate } from "@/utils/constants";
 import { useRouter } from "vue-router";
+import XEUtils from 'xe-utils';
 
 const StatisticalTime = defineAsyncComponent(() => import('@/components/StatisticalTime/index.vue')); // 日期类型选择组件
-// 表格配置项
-const columns = ref<any[]>([
-  { prop: 'userName', label: '派单人员', align: 'center' },
-  { prop: 'sendOrderNum', label: '派单量', align: 'center', sortable: true ,render: (scope) => {
-      return (
-        <el-button type="primary" link onClick={() => linkDetail(scope)}>
-          {scope.row.sendOrderNum}
-        </el-button>
-      );
-    },},
-  { prop: 'noSendOrderNum', label: '待派单件', align: 'center', sortable: true,render: (scope) => {
-      return (
-        <el-button type="primary" link onClick={() => linkDetail(scope)}>
-          {scope.row.noSendOrderNum}
-        </el-button>
-      );
-    }, },
-  { prop: 'reSendOrderNum', label: '重办信件', align: 'center', sortable: true,render: (scope) => {
-      return (
-        <el-button type="primary" link onClick={() => linkDetail(scope)}>
-          {scope.row.reSendOrderNum}
-        </el-button>
-      );
-    }, },
-  { prop: 'chainRate', label: '派单准确率', align: 'center' },
-]);
 // 定义变量内容
 const ruleFormRef = ref<RefType>(); // 表单ref
 const state = reactive<any>({
@@ -127,35 +140,6 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 	statisticalTimeRef.value.reset();
   queryList();
 }
-// 合计
-const getSummaries = (param: any) => {
-  const { columns, data } = param;
-  const sums: string[] = [];
-  columns.forEach((column: { property: string }, index: number) => {
-    if (index === 0) {
-      sums[index] = '合计';
-      return;
-    }
-    const values = data.map((item: { [x: string]: any }) => Number(item[column.property]));
-    if (['name'].includes(column.property)) {
-      //百分比不能计算
-      sums[index] = '';
-      return '';
-    } else if (!values.every((value: unknown) => Number.isNaN(value))) {
-      sums[index] = `${values.reduce((prev: any, curr: any) => {
-        const value = Number(curr);
-        if (!Number.isNaN(value)) {
-          return prev + curr;
-        } else {
-          return prev;
-        }
-      }, 0)}`;
-    } else {
-      sums[index] = ' ';
-    }
-  });
-  return sums;
-};
 // 查看明细
 const router = useRouter();
 const linkDetail = (scope: any) => {
@@ -169,7 +153,25 @@ const linkDetail = (scope: any) => {
     },
   });
 };
+// 计算合计
+const footerMethod = ({ columns, data }) => {
+	return [
+		columns.map((column: any, columnIndex: number) => {
+			if (columnIndex === 0) {
+				return '合计';
+			}
+			if (['sendOrderNum', 'noSendOrderNum', 'reSendOrderNum'].includes(column.property)) {
+				return XEUtils.sum(data, column.property);
+			}
+		}),
+	];
+};
+const toolbarRef = ref<RefType>();
+const tableRef = ref<RefType>();
 onMounted(() => {
   queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
 });
 </script>

+ 95 - 53
src/views/statistics/order/hotspotSubclass.vue

@@ -1,60 +1,71 @@
 <template>
 	<div class="statistics-order-hotspot-subclass-container layout-padding">
 		<div class="layout-padding-auto layout-padding-view pd20">
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
-				@updateTable="queryList"
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent inline>
+				<el-form-item prop="crTime">
+					<statistical-time v-model="state.queryParams.crTime" @change="handleQuery" ref="statisticalTimeRef" :disabled="state.loading" />
+				</el-form-item>
+				<el-form-item prop="TypeId" label="来电主体">
+					<el-select v-model="state.queryParams.TypeId" placeholder="请选择来电主体" @change="handleQuery">
+						<el-option :value="0" label="全部" />
+						<el-option :value="1" label="市民" />
+						<el-option :value="2" label="企业" />
+					</el-select>
+				</el-form-item>
+				<el-form-item>
+					<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+					<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.loading">
+						<SvgIcon name="ele-Refresh" class="mr5" />重置
+					</el-button>
+				</el-form-item>
+			</el-form>
+			<vxe-toolbar
+				ref="toolbarRef"
 				:loading="state.loading"
-				border
-				:pagination="false"
-				row-key="hotspotCode"
-				lazy
-				:load="load"
-				:tree-props="{ children: 'children', hasChildren: 'hasChild' }"
-				show-summary
-				:toolButton="['refresh', 'setting', 'exportAll']"
-				:exportMethod="departmentHotSmallExport"
-				:exportParams="requestParams"
+				custom
+				:refresh="{
+			queryMethod: handleQuery,
+			}"
+				:tools="[{ toolRender: { name: 'exportAll' } }]"
 			>
-				<template #table-search>
-					<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent inline>
-						<el-form-item prop="crTime">
-							<statistical-time v-model="state.queryParams.crTime" @change="handleQuery" ref="statisticalTimeRef" :disabled="state.loading" />
-						</el-form-item>
-						<el-form-item prop="TypeId" label="来电主体">
-							<el-select v-model="state.queryParams.TypeId" placeholder="请选择来电主体" @change="handleQuery">
-								<el-option :value="0" label="全部" />
-								<el-option :value="1" label="市民" />
-								<el-option :value="2" label="企业" />
-							</el-select>
-						</el-form-item>
-						<el-form-item>
-							<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
-							<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.loading">
-								<SvgIcon name="ele-Refresh" class="mr5" />重置
-							</el-button>
-						</el-form-item>
-					</el-form>
-				</template>
-			</ProTable>
+			</vxe-toolbar>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-table
+					border
+					:loading="state.loading"
+					:data="state.tableData"
+					:column-config="{ resizable: true }"
+					:row-config="{ isCurrent: true, isHover: true, height: 30,useKey:true }"
+					ref="tableRef"
+					height="auto"
+					auto-resize
+					show-overflow
+					:scrollY="{ enabled: true, gt: 0, mode: 'wheel' }"
+					id="statisticsOrderHotspotSubclass"
+					:custom-config="{ storage: true }"
+					:params="{ exportMethod: departmentHotSmallExport, exportParams: requestParams }"
+					showHeaderOverflow
+					show-footer
+					:footer-method="footerMethod"
+					:tree-config="treeConfig"
+				>
+					<vxe-column field="hotspotName" title="热点名称"  tree-node></vxe-column>
+					<vxe-column field="sumCount" title="分类统计"></vxe-column>
+				</vxe-table>
+			</div>
 		</div>
 	</div>
 </template>
 <script setup lang="tsx" name="statisticsOrderHotspotSubclass">
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import { FormInstance } from 'element-plus';
-import { departmentHotSmall, departmentHotSmallExport } from '@/api/statistics/order';
+import {  departmentHotSmall, departmentHotSmallExport } from '@/api/statistics/order';
 import { defaultDate } from '@/utils/constants';
 import Other from '@/utils/other';
 import { formatDate } from '@/utils/formatTime';
+import XEUtils from 'xe-utils';
 
 const StatisticalTime = defineAsyncComponent(() => import('@/components/StatisticalTime/index.vue')); // 日期类型选择组件
-const columns = ref<any>([
-	{ prop: 'hotspotName', label: '热点名称' },
-	{ prop: 'sumCount', label: '分类统计', width: 120 },
-]); // 表头
 // 定义变量内容
 const ruleFormRef = ref<RefType>(); // 表单ref
 const state = reactive<any>({
@@ -103,20 +114,51 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 	statisticalTimeRef.value.reset();
 	queryList();
 };
-// 懒加载
-const load = (row: any, treeNode: unknown, resolve: (date: any[]) => void) => {
-	requestParams.value = Other.deepClone(state.queryParams);
-	requestParams.value.StartTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[0];
-	requestParams.value.EndTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[1];
-	Reflect.deleteProperty(requestParams.value, 'crTime');
-	requestParams.value.HotspotCode = row.hotspotCode;
-	departmentHotSmall(requestParams.value)
-		.then((res: any) => {
-			resolve(res.result ?? []);
-		})
-		.catch(() => {});
+const treeConfig = reactive({
+	transform: true,
+	rowField: 'hotspotCode',
+	parentField: 'parentId',
+	lazy: true,
+	hasChild: 'hasChild',
+	loadMethod({ row }) {
+		// 异步加载子节点
+		return fetchChildListApi(row);
+	},
+});
+const fetchChildListApi = (row: any) => {
+	return new Promise((resolve) => {
+		const request =  Other.deepClone(state.queryParams);
+		request.StartTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[0];
+		request.EndTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[1];
+		Reflect.deleteProperty(request, 'crTime');
+		request.HotspotCode = row.hotspotCode;
+		departmentHotSmall(request)
+			.then((res: any) => {
+				resolve(res.result ?? []);
+			})
+			.catch(() => {});
+	});
+};
+// 计算合计
+const footerMethod = ({ columns, data }) => {
+	return [
+		columns.map((column: any, columnIndex: number) => {
+			if (columnIndex === 0) {
+				return '合计';
+			}
+			if (['sumCount'].includes(column.property)) {
+				return XEUtils.sum(data, column.property);
+			}
+			return null;
+		}),
+	];
 };
+const toolbarRef = ref<RefType>();
+const tableRef = ref<RefType>();
 onMounted(() => {
 	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
 });
 </script>

+ 52 - 23
src/views/statistics/order/source.vue

@@ -25,21 +25,9 @@
 					<v-chart class="chart" :option="option" :loading="state.loading" autoresize />
 				</el-col>
 				<el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
-					<ProTable
-						ref="proTableRef"
-						:columns="columns"
-						:data="state.tableData"
-						@updateTable="queryList"
-						:loading="state.loading"
-						:pagination="false"
-						border
-						:tool-button="false"
-						max-height="70vh"
-						:toolButton="['refresh', 'exportAll']"
-						:exportMethod="orderSourceExport"
-						:exportParams="requestParams"
-					>
-					</ProTable>
+					<div style="height: 70vh">
+							<vxe-grid v-bind="gridOptions"> </vxe-grid>
+					</div>
 				</el-col>
 			</el-row>
 		</el-card>
@@ -50,16 +38,11 @@ import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import { FormInstance } from 'element-plus';
 import { defaultDate } from '@/utils/constants';
 import Other from '@/utils/other';
-import { orderSource, orderSourceExport } from '@/api/statistics/order';
+import { departmentTopTenExport, orderSource, orderSourceExport } from '@/api/statistics/order';
 import { useRouter } from 'vue-router';
+import XEUtils from 'xe-utils';
 
 const StatisticalTime = defineAsyncComponent(() => import('@/components/StatisticalTime/index.vue')); // 日期类型选择组件
-// 表格配置项
-const columns = ref<any[]>([
-	{ prop: 'source', label: '信件来源', align: 'center' },
-	{ prop: 'num', label: '数量', align: 'center' },
-	{ prop: 'rateText', label: '占比', align: 'center' },
-]);
 // 定义变量内容
 const ruleFormRef = ref<RefType>(); // 表单ref
 const state = reactive<any>({
@@ -79,11 +62,54 @@ const handleQuery = () => {
 	// state.queryParams.PageIndex = 1;
 	queryList();
 };
+
+const requestParams = ref<EmptyObjectType>({});
+const gridOptions = reactive<any>({
+	loading: false,
+	border: true,
+	showOverflow: true,
+	printConfig: {},
+	columnConfig: {
+		resizable: true,
+	},
+	scrollY: {
+		enabled: true,
+		gt: 20,
+		mode: 'wheel',
+	},
+	toolbarConfig: {
+		zoom: true,
+		custom: true,
+		refresh: {
+			queryMethod: () => {
+				queryList();
+			},
+		},
+		tools: [{ toolRender: { name: 'exportAll' } }],
+	},
+	customConfig: {
+		storage: true,
+
+	},
+	id: 'statisticsOrderSource',
+	rowConfig: { isHover: true, height: 30, isCurrent: true,useKey:true },
+	height: 'auto',
+	columns: [
+		{ field: 'source', title: '信件来源'},
+		{ field: 'num', title: '数量'},
+		{ field: 'rateText', title: '占比'},
+	],
+	data: [],
+	params: {
+		exportMethod: orderSourceExport,
+		exportParams: requestParams,
+	},
+});
 /** 获取列表 */
 const dataTable = ref([]);
-const requestParams = ref<EmptyObjectType>({});
 const queryList = () => {
 	state.loading = true;
+	gridOptions.loading = true;
 	requestParams.value = Other.deepClone(state.queryParams);
 	requestParams.value.StartTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[0];
 	requestParams.value.EndTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[1];
@@ -91,6 +117,7 @@ const queryList = () => {
 	orderSource(requestParams.value)
 		.then((res: any) => {
 			state.tableData = res.result;
+			gridOptions.data = res.result;
 			const legendData = state.tableData
 				.map((item: any) => {
 					return item.source;
@@ -107,9 +134,11 @@ const queryList = () => {
 				.filter((item: any) => item.name !== '合计');
 			setOption(legendData, dataTable.value);
 			state.loading = false;
+			gridOptions.loading = false;
 		})
 		.catch(() => {
 			state.loading = false;
+			gridOptions.loading = false;
 		});
 };
 /** 重置按钮操作 */

+ 5 - 4
src/views/statistics/order/visitDiscontent.vue

@@ -57,7 +57,8 @@ const gridOptions = reactive<any>({
 	},
 	scrollY: {
 		enabled: true,
-		gt: 0,
+		gt: 20,
+		mode: 'wheel',
 	},
 	toolbarConfig: {
 		zoom: true,
@@ -75,7 +76,7 @@ const gridOptions = reactive<any>({
 		storage: true
 	},
 	id: 'statisticsVisitDiscontent',
-	rowConfig: { isHover: true, height: 30,isCurrent:true },
+	rowConfig: { isHover: true, height: 30,isCurrent:true,useKey:true },
 	height: 'auto',
 	columns: [],
 	data: [],
@@ -121,7 +122,7 @@ const queryList = () => {
 					slots: {
 						default (scope:any) {
 							return (
-								<el-button type="primary" onClick={() => handleDetail(scope)} link>
+								<el-button type="primary" onClick={() => linkDetail(scope)} link>
 									{scope.row[item.dicDataValue]}
 								</el-button>
 							)
@@ -166,7 +167,7 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 };
 // 查看详情
 const router = useRouter();
-const handleDetail = (scope: any) => {
+const linkDetail = (scope: any) => {
 	const columnKey = Object.keys(scope.row).find((item) => item === scope.column.property);
 	const startTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[0];
 	const endTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[1];