Selaa lähdekoodia

reactor:对接综合查询导出;

zhangchong 11 kuukautta sitten
vanhempi
commit
d1dc0caed5

+ 19 - 3
src/api/business/order.ts

@@ -220,7 +220,6 @@ export const provinceReturn = (data: object) => {
 		data
 	});
 }
-
 /**
  * @description 导出交办单
  * @param {object} data
@@ -229,12 +228,29 @@ export const exportJbOrder = (data: object) => {
 	return request({
 		url: `/api/v1/ExportWord/order_submission_form`,
 		method: 'post',
-		responseType: 'blob', //注意
+		responseType: 'blob',
 		data,
-		headers: {            //注意
+		headers: {
 			'Content-Type': 'application/json; application/octet-stream'
 		}
 	},{
 		reduce_data_format:false
 	});
+}
+/**
+ * @description 工单导出 综合查询
+ * @param {object} data
+ */
+export const exportOrder = (data: object) => {
+	return request({
+		url: `/api/v1/Order/order/export`,
+		method: 'post',
+		responseType: 'blob',
+		data,
+		headers: {
+			'Content-Type': 'application/json; application/octet-stream'
+		}
+	},{
+		reduce_data_format:false
+	})
 }

+ 2 - 0
src/api/public/file.ts

@@ -47,5 +47,7 @@ export const fileDownload = (params: object) => {
 		method: 'get',
 		responseType: 'blob',
 		params,
+	},{
+		reduce_data_format:false
 	});
 };

+ 18 - 0
src/api/public/wex.ts

@@ -181,4 +181,22 @@ export const switchMode = (data?: object) => {
 		method: 'post',
 		data,
 	});
+};
+/**
+ * @description 话后整理开始
+ */
+export const startAfterCall = () => {
+	return request({
+		url: `/api/v1/IPPbx/callennd-arrange-begin`,
+		method: 'get',
+	});
+};
+/**
+ * @description 话后整理结束
+ */
+export const endAfterCall = () => {
+	return request({
+		url: `/api/v1/IPPbx/callend-arrange-end`,
+		method: 'get',
+	});
 };

+ 5 - 5
src/components/OrderDetail/index.vue

@@ -370,7 +370,7 @@
 								{{ item.orgNoSatisfiedReason?.map((item) => item.value).join(',') }}
 							</el-form-item>
 						</el-col>
-<!--						<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+						<!--						<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
 							<el-form-item label="部门办件态度">
 								{{ item.orgHandledAttitude?.value }}
 							</el-form-item>
@@ -458,7 +458,7 @@
 					>办 理</el-button
 				>
 				<!-- 流程结束之后不展示补充按钮 -->
-<!--        <el-button type="primary" @click="onSupply" :loading="state.loading" v-if="[0].includes(state.workflow.status)"
+				<!--        <el-button type="primary" @click="onSupply" :loading="state.loading" v-if="[0].includes(state.workflow.status)"
           >补 充</el-button
         >-->
 				<!--				<el-button type="primary" @click="onRevoke" :loading="state.loading">撤 销</el-button>-->
@@ -690,9 +690,9 @@ const closeDialog = () => {
 };
 // 查看录音文件
 const playRecordRef = ref<RefType>();
-const recordFile = (obj:any) => {
-  const fileName = `工单编号-${obj.no} 录音文件`
-	playRecordRef.value.openDialog(import.meta.env.VITE_RECORD_PREFIX + obj.recordingAbsolutePath,fileName,obj.recordingAbsolutePath);
+const recordFile = (obj: any) => {
+	const fileName = `工单编号-${obj.no} 录音文件`;
+	playRecordRef.value.openDialog(import.meta.env.VITE_RECORD_PREFIX + obj.recordingAbsolutePath, fileName, obj.recordingAbsolutePath);
 };
 // 电话外呼
 const callPhone = (number: number | string) => {

+ 25 - 3
src/layout/navBars/breadcrumb/telControl.vue

@@ -523,6 +523,8 @@ import {
 	queryBlacklist,
 	getTelStatus,
 	switchMode,
+	startAfterCall,
+	endAfterCall,
 } from '@/api/public/wex';
 import signalR from '@/utils/signalR';
 import { Local } from '@/utils/storage';
@@ -816,6 +818,24 @@ const onConnect = () => {
 const sendMsg = (msg: any) => {
 	signalR.SR.invoke('SendSeatState', { telNo: telStatusInfo.value.telsNo, state: msg });
 };
+// 业务系统记录话后整理开始
+const onBeginAcw = async () => {
+	try {
+		const res: any = await startAfterCall();
+    console.log(res, '业务系统记录话后整理开始');
+	} catch (err) {
+		console.log(err);
+	}
+};
+// 业务系统记录话后整理结束
+const onEndAcw = async () => {
+	try {
+		const res: any = await endAfterCall();
+		console.log(res, '业务系统记录话后整理结束');
+	} catch (err) {
+		console.log(err);
+	}
+};
 const router = useRouter();
 const talkDealTimer = ref<any>(null); // 话后整理定时器
 const pingTimer = ref<any>(null); // 心跳定时器
@@ -866,9 +886,8 @@ const onMessage = async (event: any) => {
 			useTelStatusStore.resetState();
 			console.log('呼叫中心:已签出');
 			ElMessage.success('签出成功');
-			clearInterval(pingTimer.value); // 清除心跳定时器
-			isReconnect.value = false; // 不需要重连
-			seatAssistOff();
+      seatAssistOff(); // 坐席助手关闭
+      stopReconnect(); // 停止重连
 		} else if (data.state == 'ready') {
 			if (currentTel.value.telModel === 2) {
 				// 外呼模式
@@ -976,9 +995,11 @@ const onMessage = async (event: any) => {
 						useTelStatusStore.setPhoneControlState(TelStates.dutyOn);
 						ola.go_ready(); // 示闲
 						console.log('呼叫中心:调用示闲');
+						onEndAcw(); // 挂机后整理结束
 						clearTimeout(talkDealTimer.value); // 清除话后整理定时器
 					}, time);
 					console.log('呼叫中心:话后整理中');
+					onBeginAcw(); // 挂机后整理开始
 					sendMsg('acw');
 				} else {
 					// 呼出直接调用示闲
@@ -1632,6 +1653,7 @@ const unTalkingDeal = () => {
 			useTelStatusStore.setPhoneControlState(TelStates.dutyOn);
 			ola.go_ready(); // 示闲
 			clearTimeout(talkDealTimer.value); // 清除话后整理定时器
+			onEndAcw(); // 挂机后整理结束
 			console.log('呼叫中心:调用示闲');
 		})
 		.catch(() => {});

+ 15 - 4
src/utils/tools.ts

@@ -1,4 +1,5 @@
 import axios from 'axios';
+import dayjs from "dayjs";
 
 /**
  * @description 防抖
@@ -169,20 +170,30 @@ export function downloadZip(res: any) {
  * @param res 文件流
  * @param filename 文件名
  */
-export function downloadFileByStream(res: Blob, filename: string) {
+export function downloadFileByStream(res: any, filename?: string) {
 	// 创建blob对象,解析流数据
-	const blob = new Blob([res], {
+	const blob = new Blob([res.data], {
 		// 设置返回的文件类型
 		// type: 'application/pdf;charset=UTF-8' 表示下载文档为pdf,如果是word则设置为word,excel为excel
-		type: res.type,
+		type: res.data.type,
 	});
 	// 这里就是创建一个a标签,等下用来模拟点击事件
 	const a = document.createElement('a');
-	// 兼容webkit浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
+	// 兼容webkit浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载  20240401000013
 	const URL = window.URL || window.webkitURL;
 	// 根据解析后的blob对象创建URL 对象
 	// 下载链接
 	a.href = URL.createObjectURL(blob);
+	if (!filename) {
+		const fileNameStr = res.headers['content-disposition']?.split(';')[2]?.split('filename*=')[1];
+		if(fileNameStr){
+			const index = fileNameStr.lastIndexOf("'");
+			const result = fileNameStr.substring(index + 1, fileNameStr.length);
+			filename = decodeURIComponent(result);
+		}else{
+			filename = dayjs().format('YYYYMMDDHHmmss'); // 如果没有文件名,则默认取当前时间
+		}
+	}
 	// 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf'
 	a.download = filename;
 	document.body.appendChild(a);

+ 126 - 82
src/views/business/delay/audit.vue

@@ -29,20 +29,12 @@
 				v-model:page-size="state.queryParams.PageSize"
 				:key="Math.random()"
 			>
-				<template #expiredStatus="{ row }">
+				<template #expiredStatusText="{ row }">
 					<span :class="'overdue-status-' + row.order?.expiredStatus" :title="row.order?.expiredStatusText"></span>
 				</template>
-				<template #isProvince="{ row }">
-					<span>{{ row.order?.isProvince ? '省工单' : '市工单' }}</span>
-				</template>
 				<template #title="{ row }">
 					<order-detail :order="row.order" @updateList="queryList">{{ row.order?.title }}</order-detail>
 				</template>
-				<template #employeeName="{ row }">
-					<span
-						>{{ row.order?.acceptorName }} <span v-if="row.order?.acceptorStaffNo">[{{ row.acceptorStaffNo }}]</span>
-					</span>
-				</template>
 				<!-- 表格操作 -->
 				<template #operation="{ row }">
 					<el-button link type="primary" @click="onDetail(row)" title="延期详情"> 延期详情 </el-button>
@@ -85,64 +77,126 @@ const ruleFormRef = ref<RefType>(); // 表单ref
 const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
-const columns = ref<any[]>([
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center',fixed: 'left',width: 80},
-	{ prop: 'no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
-	{ prop: 'title', label: '工单标题', width: 300 },
-	{ prop: 'delayStateText', label: '延期审批状态', width: 120 },
-	{
-		prop: 'order.startTime',
-		label: '受理时间',
-		width: 170,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.order?.startTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{ prop: 'employeeName', label: '受理人', width: 120 },
-	{ prop: 'order.hotspotName', label: '热点分类', width: 200 },
-	{ prop: 'order.acceptType', label: '受理类型', width: 150 },
-	{ prop: 'order.orgLevelOneName', label: '一级部门', width: 150 },
-	{ prop: 'order.actualHandleOrgName', label: '接办部门', width: 150 },
-	{
-		prop: 'order.actualHandleTime',
-		label: '接办时间',
-		width: 170,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.order?.actualHandleTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{
-		prop: 'creationTime',
-		label: '延期申请时间',
-		width: 170,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{ prop: 'creatorOrgName', label: '延期申请部门', width: 120 },
-	{ prop: 'creatorName', label: '延期申请人', width: 150 },
-	{ prop: 'delayNum', label: '延期申请时限', width: 120 },
-	{ prop: 'delayUnitText', label: '延期申请单位', width: 120 },
-	{ prop: 'delayReason', label: '申请理由', width: 120 },
-	{
-		prop: 'beforeDelay',
-		label: '申请前期满时间',
-		width: 170,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.beforeDelay, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{
-		prop: 'afterDelay',
-		label: '通过后期满时间',
-		width: 170,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.afterDelay, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{ prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
-]);
+const columns = ref<any[]>([]);
+const columnsTodo = [
+  { prop: 'order.expiredStatusText', label: '超期状态', align: 'center',fixed: 'left',width: 80},
+  { prop: 'order.no', label: '工单编码', width: 150 },
+  { prop: 'order.isProvinceText', label: '省/市工单', width: 100 },
+  { prop: 'order.title', label: '工单标题', width: 300 },
+  { prop: 'delayStateText', label: '延期审批状态', width: 120 },
+  {
+    prop: 'order.startTime',
+    label: '受理时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.order?.startTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  { prop: 'order.acceptorName', label: '受理人', width: 120 },
+  { prop: 'order.hotspotName', label: '热点分类', width: 200 },
+  { prop: 'order.acceptType', label: '受理类型', width: 150 },
+  { prop: 'order.orgLevelOneName', label: '一级部门', width: 150 },
+  { prop: 'order.actualHandleOrgName', label: '接办部门', width: 150 },
+  {
+    prop: 'order.actualHandleTime',
+    label: '接办时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.order?.actualHandleTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  {
+    prop: 'creationTime',
+    label: '延期申请时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  { prop: 'creatorOrgName', label: '延期申请部门', width: 120 },
+  { prop: 'creatorName', label: '延期申请人', width: 150 },
+  { prop: 'delayNum', label: '延期申请时限', width: 120 },
+  { prop: 'delayUnitText', label: '延期申请单位', width: 120 },
+  { prop: 'delayReason', label: '申请理由', width: 120 },
+  {
+    prop: 'beforeDelay',
+    label: '申请前期满时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.beforeDelay, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  {
+    prop: 'afterDelay',
+    label: '通过后期满时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.afterDelay, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  { prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
+];
+const columnsDone = [
+  // 已办
+  { prop: 'order.expiredStatusText', label: '超期状态', align: 'center',fixed: 'left',width: 80},
+  { prop: 'order.no', label: '工单编码', width: 150 },
+  { prop: 'order.isProvinceText', label: '省/市工单', width: 100 },
+  { prop: 'order.title', label: '工单标题', width: 300 },
+  { prop: 'currentStepName', label: '当前节点', width: 150 },
+  { prop: 'actualHandlerName', label: '当前审批人', width: 150 },
+  { prop: 'delayStateText', label: '延期审批状态', width: 120 },
+  {
+    prop: 'order.startTime',
+    label: '受理时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.order?.startTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  { prop: 'employeeName', label: '受理人', width: 120 },
+  { prop: 'order.hotspotName', label: '热点分类', width: 200 },
+  { prop: 'order.acceptType', label: '受理类型', width: 150 },
+  { prop: 'order.orgLevelOneName', label: '一级部门', width: 150 },
+  { prop: 'order.actualHandleOrgName', label: '接办部门', width: 150 },
+  {
+    prop: 'order.actualHandleTime',
+    label: '接办时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.order?.actualHandleTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  {
+    prop: 'creationTime',
+    label: '延期申请时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  { prop: 'creatorOrgName', label: '延期申请部门', width: 120 },
+  { prop: 'creatorName', label: '延期申请人', width: 150 },
+  { prop: 'delayNum', label: '延期申请时限', width: 120 },
+  { prop: 'delayUnitText', label: '延期申请单位', width: 120 },
+  { prop: 'delayReason', label: '申请理由', width: 120 },
+  {
+    prop: 'beforeDelay',
+    label: '申请前期满时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.beforeDelay, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  {
+    prop: 'afterDelay',
+    label: '通过后期满时间',
+    width: 170,
+    render: (scope) => {
+      return <span>{formatDate(scope.row.afterDelay, 'YYYY-mm-dd HH:MM:SS')}</span>;
+    },
+  },
+  { prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
+];
 // 手动查询,将页码设置为1
 const handleQuery = () => {
 	state.queryParams.PageIndex = 1;
@@ -153,21 +207,11 @@ const queryList = () => {
 	state.loading = true;
 	delayList(state.queryParams)
 		.then((res: any) => {
-			const index = columns.value.findIndex((item) => item.prop === 'delayStateText');
-			if (state.queryParams.IsApply === 'true') {
-				if (!columns.value.find((item) => item.prop === 'actualHandleStepName')) {
-					columns.value.splice(
-						index,
-						0,
-						{ prop: 'actualHandleStepName', label: '当前节点', width: 150 },
-						{ prop: 'actualHandlerName', label: '当前审批人', width: 150 }
-					);
-				}
-			} else {
-				if (columns.value.find((item) => item.prop === 'actualHandleStepName')) {
-					columns.value = columns.value.filter((item) => item.prop !== 'actualHandleStepName' && item.prop !== 'actualHandlerName');
-				}
-			}
+      if (state.queryParams.IsApply === 'true') {
+        columns.value = columnsDone;
+      } else {
+        columns.value = columnsTodo;
+      }
 			state.tableData = res.result?.items ?? [];
 			state.total = res.result?.total ?? 0;
 			state.loading = false;

+ 6 - 13
src/views/business/delay/index.vue

@@ -30,20 +30,12 @@
 				v-model:page-index="state.queryParams.PageIndex"
 				v-model:page-size="state.queryParams.PageSize"
 			>
-				<template #expiredStatus="{ row }">
+				<template #expiredStatusText="{ row }">
 					<span :class="'overdue-status-' + row.order?.expiredStatus" :title="row.order?.expiredStatusText"></span>
 				</template>
-				<template #isProvince="{ row }">
-					<span>{{ row.order?.isProvince ? '省工单' : '市工单' }}</span>
-				</template>
 				<template #title="{ row }">
 					<order-detail :order="row.order" @updateList="queryList">{{ row.order?.title }}</order-detail>
 				</template>
-				<template #employeeName="{ row }">
-					<span
-						>{{ row.order?.acceptorName }} <span v-if="row.order?.acceptorStaffNo">[{{ row.order?.acceptorStaffNo }}]</span>
-					</span>
-				</template>
 				<!-- 表格操作 -->
 				<template #operation="{ row }">
 					<el-button link type="primary" @click="onDetail(row)" title="查看延期详情"> 延期详情 </el-button>
@@ -71,11 +63,12 @@ const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center',fixed: 'left',width: 80},
+	{ prop: 'expiredStatusText', label: '超期状态', align: 'center',fixed: 'left',width: 80},
 	{ prop: 'no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
+	{ prop: 'order.isProvinceText', label: '省/市工单', width: 100 },
 	{ prop: 'title', label: '工单标题', width: 300 },
-	{ prop: 'order.actualHandleStepName', label: '办理节点', width: 120 },
+	{ prop: 'currentStepName', label: '办理节点', width: 120 },
+  { prop: 'actualHandlerName', label: '审批人', width: 150 },
 	{ prop: 'delayStateText', label: '延期申请状态', width: 120 },
 	{
 		prop: 'order.startTime',
@@ -85,7 +78,7 @@ const columns = ref<any[]>([
 			return <span>{formatDate(scope.row.order?.startTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
 		},
 	},
-	{ prop: 'employeeName', label: '受理人', width: 120 },
+	{ prop: 'order.acceptorName', label: '受理人', width: 120 },
   { prop: 'order.hotspotName', label: '热点分类', width: 120 },
   { prop: 'order.acceptType', label: '受理类型', width: 120 },
   {prop: 'order.orgLevelOneName', label: '一级部门', width: 120 },

+ 63 - 28
src/views/business/discern/todo.vue

@@ -42,20 +42,12 @@
 				v-model:page-size="state.queryParams.PageSize"
 				:key="Math.random()"
 			>
-				<template #expiredStatus="{ row }">
+				<template #expiredStatusText="{ row }">
 					<span :class="'overdue-status-' + row.order?.expiredStatus" :title="row.order?.expiredStatusText"></span>
 				</template>
-				<template #isProvince="{ row }">
-					<span>{{ row.order?.isProvince ? '省工单' : '市工单' }}</span>
-				</template>
 				<template #title="{ row }">
 					<order-detail :order="row.order" @updateList="queryList">{{ row.order?.title }}</order-detail>
 				</template>
-				<template #acceptorName="{ row }">
-					<span
-						>{{ row.order?.acceptorName }} <span v-if="row.order?.acceptorStaffNo">[{{ row.order?.acceptorStaffNo }}]</span>
-					</span>
-				</template>
 				<!-- 表格操作 -->
 				<template #operation="{ row }">
 					<el-button link type="primary" @click="onDetail(row)" title="查看甄别详情"> 甄别详情 </el-button>
@@ -85,11 +77,65 @@ const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/
 const ruleFormRef = ref<RefType>(); // 表单ref
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
-const columns = ref<any[]>([
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center', fixed: 'left', width: 80 },
+const columns = ref<any[]>([]);
+const columnsTodo = [
+	{ prop: 'order.expiredStatusText', label: '超期状态', align: 'center', fixed: 'left', width: 80 },
+	{ prop: 'order.no', label: '工单编码', width: 150 },
+	{ prop: 'order.isProvinceText', label: '省/市工单', width: 100 },
+	{ prop: 'order.title', label: '工单标题', width: 300 },
+	{ prop: 'order.sourceChannel', label: '来源方式', width: 100 },
+	{ prop: 'order.acceptType', label: '受理类型', width: 150 },
+	{ prop: 'order.acceptorName', label: '受理人', width: 120 },
+	{ prop: 'order.orgLevelOneName', label: '一级部门', width: 150 },
+	{ prop: 'order.actualHandleOrgName', label: '接办部门', width: 150 },
+	{
+		prop: 'order.actualHandleTime',
+		label: '接办时间',
+		width: 170,
+		render: (scope) => {
+			return <span>{formatDate(scope.row.order?.actualHandleTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{
+		prop: 'order.startTime',
+		label: '受理时间',
+		width: 170,
+		render: (scope) => {
+			return <span>{formatDate(scope.row.order?.startTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{
+		prop: 'visit.visitTime',
+		label: '回访时间',
+		width: 170,
+		render: (scope) => {
+			return <span>{formatDate(scope.row.visit?.visitTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{
+		prop: 'creationTime',
+		label: '甄别申请时间',
+		width: 170,
+		render: (scope) => {
+			return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{ prop: 'creatorName', label: '甄别申请人', width: 120 },
+	{ prop: 'creatorOrgName', label: '甄别申请部门', width: 150 },
+	{ prop: 'typeDicName', label: '甄别申请类型', width: 120 },
+	{ prop: 'timeConsuminText', label: '发起甄别耗时', width: 120 },
+	{ prop: 'content', label: '甄别申请原因', width: 200 },
+	{ prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
+];
+const columnsDone = [
+	// 已办
+	{ prop: 'order.expiredStatusText', label: '超期状态', align: 'center', fixed: 'left', width: 80 },
 	{ prop: 'order.no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
-	{ prop: 'title', label: '工单标题', width: 300 },
+	{ prop: 'order.isProvinceText', label: '省/市工单', width: 100 },
+	{ prop: 'statusText', label: '甄别状态', width: 120 },
+	{ prop: 'actualHandleStepName', label: '当前节点', width: 150 },
+	{ prop: 'actualHandlerName', label: '当前审批人', width: 150 },
+	{ prop: 'order.title', label: '工单标题', width: 300 },
 	{ prop: 'order.sourceChannel', label: '来源方式', width: 100 },
 	{ prop: 'order.acceptType', label: '受理类型', width: 150 },
 	{ prop: 'order.acceptorName', label: '受理人', width: 120 },
@@ -133,7 +179,7 @@ const columns = ref<any[]>([
 	{ prop: 'timeConsuminText', label: '发起甄别耗时', width: 120 },
 	{ prop: 'content', label: '甄别申请原因', width: 200 },
 	{ prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
-]);
+];
 const state = reactive({
 	queryParams: {
 		// 查询条件
@@ -186,21 +232,10 @@ const queryList = () => {
 	screenList(request)
 		.then((response: any) => {
 			if (state.queryParams.Status === '4') {
-				if (!columns.value.find((item) => item.prop === 'statusText')) {
-					columns.value.splice(
-						index,
-						0,
-						{ prop: 'statusText', label: '甄别状态', width: 120 },
-						{ prop: 'actualHandleStepName', label: '当前节点', width: 150 },
-						{ prop: 'actualHandlerName', label: '当前审批人', width: 150 }
-					);
-				}
+				// 已办
+				columns.value = columnsDone;
 			} else {
-				if (columns.value.find((item) => item.prop === 'statusText')) {
-					columns.value = columns.value.filter(
-						(item) => item.prop !== 'statusText' && item.prop !== 'actualHandleStepName' && item.prop !== 'actualHandlerName'
-					);
-				}
+				columns.value = columnsTodo;
 			}
 			state.tableData = response?.result.items ?? [];
 			state.total = response?.result.total;

+ 39 - 30
src/views/business/order/index.vue

@@ -316,8 +316,9 @@
 				:total="state.total"
 				v-model:page-index="state.queryParams.PageIndex"
 				v-model:page-size="state.queryParams.PageSize"
-				@export-current="exportCurrent"
-				@export-all="exportAll"
+				:toolButton="['refresh', 'setting', 'exportCurrent', 'exportAll']"
+				@export-current="exportTable($event)"
+				@export-all="exportTable($event, true)"
 				:key="Math.random()"
 			>
 				<!-- 表格 header 按钮 -->
@@ -344,20 +345,12 @@
 						><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
 					</el-button>
 				</template>
-				<template #expiredStatus="{ row }">
+				<template #expiredStatusText="{ row }">
 					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
 				</template>
-				<template #isProvince="{ row }">
-					<span>{{ row.isProvince ? '省工单' : '市工单' }}</span>
-				</template>
 				<template #title="{ row }">
 					<order-detail :order="row" @updateList="queryList" :type="row.canSign ? 'danger' : 'primary'">{{ row.title }}</order-detail>
 				</template>
-				<template #employeeName="{ row }">
-					<span
-						>{{ row.acceptorName }} <span v-if="row.acceptorStaffNo">[{{ row.acceptorStaffNo }}]</span>
-					</span>
-				</template>
 				<!-- 表格操作 -->
 				<template #operation="{ row }">
 					<!--					<el-button
@@ -393,12 +386,12 @@ import { shortcuts } from '@/utils/constants';
 import other from '@/utils/other';
 import { useRoute, useRouter } from 'vue-router';
 import { formatDate } from '@/utils/formatTime';
-import { exportJbOrder, listBaseData, orderList, provinceReturn } from '@/api/business/order';
+import { exportJbOrder, exportOrder, listBaseData, orderList, provinceReturn } from '@/api/business/order';
 import { addObserve } from '@/api/query/observe';
 import { addEnd } from '@/api/query/end';
 import { treeArea } from '@/api/auxiliary/area';
 import { orderSign } from '@/api/todo/order';
-import { downloadZip } from '@/utils/tools';
+import { downloadFileByStream, downloadZip } from '@/utils/tools';
 
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
@@ -496,15 +489,15 @@ const selectable = (row: any) => {
 	if (state.queryParams.IsProvinceOrder) {
 		return row?.isProvince && row?.source > 1 && row?.status <= 1;
 	} else {
-		return !row?.isProvince;
+		return true;
 	}
 };
 // 表格配置项
 const columns = ref<any[]>([
 	{ type: 'selection', fixed: 'left', width: 55, selectable: selectable, align: 'center' },
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center', width: 80 },
+	{ prop: 'expiredStatusText', label: '超期状态', align: 'center', width: 80 },
 	{ prop: 'no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
+	{ prop: 'isProvinceText', label: '省/市工单', width: 100 },
 	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
 	{ prop: 'statusText', label: '工单状态', width: 100 },
 	{ prop: 'title', label: '工单标题', width: 300 },
@@ -539,20 +532,14 @@ const columns = ref<any[]>([
 	{ prop: 'sourceChannel', label: '来源方式', width: 100 },
 	{ prop: 'hotspotName', label: '热点分类', width: 200 },
 	{
-		prop: 'sensitive',
+		prop: 'sensitiveText',
 		label: '敏感词',
 		width: 200,
-		render: (scope) => {
-			return <span>{scope.row.sensitive?.join(',')}</span>;
-		},
 	},
-	{ prop: 'employeeName', label: '受理人', width: 120 },
+	{ prop: 'acceptorName', label: '受理人', width: 100 },
 	{
 		prop: 'reTransactNum',
-		label: '重办次数',
-		render: (scope) => {
-			return <span>{scope.row.reTransactNum ? scope.row.reTransactNum : 0}</span>;
-		},
+		label: '重办次数'
 	},
 	{ prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
 ]);
@@ -778,11 +765,33 @@ const orderReturnRef = ref<RefType>(); // 工单退回ref
 const onReturn = (row: any) => {
 	orderReturnRef.value.openDialog(row);
 };
-const exportCurrent = () => {
-	console.log('导出当前页', proTableRef.value);
-};
-const exportAll = () => {
-	console.log('导出全部', proTableRef.value);
+// 表格导出
+const exportTable = (val: any, isExportAll = false) => {
+	let request = other.deepClone(state.queryParams);
+	Reflect.deleteProperty(request, 'crTime'); // 删除无用的参数
+	Reflect.deleteProperty(request, 'exTime'); // 删除无用的参数
+	Reflect.deleteProperty(request, 'doneTime'); // 删除无用的参数
+	Reflect.deleteProperty(request, 'AreaCode'); // 删除无用的参数
+	const columnInfos = val.map((item: any) => {
+		return {
+			prop: item.prop,
+			name: item.label,
+		};
+	});
+	const req = {
+		queryDto: request,
+		columnInfos,
+		isExportAll,
+	};
+	state.loading = true;
+	exportOrder(req)
+		.then((res: any) => {
+			state.loading = false;
+			downloadFileByStream(res);
+		})
+		.catch(() => {
+			state.loading = false;
+		});
 };
 // 交办单导出
 const onJbExport = () => {

+ 2 - 10
src/views/business/publish/index.vue

@@ -31,17 +31,9 @@
 				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.order" @updateList="queryList">{{ row.order?.title }}</order-detail>
 				</template>
-				<template #acceptorName="{ row }">
-					<span
-						>{{ row.order?.acceptorName }} <span v-if="row.order?.acceptorStaffNo">[{{ row.order?.acceptorStaffNo }}]</span>
-					</span>
-				</template>
 				<template #publishState="{ row }">
 					<span>{{ row.publishState ? '公开' : '不公开' }}</span>
 				</template>
@@ -75,8 +67,8 @@ const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
 	{ prop: 'order.no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
-	{ prop: 'title', label: '工单标题', width: 300 },
+	{ prop: 'order.isProvinceText', label: '省/市工单', width: 100 },
+	{ prop: 'order.title', label: '工单标题', width: 300 },
 	{ prop: 'order.counterSignTypeText', label: '是否会签', width: 100 },
 	{ prop: 'order.sourceChannel', label: '来源方式', width: 120 },
 	{ prop: 'order.statusText', label: '工单状态', width: 100 },

+ 2 - 10
src/views/business/publish/todo.vue

@@ -42,17 +42,9 @@
 						<SvgIcon name="iconfont icon-tianjiawenjian" class="mr5" />批量发布
 					</el-button>
 				</template>
-				<template #isProvince="{ row }">
-					<span>{{ row.isProvince ? '省工单' : '市工单' }}</span>
-				</template>
 				<template #title="{ row }">
 					<order-detail :order="row" @updateList="queryList">{{ row.title }}</order-detail>
 				</template>
-				<template #employeeName="{ row }">
-					<span
-						>{{ row.acceptorName }} <span v-if="row.acceptorStaffNo">[{{ row.acceptorStaffNo }}]</span>
-					</span>
-				</template>
 				<!-- 表格操作 -->
 				<template #operation="{ row }">
 					<el-button link type="primary" @click="publish(row)" title="发布工单" v-auth="'business:publish:todo:publish'"> 发布 </el-button>
@@ -96,14 +88,14 @@ const selectable = (row: any) => {
 const columns = ref<any[]>([
 	{ type: 'selection', selectable: selectable, fixed: 'left', width: 55,align: 'center' },
 	{ prop: 'no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
+	{ prop: 'isProvinceText', label: '省/市工单', width: 100 },
 	{ prop: 'statusText', label: '发布状态', width: 100 },
 	{ prop: 'title', label: '工单标题', width: 300 },
 	{ prop: 'sourceChannel', label: '来源方式' },
 	{ prop: 'acceptType', label: '受理类型', width: 150 },
 	{ prop: 'counterSignTypeText', label: '是否会签', width: 100 },
 	{ prop: 'actualHandleOrgName', label: '接办部门', width: 150 },
-	{ prop: 'employeeName', label: '受理人', width: 120 },
+	{ prop: 'acceptorName', label: '受理人', width: 120 },
 	{
 		prop: 'actualHandleTime',
 		label: '接办时间',

+ 10 - 20
src/views/home/component/ToDo.vue

@@ -35,20 +35,12 @@
 				:pagination="false"
 				:key="Math.random()"
 			>
-				<template #expiredStatus="{ row }">
+				<template #expiredStatusText="{ row }">
 					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
 				</template>
-				<template #isProvince="{ row }">
-					<span>{{ row.isProvince ? '省工单' : '市工单' }}</span>
-				</template>
 				<template #title="{ row }">
 					<order-detail :order="row" @updateList="handleChange(activeName)" :type="row.canSign ? 'danger' : 'primary'">{{ row.title }}</order-detail>
 				</template>
-				<template #employeeName="{ row }">
-					<span
-						>{{ row.acceptorName }} <span v-if="row.acceptorStaffNo">[{{ row.acceptorStaffNo }}]</span>
-					</span>
-				</template>
 				<!-- 表格操作 -->
 				<template #operation="{ row }">
 					<el-button link type="primary" @click="onSign(row)" title="签收工单" v-if="row.canSign"> 签收 </el-button>
@@ -87,16 +79,14 @@ watchEffect(() => {
 		return (activeName.value = '1');
 	}
 });
-
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([]);
-
 // 工单待办表头
 const todoColumns = [
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center',fixed: 'left',width: 80 },
+	{ prop: 'expiredStatusText', label: '超期状态', align: 'center', fixed: 'left', width: 80 },
 	{ prop: 'no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
+	{ prop: 'isProvinceText', label: '省/市工单', width: 100 },
 	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
 	{ prop: 'statusText', label: '工单状态', width: 100 },
 	{ prop: 'title', label: '工单标题', width: 300 },
@@ -116,17 +106,17 @@ const todoColumns = [
 			return <span>{formatDate(scope.row.expiredTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
 		},
 	},
-	{ prop: 'acceptType', label: '受理类型', width: 150 },
+	{ prop: 'acceptType', label: '受理类型', width: 120 },
 	{ prop: 'emergencyLevelText', label: '紧急程度', width: 100 },
 	{ prop: 'sourceChannel', label: '来源方式', width: 100 },
-	{ prop: 'hotspotName', label: '热点分类', width: 100 },
-	{ prop: 'employeeName', label: '受理人', width: 170 },
+	{ prop: 'hotspotName', label: '热点分类', width: 200 },
+	{ prop: 'acceptorName', label: '受理人', width: 170 },
 	{ prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
 ];
 // 工单坐席待办表头
 const seatsColumns = [
-	{ prop: 'no', label: '工单编码', width: 150,fixed: 'left' },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
+	{ prop: 'no', label: '工单编码', width: 150, fixed: 'left' },
+	{ prop: 'isProvinceText', label: '省/市工单', width: 100 },
 	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
 	{ prop: 'statusText', label: '工单状态', width: 100 },
 	{ prop: 'title', label: '工单标题', width: 300 },
@@ -157,8 +147,8 @@ const seatsColumns = [
 	{ prop: 'acceptType', label: '受理类型', width: 120 },
 	{ prop: 'sourceChannel', label: '来源方式', width: 120 },
 	{ prop: 'emergencyLevelText', label: '紧急程度', width: 100 },
-	{ prop: 'hotspotName', label: '热点分类', width: 100 },
-	{ prop: 'employeeName', label: '受理人', width: 150 },
+	{ prop: 'hotspotName', label: '热点分类', width: 200 },
+	{ prop: 'acceptorName', label: '受理人', width: 150 },
 	{ prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
 ];
 // tab切换

+ 4 - 4
src/views/statistics/call/seatsRecord.vue

@@ -3,14 +3,14 @@
 		<!-- 搜索  -->
 		<el-card shadow="never">
 			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent inline>
-				<el-form-item label="分机号" prop="CDPN">
-					<el-input v-model="state.queryParams.CDPN" placeholder="分机号" clearable @keyup.enter="handleQuery" class="keyword-input" />
+				<el-form-item label="分机号" prop="TelNo">
+					<el-input v-model="state.queryParams.TelNo" placeholder="分机号" clearable @keyup.enter="handleQuery" class="keyword-input" />
 				</el-form-item>
 				<el-form-item label="动作类型" prop="CDPN">
 					<el-input v-model="state.queryParams.CDPN" placeholder="动作类型" clearable @keyup.enter="handleQuery" class="keyword-input" />
 				</el-form-item>
-				<el-form-item label="坐席" prop="CDPN">
-					<el-input v-model="state.queryParams.CDPN" placeholder="坐席" clearable @keyup.enter="handleQuery" class="keyword-input" />
+				<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 label="时间段" prop="crTime">
 					<el-date-picker

+ 39 - 27
src/views/todo/center/index.vue

@@ -115,6 +115,9 @@
 				v-model:page-index="state.queryParams.PageIndex"
 				v-model:page-size="state.queryParams.PageSize"
 				:key="Math.random()"
+        :toolButton="['refresh', 'setting', 'exportCurrent', 'exportAll']"
+        @export-current="exportTable($event)"
+        @export-all="exportTable($event, true)"
 			>
 				<!-- 表格 header 按钮 -->
 				<template #tableHeader="scope">
@@ -122,20 +125,12 @@
 						><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
 					</el-button>
 				</template>
-				<template #expiredStatus="{ row }">
-					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
-				</template>
-				<template #isProvince="{ row }">
-					<span>{{ row.isProvince ? '省工单' : '市工单' }}</span>
-				</template>
-				<template #title="{ row }">
-					<order-detail :order="row" @updateList="queryList" :type="row.canSign ? 'danger' : 'primary'">{{ row.title }}</order-detail>
-				</template>
-				<template #employeeName="{ row }">
-					<span
-						>{{ row.acceptorName }} <span v-if="row.acceptorStaffNo">[{{ row.acceptorStaffNo }}]</span>
-					</span>
-				</template>
+        <template #expiredStatusText="{ row }">
+          <span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
+        </template>
+        <template #title="{ row }">
+          <order-detail :order="row" @updateList="queryList">{{ row.title }}</order-detail>
+        </template>
 				<!-- 表格操作 -->
 				<template #operation="{ row }">
 					<el-button link type="primary" @click="onSign(row)" title="签收工单" v-if="row.canSign" v-auth="'todo:center:sign'"> 签收 </el-button>
@@ -160,8 +155,8 @@ import { useRoute, useRouter } from 'vue-router';
 import { formatDate } from '@/utils/formatTime';
 import { centerTodo, centerTodoBase } from '@/api/todo/center';
 import { orderSign } from '@/api/todo/order';
-import { exportJbOrder } from '@/api/business/order';
-import { downloadZip } from '@/utils/tools';
+import { exportJbOrder, exportOrder } from "@/api/business/order";
+import { downloadFileByStream, downloadZip } from "@/utils/tools";
 
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
@@ -205,9 +200,9 @@ const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
 	{ type: 'selection', fixed: 'left', width: 55, align: 'center' },
-	{ prop: 'expiredStatus', label: '超期状态', width: 80 },
+	{ prop: 'expiredStatusText', label: '超期状态', width: 80,align: 'center' },
 	{ prop: 'no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
+	{ prop: 'isProvinceText', label: '省/市工单', width: 100 },
 	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
 	{ prop: 'statusText', label: '工单状态', width: 100 },
 	{ prop: 'title', label: '工单标题', width: 300 },
@@ -244,18 +239,12 @@ const columns = ref<any[]>([
 	{
 		prop: 'sensitive',
 		label: '敏感词',
-		width: 200,
-		render: (scope) => {
-			return <span>{scope.row.sensitive?.join(',')}</span>;
-		},
+		width: 200
 	},
-	{ prop: 'employeeName', label: '受理人', width: 120 },
+	{ prop: 'acceptorName', label: '受理人', width: 120 },
 	{
 		prop: 'reTransactNum',
-		label: '重办次数',
-		render: (scope) => {
-			return <span>{scope.row.reTransactNum ? scope.row.reTransactNum : 0}</span>;
-		},
+		label: '重办次数'
 	},
 	{ prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
 ]);
@@ -377,6 +366,29 @@ const onJbExport = () => {
     })
     .catch(() => {});
 };
+// 表格导出
+const exportTable = (val: any, isExportAll = false) => {
+  const columnInfos = val.map((item: any) => {
+    return {
+      prop: item.prop,
+      name: item.label,
+    };
+  });
+  const req = {
+    queryDto: { ...state.queryParams },
+    columnInfos,
+    isExportAll,
+  };
+  state.loading = true;
+  exportOrder(req)
+    .then((res: any) => {
+      state.loading = false;
+      downloadFileByStream(res);
+    })
+    .catch(() => {
+      state.loading = false;
+    });
+};
 onMounted(() => {
 	getBaseData();
 	queryList();

+ 111 - 55
src/views/todo/order/index.vue

@@ -45,26 +45,21 @@
 				v-model:page-index="state.queryParams.PageIndex"
 				v-model:page-size="state.queryParams.PageSize"
 				:key="Math.random()"
+        :toolButton="['refresh', 'setting', 'exportCurrent', 'exportAll']"
+        @export-current="exportTable($event)"
+        @export-all="exportTable($event, true)"
 			>
-        <template #tableHeader="scope">
-          <el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'todo:seats:jbdExport'"
-          ><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
-          </el-button>
-        </template>
-				<template #expiredStatus="{ row }">
-					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
+				<template #tableHeader="scope">
+					<el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'todo:seats:jbdExport'"
+						><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
+					</el-button>
 				</template>
-				<template #isProvince="{ row }">
-					<span>{{ row.isProvince ? '省工单' : '市工单' }}</span>
+				<template #expiredStatusText="{ row }">
+					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
 				</template>
 				<template #title="{ row }">
 					<order-detail :order="row" @updateList="queryList">{{ row.title }}</order-detail>
 				</template>
-				<template #employeeName="{ row }">
-					<span
-						>{{ row.acceptorName }} <span v-if="row.acceptorStaffNo">[{{ row.acceptorStaffNo }}]</span>
-					</span>
-				</template>
 				<!-- 表格操作 -->
 				<template #operation="{ row }">
 					<order-detail :order="row" @updateList="queryList" />
@@ -75,12 +70,12 @@
 </template>
 <script setup lang="tsx" name="todoOrder">
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
-import { ElMessage, ElMessageBox, FormInstance } from "element-plus";
+import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
 import { formatDate } from '@/utils/formatTime';
 import { useRouter } from 'vue-router';
 import { orderListTodo } from '@/api/todo/order';
-import { exportJbOrder } from "@/api/business/order";
-import { downloadZip } from "@/utils/tools";
+import { exportJbOrder } from '@/api/business/order';
+import { downloadZip } from '@/utils/tools';
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
 // 定义变量内容
@@ -103,11 +98,12 @@ const ruleFormRef = ref<RefType>(); // 表单ref
 const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
-const columns = ref<any[]>([
-  { type: 'selection', fixed: 'left', width: 55, align: 'center' },
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center' },
+const columns = ref<any[]>([]);
+const columnsTodo = [
+	{ type: 'selection', fixed: 'left', width: 55, align: 'center' },
+	{ prop: 'expiredStatusText', label: '超期状态', align: 'center', width: 80 },
 	{ prop: 'no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
+	{ prop: 'isProvinceText', label: '省/市工单', width: 100 },
 	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
 	{ prop: 'statusText', label: '工单状态', width: 100 },
 	{ prop: 'title', label: '工单标题', width: 300 },
@@ -140,16 +136,60 @@ const columns = ref<any[]>([
 	{ prop: 'emergencyLevelText', label: '紧急程度', width: 150 },
 	{ prop: 'sourceChannel', label: '来源方式', width: 100 },
 	{ prop: 'hotspotName', label: '热点分类', width: 200 },
-	{ prop: 'employeeName', label: '受理人', width: 120 },
+	{ prop: 'acceptorName', label: '受理人', width: 120 },
 	{
 		prop: 'reTransactNum',
 		label: '重办次数',
+	},
+	{ prop: 'operation', label: '操作', fixed: 'right', width: 140, align: 'center' },
+];
+const columnsDone = [
+	// 已办
+	{ type: 'selection', fixed: 'left', width: 55, align: 'center' },
+	{ prop: 'expiredStatusText', label: '超期状态', align: 'center', width: 80 },
+	{ prop: 'no', label: '工单编码', width: 150 },
+	{ prop: 'isProvinceText', label: '省/市工单', width: 100 },
+	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
+	{ prop: 'statusText', label: '工单状态', width: 100 },
+	{ prop: 'title', label: '工单标题', width: 300 },
+	{ prop: 'counterSignTypeText', label: '是否会签', width: 100 },
+	{
+		prop: 'creationTime',
+		label: '生成时间',
+		width: 170,
+		render: (scope) => {
+			return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{
+		prop: 'startTime',
+		label: '受理时间',
+		width: 170,
+		render: (scope) => {
+			return <span>{formatDate(scope.row.startTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{
+		prop: 'expiredTime',
+		label: '工单期满时间',
+		width: 170,
 		render: (scope) => {
-			return <span>{scope.row.reTransactNum ? scope.row.reTransactNum : 0}</span>;
+			return <span>{formatDate(scope.row.expiredTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
 		},
 	},
-	{ prop: 'operation', label: '操作', fixed: 'right', width: 100, align: 'center' },
-]);
+	{ prop: 'orgLevelOneName', label: '一级部门', width: 150 },
+	{ prop: 'actualHandleOrgName', label: '接办部门', width: 150 },
+	{ prop: 'acceptType', label: '受理类型', width: 150 },
+	{ prop: 'emergencyLevelText', label: '紧急程度', width: 150 },
+	{ prop: 'sourceChannel', label: '来源方式', width: 100 },
+	{ prop: 'hotspotName', label: '热点分类', width: 200 },
+	{ prop: 'acceptorName', label: '受理人', width: 120 },
+	{
+		prop: 'reTransactNum',
+		label: '重办次数',
+	},
+	{ prop: 'operation', label: '操作', fixed: 'right', width: 140, align: 'center' },
+];
 // 手动查询,将页码设置为1
 const handleQuery = () => {
 	state.queryParams.PageIndex = 1;
@@ -161,18 +201,9 @@ const queryList = async () => {
 		state.loading = true;
 		const index = columns.value.findIndex((item) => item.prop === 'acceptType');
 		if (state.queryParams.IsHandled === 'true') {
-			if (!columns.value.find((item) => item.prop === 'orgLevelOneName')) {
-				columns.value.splice(
-					index,
-					0,
-					{ prop: 'orgLevelOneName', label: '一级部门', width: 150 },
-					{ prop: 'actualHandleOrgName', label: '接办部门', width: 150 }
-				);
-			}
+			columns.value = columnsDone;
 		} else {
-			if (columns.value.find((item) => item.prop === 'orgLevelOneName')) {
-				columns.value = columns.value.filter((item) => item.prop !== 'orgLevelOneName' && item.prop !== 'actualHandleOrgName');
-			}
+			columns.value = columnsTodo;
 		}
 		const res: any = await orderListTodo(state.queryParams);
 		state.tableData = res.result?.items ?? [];
@@ -190,26 +221,51 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 };
 // 交办单导出
 const onJbExport = () => {
-  const ids = proTableRef.value.selectedList.map((item: any) => item.id);
-  ElMessageBox.confirm(`您确定导出选中的${proTableRef.value.selectedList.length}个工单的交办单,是否继续?`, '提示', {
-    confirmButtonText: '确认',
-    cancelButtonText: '取消',
-    type: 'warning',
-    draggable: true,
-    cancelButtonClass: 'default-button',
-    autofocus: false,
-  })
-    .then(() => {
-      state.loading = true;
-      exportJbOrder(ids)
-        .then((res: any) => {
-          downloadZip(res);
-          state.loading = false;
-          ElMessage.success('导出成功');
-        })
-        .catch(() => {state.loading = false;});
+	const ids = proTableRef.value.selectedList.map((item: any) => item.id);
+	ElMessageBox.confirm(`您确定导出选中的${proTableRef.value.selectedList.length}个工单的交办单,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			state.loading = true;
+			exportJbOrder(ids)
+				.then((res: any) => {
+					downloadZip(res);
+					state.loading = false;
+					ElMessage.success('导出成功');
+				})
+				.catch(() => {
+					state.loading = false;
+				});
+		})
+		.catch(() => {});
+};
+// 表格导出
+const exportTable = (val: any, isExportAll = false) => {
+  const columnInfos = val.map((item: any) => {
+    return {
+      prop: item.prop,
+      name: item.label,
+    };
+  });
+  const req = {
+    queryDto: { ...state.queryParams },
+    columnInfos,
+    isExportAll,
+  };
+  state.loading = true;
+  exportOrder(req)
+    .then((res: any) => {
+      state.loading = false;
+      downloadFileByStream(res);
     })
-    .catch(() => {});
+    .catch(() => {
+      state.loading = false;
+    });
 };
 const historyParams = history.state;
 onMounted(() => {

+ 109 - 54
src/views/todo/seats/index.vue

@@ -39,28 +39,23 @@
 				v-model:page-index="state.queryParams.PageIndex"
 				v-model:page-size="state.queryParams.PageSize"
 				:key="Math.random()"
+				:toolButton="['refresh', 'setting', 'exportCurrent', 'exportAll']"
+				@export-current="exportTable($event)"
+				@export-all="exportTable($event, true)"
 			>
 				<!-- 表格 header 按钮 -->
 				<template #tableHeader="scope">
 					<el-button type="primary" @click="onAddOrder" v-auth="'todo:seats:add'"> <SvgIcon name="ele-Plus" class="mr5" />新建工单 </el-button>
-          <el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'todo:order:jbdExport'"
-          ><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
-          </el-button>
+					<el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'todo:order:jbdExport'"
+						><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
+					</el-button>
 				</template>
-				<template #expiredStatus="{ row }">
+				<template #expiredStatusText="{ row }">
 					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
 				</template>
-				<template #isProvince="{ row }">
-					<span>{{ row.isProvince ? '省工单' : '市工单' }}</span>
-				</template>
 				<template #title="{ row }">
 					<order-detail :order="row" @updateList="queryList" :type="row.canSign ? 'danger' : 'primary'">{{ row.title }}</order-detail>
 				</template>
-				<template #employeeName="{ row }">
-					<span
-						>{{ row.acceptorName }} <span v-if="row.acceptorStaffNo">[{{ row.acceptorStaffNo }}]</span>
-					</span>
-				</template>
 				<!-- 表格操作 -->
 				<template #operation="{ row }">
 					<el-button link type="success" @click="onOrderEdit(row)" title="编辑工单" v-if="row.canEdit" v-auth="'todo:seats:edit'"> 修改 </el-button>
@@ -77,8 +72,8 @@ import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
 import { formatDate } from '@/utils/formatTime';
 import { useRouter } from 'vue-router';
 import { seatsListTodo, orderSign } from '@/api/todo/order';
-import { downloadZip, guid } from "@/utils/tools";
-import { exportJbOrder } from "@/api/business/order";
+import { downloadFileByStream, downloadZip } from '@/utils/tools';
+import { exportJbOrder, exportOrder } from '@/api/business/order';
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
 // 定义变量内容
@@ -100,11 +95,12 @@ const ruleFormRef = ref<RefType>(); // 表单ref
 const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
-const columns = ref<any[]>([
-  { type: 'selection', fixed: 'left', width: 55, align: 'center' },
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center',width: 80 },
+const columns = ref<any[]>([]);
+const columnsTodo = [
+	{ type: 'selection', fixed: 'left', width: 55, align: 'center' },
+	{ prop: 'expiredStatusText', label: '超期状态', align: 'center', width: 80 },
 	{ prop: 'no', label: '工单编码', width: 150 },
-	{ prop: 'isProvince', label: '省/市工单', width: 100 },
+	{ prop: 'isProvinceText', label: '省/市工单', width: 100 },
 	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
 	{ prop: 'statusText', label: '工单状态', width: 100 },
 	{ prop: 'title', label: '工单标题', width: 300 },
@@ -137,16 +133,60 @@ const columns = ref<any[]>([
 	{ prop: 'emergencyLevelText', label: '紧急程度', width: 150 },
 	{ prop: 'sourceChannel', label: '来源方式', width: 100 },
 	{ prop: 'hotspotName', label: '热点分类', width: 200 },
-	{ prop: 'employeeName', label: '受理人', width: 120 },
+	{ prop: 'acceptorName', label: '受理人', width: 120 },
 	{
 		prop: 'reTransactNum',
 		label: '重办次数',
+	},
+	{ prop: 'operation', label: '操作', fixed: 'right', width: 140, align: 'center' },
+];
+const columnsDone = [
+	// 已办
+	{ type: 'selection', fixed: 'left', width: 55, align: 'center' },
+	{ prop: 'expiredStatusText', label: '超期状态', align: 'center', width: 80 },
+	{ prop: 'no', label: '工单编码', width: 150 },
+	{ prop: 'isProvinceText', label: '省/市工单', width: 100 },
+	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
+	{ prop: 'statusText', label: '工单状态', width: 100 },
+	{ prop: 'title', label: '工单标题', width: 300 },
+	{ prop: 'counterSignTypeText', label: '是否会签', width: 100 },
+	{
+		prop: 'creationTime',
+		label: '生成时间',
+		width: 170,
+		render: (scope) => {
+			return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{
+		prop: 'startTime',
+		label: '受理时间',
+		width: 170,
+		render: (scope) => {
+			return <span>{formatDate(scope.row.startTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{
+		prop: 'expiredTime',
+		label: '工单期满时间',
+		width: 170,
 		render: (scope) => {
-			return <span>{scope.row.reTransactNum ? scope.row.reTransactNum : 0}</span>;
+			return <span>{formatDate(scope.row.expiredTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
 		},
 	},
+	{ prop: 'orgLevelOneName', label: '一级部门', width: 150 },
+	{ prop: 'actualHandleOrgName', label: '接办部门', width: 150 },
+	{ prop: 'acceptType', label: '受理类型', width: 150 },
+	{ prop: 'emergencyLevelText', label: '紧急程度', width: 150 },
+	{ prop: 'sourceChannel', label: '来源方式', width: 100 },
+	{ prop: 'hotspotName', label: '热点分类', width: 200 },
+	{ prop: 'acceptorName', label: '受理人', width: 120 },
+	{
+		prop: 'reTransactNum',
+		label: '重办次数',
+	},
 	{ prop: 'operation', label: '操作', fixed: 'right', width: 140, align: 'center' },
-]);
+];
 // 手动查询,将页码设置为1
 const handleQuery = () => {
 	state.queryParams.PageIndex = 1;
@@ -156,20 +196,10 @@ const handleQuery = () => {
 const queryList = async () => {
 	try {
 		state.loading = true;
-		const index = columns.value.findIndex((item) => item.prop === 'acceptType');
 		if (state.queryParams.IsHandled === 'true') {
-			if (!columns.value.find((item) => item.prop === 'orgLevelOneName')) {
-				columns.value.splice(
-					index,
-					0,
-					{ prop: 'orgLevelOneName', label: '一级部门', width: 150 },
-					{ prop: 'actualHandleOrgName', label: '接办部门', width: 150 }
-				);
-			}
+			columns.value = columnsDone;
 		} else {
-			if (columns.value.find((item) => item.prop === 'orgLevelOneName')) {
-				columns.value = columns.value.filter((item) => item.prop !== 'orgLevelOneName' && item.prop !== 'actualHandleOrgName');
-			}
+			columns.value = columnsTodo;
 		}
 		const res: any = await seatsListTodo(state.queryParams);
 		state.tableData = res.result?.items ?? [];
@@ -191,7 +221,7 @@ const onAddOrder = () => {
 		name: 'orderAccept',
 		params: {
 			tagsViewName: `工单受理`,
-      callId: new Date().getTime(),
+			callId: new Date().getTime(),
 		},
 	});
 };
@@ -226,26 +256,51 @@ const onSign = (row: any) => {
 };
 // 交办单导出
 const onJbExport = () => {
-  const ids = proTableRef.value.selectedList.map((item: any) => item.id);
-  ElMessageBox.confirm(`您确定导出选中的${proTableRef.value.selectedList.length}个工单的交办单,是否继续?`, '提示', {
-    confirmButtonText: '确认',
-    cancelButtonText: '取消',
-    type: 'warning',
-    draggable: true,
-    cancelButtonClass: 'default-button',
-    autofocus: false,
-  })
-    .then(() => {
-      state.loading = true;
-      exportJbOrder(ids)
-        .then((res: any) => {
-          downloadZip(res);
-          state.loading = false;
-          ElMessage.success('导出成功');
-        })
-        .catch(() => {state.loading = false;});
-    })
-    .catch(() => {});
+	const ids = proTableRef.value.selectedList.map((item: any) => item.id);
+	ElMessageBox.confirm(`您确定导出选中的${proTableRef.value.selectedList.length}个工单的交办单,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			state.loading = true;
+			exportJbOrder(ids)
+				.then((res: any) => {
+					downloadZip(res);
+					state.loading = false;
+					ElMessage.success('导出成功');
+				})
+				.catch(() => {
+					state.loading = false;
+				});
+		})
+		.catch(() => {});
+};
+// 表格导出
+const exportTable = (val: any, isExportAll = false) => {
+	const columnInfos = val.map((item: any) => {
+		return {
+			prop: item.prop,
+			name: item.label,
+		};
+	});
+	const req = {
+		queryDto: { ...state.queryParams },
+		columnInfos,
+		isExportAll,
+	};
+	state.loading = true;
+	exportOrder(req)
+		.then((res: any) => {
+			state.loading = false;
+			downloadFileByStream(res);
+		})
+		.catch(() => {
+			state.loading = false;
+		});
 };
 onMounted(() => {
 	queryList();