Prechádzať zdrojové kódy

reactor:529 【坐席话务统计分析】需支持点击数据打开明细表;528 回访量统计:需支持点击数据打开对应明细页(自贡+泸州通用)

zhangchong 1 týždeň pred
rodič
commit
1019049098

+ 28 - 0
src/api/statistics/call.ts

@@ -143,6 +143,34 @@ export const callAgentExport = (data: object) => {
 		}
 	);
 };
+/**
+ * @description 坐席话务统计分析明细
+ * @param {object} params
+ */
+export const callAgentDetail = (params: object) => {
+	return request({
+		url: `/api/v1/BiCall/seats/list`,
+		method: 'get',
+		params,
+	});
+}
+/**
+ * @description 坐席话务统计分析明细导出
+ * @param {object} data
+ */
+export const callAgentDetailExport = (data: object) => {
+	return request(
+		{
+			url: `/api/v1/BiCall/seats/list/export`,
+			method: 'post',
+			data,
+			responseType: 'blob',
+		},
+		{
+			reduce_data_format: false,
+		}
+	);
+}
 /**
  * @description 坐席小休统计
  * @param {object} params

+ 28 - 0
src/api/statistics/order.ts

@@ -316,6 +316,34 @@ export const departmentVisitZGExport = (data: object) => {
 		}
 	);
 };
+/**
+ * @description 回访量统计明细 自贡
+ * @param {object} params
+ */
+export const departmentVisitZGDetail = (params: object) => {
+	return request({
+		url: `/api/v1/BiOrder/visit/quantity/list`,
+		method: 'get',
+		params,
+	});
+}
+/**
+ * @description 回访量统计明细导出 自贡
+ * @param {object} data
+ */
+export const departmentVisitZGDetailExport = (data: object) => {
+	return request(
+		{
+			url: `/api/v1/BiOrder/visit/quantity/list/export`,
+			method: 'post',
+			data,
+			responseType: 'blob',
+		},
+		{
+			reduce_data_format: false,
+		}
+	);
+}
 /**
  * @description 热点类型小类统计
  * @param {object} params

+ 11 - 1
src/router/route.ts

@@ -477,7 +477,17 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
 			title: '话务时段分析明细',
 			isKeepAlive: true,
 		},
-	},{
+	},
+	{
+		path: '/statistics/call/detailTelPhoneList',
+		name: 'statisticsCallDetailTelPhoneList',
+		component: () => import('@/views/statistics/call/detailTelPhoneList.vue'),
+		meta: {
+			title: '坐席话务统计分析明细',
+			isKeepAlive: true,
+		},
+	}
+	,{
 		path: '/statistics/center/detailReport/:id/:tagsViewName?',
 		name: 'statisticsCenterDetailReport',
 		component: () => import('@/views/statistics/center/detail-report.vue'),

+ 180 - 0
src/views/statistics/call/detailTelPhoneList.vue

@@ -0,0 +1,180 @@
+<template>
+	<div class="statistics-call-detail-tel-phoneList-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<vxe-toolbar
+				ref="toolbarRef"
+				:loading="state.loading"
+				custom
+				:refresh="{
+					queryMethod: queryList,
+				}"
+				:tools="[{ toolRender: { name: 'exportCurrent' } }, { 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: 100 }"
+					id="statisticsCallDetailTelPhoneList"
+					:custom-config="{ storage: true }"
+					:params="{ exportMethod: callAgentDetailExport, exportParams: requestParams }"
+					showHeaderOverflow
+				>
+					<vxe-column field="orderNo" title="工单编码" width="140"></vxe-column>
+					<vxe-column field="title" title="工单标题" width="200">
+						<template #default="{ row }">
+							<order-detail :order="{ ...row, id: row.orderId }" @updateList="queryList">{{ row.orderTitle }}</order-detail>
+						</template>
+					</vxe-column>
+					<vxe-column field="cpn" title="主叫号码" width="120"></vxe-column>
+					<vxe-column field="cdpn" title="被叫号码" width="120"></vxe-column>
+					<vxe-column field="telNo" title="响应分机" width="120"></vxe-column>
+					<vxe-column field="endByText" title="挂断状态" width="120"></vxe-column>
+					<vxe-column field="userName" title="话务员" width="120"></vxe-column>
+					<vxe-column field="createdTime" title="开始时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.createdTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column field="answeredTime" title="接通时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.answeredTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column field="overTime" title="挂断时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.overTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column field="duration" title="通话时间(秒)" width="120"></vxe-column>
+					<vxe-column title="操作" fixed="right" width="160" align="center" :show-overflow="false">
+						<template #default="{ row }">
+							<el-button type="primary" @click="onPlaySoundRecording(row)" title="播放录音" link v-if="row.recordingAbsolutePath">播放录音</el-button>
+							<el-button link type="primary" @click="onDownload(row)" title="下载录音" v-if="row.recordingAbsolutePath">下载录音</el-button>
+						</template>
+					</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>
+		<!-- 播放录音 -->
+		<play-record ref="playRecordRef" />
+	</div>
+</template>
+<script setup lang="tsx" name="statisticsCallDetailTelPhoneList">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { ElMessageBox } from 'element-plus';
+import { callAgentDetail, callAgentDetailExport } from '@/api/statistics/call';
+import { useRoute } from 'vue-router';
+import { formatDate } from '@/utils/formatTime';
+import { fileDownload } from '@/api/public/file';
+import { downloadFileBySrc, downloadFileByStream } from '@/utils/tools';
+import { useThemeConfig } from '@/stores/themeConfig';
+import { storeToRefs } from 'pinia';
+import { useAppConfig } from '@/stores/appConfig';
+
+const PlayRecord = defineAsyncComponent(() => import('@/components/PlayRecord/index.vue')); // 播放录音
+const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
+const state = reactive<any>({
+	queryParams: {
+		PageIndex: 1,
+		PageSize: 20,
+	},
+	tableData: [], //表单
+	loading: false, // 加载
+	total: 0, // 总数
+	callForwardingSource: [],
+	totalCount: {},
+});
+/** 获取列表 */
+const requestParams = ref<EmptyObjectType>({});
+const route = useRoute();
+const routeQueryParams = route.query;
+const queryList = async () => {
+	state.loading = true;
+	try {
+		requestParams.value = {
+			StartTime: routeQueryParams.StartTime,
+			EndTime: routeQueryParams.EndTime,
+			FieldName: routeQueryParams.FieldName,
+			pageIndex: state.queryParams.PageIndex,
+			pageSize: state.queryParams.PageSize,
+			UserId: routeQueryParams.UserId,
+			UserName: routeQueryParams.UserName,
+		};
+		const { result } = await callAgentDetail(requestParams.value);
+		state.tableData = result?.items ?? [];
+		state.tableData = state.tableData.map((item: any) => {
+			return {
+				id: item.orderId,
+				...item,
+			};
+		});
+		state.total = result.total ?? 0;
+		state.loading = false;
+	} catch (e) {
+		state.loading = false;
+		console.log(e);
+	}
+};
+// 播放录音
+const playRecordRef = ref<RefType>();
+const storesThemeConfig = useThemeConfig();
+const { themeConfig } = storeToRefs(storesThemeConfig);
+const appConfigStore = useAppConfig();
+const { AppConfigInfo } = storeToRefs(appConfigStore); // 系统配置信息
+const onPlaySoundRecording = (val: any) => {
+	playRecordRef.value.playRecord(val.otherAccept);
+};
+// 下载录音
+const onDownload = (row: any) => {
+	ElMessageBox.confirm(`您确定要下载此录音吗?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			switch (themeConfig.value.appScope) {
+				case 'YiBin':
+					fileDownload({ path: AppConfigInfo.value.recordDownLoadPrefix + row.audioFile })
+						.then((res: any) => {
+							downloadFileByStream(res, row.audioFile);
+						})
+						.catch(() => {});
+					break;
+				case 'ZiGong':
+				case 'LuZhou':
+					downloadFileBySrc(AppConfigInfo.value.recordPrefix + row.audioFile, row.audioFile);
+					// window.open(AppConfigInfo.value.recordPrefix + row.audioFile)
+					break;
+			}
+		})
+		.catch(() => {});
+};
+const toolbarRef = ref<RefType>();
+const tableRef = ref<RefType>();
+onMounted(() => {
+	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
+});
+</script>

+ 71 - 69
src/views/statistics/call/telephonist.vue

@@ -45,69 +45,80 @@
 					id="statisticsCallTelephonist"
 					:custom-config="{ storage: true }"
 					show-footer
-					:footer-method="footerMethod"
 					:params="{ exportMethod: callAgentExport, exportParams: requestParams }"
+					:footer-data="state.footerData"
+					show-footer-overflow
 				>
 					<vxe-column field="name" title="坐席工号" width="120"></vxe-column>
 					<vxe-column field="inTotal" title="呼入总量" sortable width="120">
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'inTotal')">{{ row.inTotal }}</el-button>-->
-							{{ row.inTotal }}
+							<el-button link type="primary" @click="linkDetail(row, 'inTotal')">{{ row.inTotal }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'inTotal', true)">{{ row.inTotal }}</el-button>
 						</template>
-						<!--						<template #footer="{ row }">
-							<span style="color: blue;">{{ row.inTotal }}</span>
-						</template>-->
 					</vxe-column>
 					<vxe-column field="inAnswered" title="接通总量" sortable width="120">
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'inAnswered')">{{ row.inAnswered }}</el-button>-->
-							{{ row.inAnswered }}
+							<el-button link type="primary" @click="linkDetail(row, 'inAnswered')">{{ row.inAnswered }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'inAnswered', true)">{{ row.inAnswered }}</el-button>
 						</template>
 					</vxe-column>
 					<vxe-column field="inHangupImmediate" title="呼入秒挂" sortable width="120">
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'inHangupImmediate')">{{ row.inHangupImmediate }}</el-button>-->
-							{{ row.inHangupImmediate }}
+							<el-button link type="primary" @click="linkDetail(row, 'inHangupImmediate')">{{ row.inHangupImmediate }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'inHangupImmediate', true)">{{ row.inHangupImmediate }}</el-button>
 						</template>
 					</vxe-column>
 					<vxe-column field="inHanguped" title="呼入超时未接" sortable width="130">
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'inHanguped')">{{ row.inHanguped }}</el-button>-->
-							{{ row.inHanguped }}
+							<el-button link type="primary" @click="linkDetail(row, 'inHanguped')">{{ row.inHanguped }}</el-button>
 						</template>
-					</vxe-column>
-					<vxe-column field="inAnsweredRateString" title="接通率" sortable width="120"></vxe-column>
-					<vxe-column field="inDurationAvg" title="呼入平均时长" sortable width="130">
-						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'inDurationAvg')">{{ row.inDurationAvg }}</el-button>-->
-							{{ row.inDurationAvg }}
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'inHanguped', true)">{{ row.inHanguped }}</el-button>
 						</template>
 					</vxe-column>
+					<vxe-column field="inAnsweredRateString" title="接通率" sortable width="120"></vxe-column>
+					<vxe-column field="inDurationAvg" title="呼入平均时长" sortable width="130"></vxe-column>
 					<vxe-column field="inAvailableAnswer" title="有效接通量" sortable width="120">
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'inAvailableAnswer')">{{ row.inAvailableAnswer }}</el-button>-->
-							{{ row.inAvailableAnswer }}
+							<el-button link type="primary" @click="linkDetail(row, 'inAvailableAnswer')">{{ row.inAvailableAnswer }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'inAvailableAnswer', true)">{{ row.inAvailableAnswer }}</el-button>
 						</template>
 					</vxe-column>
 					<vxe-column field="inHangupImmediateWhenAnswered" title="接通秒挂" sortable width="120">
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'inHangupImmediateWhenAnswered')">{{
+							<el-button link type="primary" @click="linkDetail(row, 'inHangupImmediateWhenAnswered')">{{
+								row.inHangupImmediateWhenAnswered
+							}}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'inHangupImmediateWhenAnswered', true)">{{
 								row.inHangupImmediateWhenAnswered
-							}}</el-button>-->
-							{{ row.inHangupImmediateWhenAnswered }}
+							}}</el-button>
 						</template>
 					</vxe-column>
 					<vxe-column field="availableAnswerRateString" title="有效接通率" sortable width="120"></vxe-column>
 					<vxe-column field="outTotal" title="呼出总量" sortable width="120">
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'outTotal')">{{ row.outTotal }}</el-button>-->
-							{{ row.outTotal }}
+							<el-button link type="primary" @click="linkDetail(row, 'outTotal')">{{ row.outTotal }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'outTotal', true)">{{ row.outTotal }}</el-button>
 						</template>
 					</vxe-column>
 					<vxe-column field="outAnswered" title="呼出接通量" sortable width="120">
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'outAnswered')">{{ row.outAnswered }}</el-button>-->
-							{{ row.outAnswered }}
+							<el-button link type="primary" @click="linkDetail(row, 'outAnswered')">{{ row.outAnswered }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'outAnswered', true)">{{ row.outAnswered }}</el-button>
 						</template>
 					</vxe-column>
 					<vxe-column field="outAnsweredRateString" title="呼出接通率" sortable width="120"></vxe-column>
@@ -116,11 +127,17 @@
 						<template #default="scope">
 							{{ formatDurationDay(scope.row.loginDuration) }}
 						</template>
+						<template #footer="{ row }">
+							{{ formatDurationDay(row.loginDuration) }}
+						</template>
 					</vxe-column>
 					<vxe-column field="restDuration" title="小休时长" width="120" sortable>
 						<template #default="scope">
 							{{ formatDurationDay(scope.row.restDuration) }}
 						</template>
+						<template #footer="{ row }">
+							{{ formatDurationDay(row.restDuration) }}
+						</template>
 					</vxe-column>
 					<vxe-column field="workRateString" title="工作效率" width="120" sortable></vxe-column>
 				</vxe-table>
@@ -135,7 +152,6 @@ import { callAgent, callAgentExport } from '@/api/statistics/call';
 import { defaultDate } from '@/utils/constants';
 import { formatDurationDay } from '@/utils/formatTime';
 import Other from '@/utils/other';
-import XEUtils from 'xe-utils';
 import { useRouter } from 'vue-router';
 
 const StatisticalTime = defineAsyncComponent(() => import('@/components/StatisticalTime/index.vue')); // 日期类型选择组件
@@ -153,6 +169,7 @@ const state = reactive<any>({
 	tableData: [], //表单
 	loading: false, // 加载
 	total: 0, // 总数
+	footerData: [], // 表格合计数据
 });
 /** 搜索按钮操作 */
 const handleQuery = () => {
@@ -169,7 +186,8 @@ const queryList = () => {
 	Reflect.deleteProperty(requestParams.value, 'crTime');
 	callAgent(requestParams.value)
 		.then((res: any) => {
-			state.tableData = res.result;
+			state.tableData = res.result?.list ?? [];
+			state.footerData = [res.result?.total] ?? [];
 			state.loading = false;
 		})
 		.catch(() => {
@@ -184,48 +202,32 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 	statisticalTimeRef.value.reset();
 	queryList();
 };
-// 计算合计
-const footerMethod = ({ columns, data }) => {
-	return [
-		columns.map((column: any, columnIndex: number) => {
-			if (columnIndex === 0) {
-				return '合计';
-			}
-			if (
-				[
-					'inTotal',
-					'inAnswered',
-					'inHangupImmediate',
-					'inHanguped',
-					'inDurationAvg',
-					'inAvailableAnswer',
-					'inHangupImmediateWhenAnswered',
-					'outTotal',
-					'outAnswered',
-				].includes(column.property)
-			) {
-				return XEUtils.sum(data, column.property);
-			}
-			if (['loginDuration', 'restDuration'].includes(column.property)) {
-				return formatDurationDay(XEUtils.sum(data, column.property));
-			}
-		}),
-	];
-};
 // 查看详情
 const router = useRouter();
-const linkDetail = (row: any, type: string) => {
-	console.log(row, '111');
-	/*	router.push({
-		path: '/statistics/order/detailVisitContentZG',
-		query: {
-			StartTime: requestParams.value.StartTime,
-			EndTime: requestParams.value.EndTime,
-			type,
-			tagsViewName: '回访量统计明细',
-			mode: 'normal',
-		},
-	});*/
+const linkDetail = (row: any, FieldName: string, isFooterData?: boolean) => {
+	if (isFooterData) {
+		router.push({
+			path: '/statistics/call/detailTelPhoneList',
+			query: {
+				StartTime: requestParams.value.StartTime,
+				EndTime: requestParams.value.EndTime,
+				FieldName,
+				tagsViewName: '话务时段分析明细',
+			},
+		});
+	} else {
+		router.push({
+			path: '/statistics/call/detailTelPhoneList',
+			query: {
+				StartTime: requestParams.value.StartTime,
+				EndTime: requestParams.value.EndTime,
+				FieldName,
+				tagsViewName: '话务时段分析明细',
+				UserId: row.userId,
+				UserName: row.name,
+			},
+		});
+	}
 };
 const toolbarRef = ref<RefType>();
 const tableRef = ref<RefType>();

+ 43 - 43
src/views/statistics/order/ZGVisitCount.vue

@@ -53,32 +53,40 @@
 					id="statisticsOrderZGVisitCount"
 					:custom-config="{ storage: true }"
 					show-footer
-					:footer-method="footerMethod"
 					:params="{ exportMethod: departmentVisitZGExport, exportParams: requestParams }"
+					:footer-data="state.footerData"
 				>
 					<vxe-column field="employeeName" title="回访员"></vxe-column>
 					<vxe-column field="callVisitCount" title="电话回访量" sortable>
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'callVisitCount')">{{ row.callVisitCount }}</el-button>-->
-							{{ row.callVisitCount }}
+							<el-button link type="primary" @click="linkDetail(row, 'callVisitCount')">{{ row.callVisitCount }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'callVisitCount', true)">{{ row.callVisitCount }}</el-button>
 						</template>
 					</vxe-column>
 					<vxe-column field="defaultVisitCount" title="默认回访量" sortable>
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'defaultVisitCount')">{{ row.defaultVisitCount }}</el-button>-->
-							{{ row.defaultVisitCount }}
+							<el-button link type="primary" @click="linkDetail(row, 'defaultVisitCount')">{{ row.defaultVisitCount }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'defaultVisitCount', true)">{{ row.defaultVisitCount }}</el-button>
 						</template>
 					</vxe-column>
 					<vxe-column field="smsVisitCount" title="短信回访量" sortable>
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'smsVisitCount')">{{ row.smsVisitCount }}</el-button>-->
-							{{ row.smsVisitCount }}
+							<el-button link type="primary" @click="linkDetail(row, 'smsVisitCount')">{{ row.smsVisitCount }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'smsVisitCount', true)">{{ row.smsVisitCount }}</el-button>
 						</template>
 					</vxe-column>
 					<vxe-column field="totalVisitCount" title="总回访量" sortable>
 						<template #default="{ row }">
-							<!--							<el-button link type="primary" @click="linkDetail(row, 'totalVisitCount')">{{ row.totalVisitCount }}</el-button>-->
-							{{ row.totalVisitCount }}
+							<el-button link type="primary" @click="linkDetail(row, 'totalVisitCount')">{{ row.totalVisitCount }}</el-button>
+						</template>
+						<template #footer="{ row }">
+							<el-button link type="primary" @click="linkDetail(row, 'totalVisitCount', true)">{{ row.totalVisitCount }}</el-button>
 						</template>
 					</vxe-column>
 				</vxe-table>
@@ -92,7 +100,6 @@ import { FormInstance } from 'element-plus';
 import { departmentVisitZG, departmentVisitZGExport } from '@/api/statistics/order';
 import { defaultDate } from '@/utils/constants';
 import Other from '@/utils/other';
-import XEUtils from 'xe-utils';
 import { useRouter } from 'vue-router';
 
 const StatisticalTime = defineAsyncComponent(() => import('@/components/StatisticalTime/index.vue')); // 日期类型选择组件
@@ -106,12 +113,7 @@ const state = reactive<any>({
 	tableData: [],
 	loading: false, // 加载
 	total: 0, // 总数
-	data: {
-		aiVisitCount: 0,
-		aiVisitSatisfiedCount: 0,
-		aiVisitNoSatisfiedCount: 0,
-		aiVisitFailCount: 0,
-	},
+	footerData: [],
 });
 /** 搜索按钮操作 */
 const handleQuery = () => {
@@ -128,8 +130,8 @@ const queryList = () => {
 	Reflect.deleteProperty(requestParams.value, 'crTime');
 	departmentVisitZG(requestParams.value)
 		.then((res: any) => {
-			state.tableData = res.result ?? [];
-			state.data = res.result ?? {};
+			state.tableData = res.result?.list ?? [];
+			state.footerData = [res.result?.total] ?? [];
 			state.loading = false;
 		})
 		.catch(() => {
@@ -146,31 +148,29 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 };
 // 查看详情
 const router = useRouter();
-const linkDetail = (row: any, type: string) => {
-	console.log(row, '111');
-	/*	router.push({
-		path: '/statistics/order/detailVisitContentZG',
-		query: {
-			StartTime: requestParams.value.StartTime,
-			EndTime: requestParams.value.EndTime,
-			type,
-			tagsViewName: '回访量统计明细',
-			mode: 'normal',
-		},
-	});*/
-};
-// 计算合计
-const footerMethod = ({ columns, data }) => {
-	return [
-		columns.map((column: any, columnIndex: number) => {
-			if (columnIndex === 0) {
-				return '合计';
-			}
-			if (['callVisitCount', 'defaultVisitCount', 'smsVisitCount', 'totalVisitCount'].includes(column.property)) {
-				return XEUtils.sum(data, column.property);
-			}
-		}),
-	];
+const linkDetail = (row: any, FieldName: string, isFooterData?: boolean) => {
+	if (isFooterData) {
+		router.push({
+			path: '/statistics/order/detailVisitContentZG',
+			query: {
+				StartTime: requestParams.value.StartTime,
+				EndTime: requestParams.value.EndTime,
+				FieldName,
+				tagsViewName: '回访量统计明细',
+			},
+		});
+	} else {
+		router.push({
+			path: '/statistics/order/detailVisitContentZG',
+			query: {
+				StartTime: requestParams.value.StartTime,
+				EndTime: requestParams.value.EndTime,
+				FieldName,
+				tagsViewName: '回访量统计明细',
+				UserId: row.employeeId,
+			},
+		});
+	}
 };
 const toolbarRef = ref<RefType>();
 const tableRef = ref<RefType>();

+ 129 - 112
src/views/statistics/order/detailVisitContentZG.vue

@@ -17,8 +17,8 @@
 						:default-time="defaultTimeStartEnd"
 					/>
 				</el-form-item>
-				<el-form-item label="工单标题" prop="Keyword">
-					<el-input v-model="state.queryParams.Keyword" placeholder="工单标题" clearable @keyup.enter="handleQuery" class="keyword-input" />
+				<el-form-item label="工单标题" prop="Title">
+					<el-input v-model="state.queryParams.Title" placeholder="工单标题" clearable @keyup.enter="handleQuery" class="keyword-input" />
 				</el-form-item>
 				<el-form-item label="工单编码" prop="No">
 					<el-input v-model="state.queryParams.No" placeholder="工单编码" clearable @keyup.enter="handleQuery" class="keyword-input" />
@@ -54,11 +54,11 @@
 					:custom-config="{ storage: true }"
 					showHeaderOverflow
 					:sort-config="{ remote: true }"
-					:params="{ exportMethod: departmentOverdueDetailExport, exportParams: requestParams }"
+					:params="{ exportMethod: departmentVisitZGDetailExport, exportParams: requestParams }"
 				>
 					<vxe-column field="order.expiredStatusText" title="状态" width="60" align="center">
 						<template #default="{ row }">
-							<span :class="'overdue-status-' + row.order?.expiredStatus" :title="row.order.expiredStatusText"></span>
+							<span :class="'overdue-status-' + row.order?.expiredStatus" :title="row.order?.expiredStatusText"></span>
 						</template>
 					</vxe-column>
 					<vxe-column field="statusText" title="工单状态" width="110">
@@ -70,7 +70,7 @@
 						</template>
 					</vxe-column>
 					<vxe-column field="order.sourceChannel" title="来源渠道" width="110"></vxe-column>
-					<vxe-column field="order.sourceChannel" title="当前节点" width="110"></vxe-column>
+					<vxe-column field="order.currentStepName" title="当前节点" width="110"></vxe-column>
 					<vxe-column field="order.no" title="工单编码" width="140"></vxe-column>
 					<vxe-column field="order.creationTime" title="受理时间" width="160">
 						<template #default="{ row }">
@@ -82,17 +82,17 @@
 							<order-detail :order="row.order" @updateList="queryList">{{ row.order?.title }}</order-detail>
 						</template>
 					</vxe-column>
-					<vxe-column field="order.contact" title="联系电话" width="120"></vxe-column>
-					<vxe-column field="order.contact" title="接办部门" width="120"></vxe-column>
-					<vxe-column field="visitTime" title="办结时间" width="160">
+					<vxe-column field="order.fromPhone" title="来电号码" width="120"></vxe-column>
+					<vxe-column field="order.actualHandleOrgName" title="接办部门" width="120"></vxe-column>
+					<vxe-column field="order.filedTime" title="办结时间" width="160">
 						<template #default="{ row }">
-							{{ formatDate(row.visitTime, 'YYYY-mm-dd HH:MM:SS') }}
+							{{ formatDate(row.order?.filedTime, 'YYYY-mm-dd HH:MM:SS') }}
 						</template>
 					</vxe-column>
 					<vxe-column field="employeeName" title="回访人" width="120"></vxe-column>
-					<vxe-column field="employeeName" title="受理类型" width="120"></vxe-column>
-					<vxe-column field="employeeName" title="热点分类" width="150"></vxe-column>
-					<vxe-column field="employeeName" title="受理人" width="120"></vxe-column>
+					<vxe-column field="order.acceptType" title="受理类型" width="120"></vxe-column>
+					<vxe-column field="order.hotspotName" title="热点分类" width="150"></vxe-column>
+					<vxe-column field="order.acceptorName" title="受理人" width="120"></vxe-column>
 					<vxe-column title="操作" fixed="right" width="100" align="center" :show-overflow="false">
 						<template #default="{ row }">
 							<el-button link type="primary" @click="visitDetail(row)" title="查看回访详情"> 回访详情 </el-button>
@@ -113,9 +113,32 @@
 		<!--	更多查询	-->
 		<el-drawer v-model="drawer" title="更多查询" size="500px">
 			<el-form :model="state.queryParams" ref="drawerRuleFormRef" @submit.native.prevent label-width="100px" :disabled="state.loading">
-				<el-form-item label="受理时间" prop="crTime">
+				<el-form-item label="接办部门" prop="ActualHandleOrgName">
+					<el-input v-model="state.queryParams.ActualHandleOrgName" placeholder="接办部门" clearable @keyup.enter="handleQuery" />
+				</el-form-item>
+				<el-form-item label="受理类型" prop="AcceptType">
+					<el-select v-model="state.queryParams.AcceptType" placeholder="请选择受理类型" clearable class="w100" @change="handleQuery">
+						<el-option v-for="item in state.acceptTypeOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+					</el-select>
+				</el-form-item>
+				<el-form-item label="受理人" prop="AcceptorName">
+					<el-input v-model="state.queryParams.AcceptorName" placeholder="受理人" clearable @keyup.enter="handleQuery" />
+				</el-form-item>
+				<el-form-item label="接办人" prop="ActualHandlerName">
+					<el-input v-model="state.queryParams.ActualHandlerName" placeholder="接办人" clearable @keyup.enter="handleQuery" />
+				</el-form-item>
+				<el-form-item label="来电号码" prop="FromPhone">
+					<el-input v-model="state.queryParams.FromPhone" placeholder="来电号码" clearable @keyup.enter="handleQuery" />
+				</el-form-item>
+				<el-form-item label="联系电话" prop="Contact">
+					<el-input v-model="state.queryParams.Contact" placeholder="联系电话" clearable @keyup.enter="handleQuery" />
+				</el-form-item>
+				<el-form-item label="来电人姓名" prop="FromName">
+					<el-input v-model="state.queryParams.FromName" placeholder="来电人姓名" clearable @keyup.enter="handleQuery" />
+				</el-form-item>
+				<el-form-item label="受理时间" prop="slTime">
 					<el-date-picker
-						v-model="state.queryParams.crTime"
+						v-model="state.queryParams.slTime"
 						type="datetimerange"
 						unlink-panels
 						range-separator="至"
@@ -127,63 +150,9 @@
 						:default-time="defaultTimeStartEnd"
 					/>
 				</el-form-item>
-				<el-form-item label="部门分类" prop="OrgVisitStatisticsType">
-					<el-select v-model="state.queryParams.OrgVisitStatisticsType" placeholder="请选择部门分类" @change="handleQuery" clearable>
-						<el-option label="中心归档" value="10" />
-						<el-option label="部门归档" value="20" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="来源渠道" prop="Channel">
-					<el-select v-model="state.queryParams.Channel" placeholder="请选择来源渠道" clearable @change="handleQuery">
-						<el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="回访人姓名" prop="VisitUser">
-					<el-input v-model="state.queryParams.VisitUser" placeholder="回访人姓名" clearable @keyup.enter="handleQuery" />
-				</el-form-item>
-				<el-form-item label="查询类型" prop="AttitudeType">
-					<el-select v-model="state.queryParams.AttitudeType" placeholder="请选择查询类型">
-						<el-option v-for="item in state.attitudeType" :value="item.key" :key="item.key" :label="item.value" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="办件结果" prop="OrgProcessingResults" v-if="state.queryParams.AttitudeType === 1">
-					<el-select v-model="state.queryParams.OrgProcessingResults" placeholder="请选择办件结果" multiple clearable>
-						<el-option
-							v-for="item in state.visitSatisfaction"
-							:value="item.dicDataValue"
-							:key="item.dicDataValue"
-							:label="item.dicDataName"
-						></el-option>
-					</el-select>
-				</el-form-item>
-				<el-form-item label="办件态度" prop="OrgProcessingResults" v-if="state.queryParams.AttitudeType === 2">
-					<el-select v-model="state.queryParams.OrgProcessingResults" placeholder="请选择办件态度" multiple clearable>
-						<el-option v-for="item in state.visitMananer" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName"></el-option>
-					</el-select>
-				</el-form-item>
-				<el-form-item label="热点分类" prop="Hotspot">
-					<el-input v-model="state.queryParams.Hotspot" placeholder="热点分类名称" clearable @keyup.enter="handleQuery" />
-				</el-form-item>
-				<el-form-item label="接办部门" prop="ActualHandleOrgName">
-					<el-input v-model="state.queryParams.ActualHandleOrgName" placeholder="接办部门" clearable @keyup.enter="handleQuery" />
-				</el-form-item>
-				<el-form-item label="回访部门" prop="OrgId">
-					<el-cascader
-						:options="state.orgsOptions"
-						filterable
-						:show-all-levels="false"
-						:props="{ checkStrictly: true, value: 'id', label: 'name', emitPath: false }"
-						placeholder="请选择回访部门"
-						clearable
-						class="w100"
-						v-model="state.queryParams.OrgId"
-						@change="handleQuery"
-					>
-					</el-cascader>
-				</el-form-item>
-				<el-form-item label="办结时间" prop="doneTime">
+				<el-form-item label="期满时间" prop="qmTime">
 					<el-date-picker
-						v-model="state.queryParams.doneTime"
+						v-model="state.queryParams.qmTime"
 						type="datetimerange"
 						unlink-panels
 						range-separator="至"
@@ -195,32 +164,9 @@
 						:default-time="defaultTimeStartEnd"
 					/>
 				</el-form-item>
-				<el-form-item label="来电主体" prop="TypeCode">
-					<el-select v-model="state.queryParams.TypeCode" 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 label="省/市工单" prop="IsProvinceOrder">
-					<el-select v-model="state.queryParams.IsProvinceOrder" placeholder="请选择省/市工单" clearable @change="handleQuery">
-						<el-option :value="true" label="省工单" />
-						<el-option :value="false" label="市工单" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="来源渠道" prop="SourceChannelCode">
-					<el-select v-model="state.queryParams.SourceChannelCode" placeholder="请选择来源渠道" clearable class="w100" @change="handleQuery">
-						<el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="受理类型" prop="AcceptTypeCode">
-					<el-select v-model="state.queryParams.AcceptTypeCode" placeholder="请选择受理类型" clearable class="w100" @change="handleQuery">
-						<el-option v-for="item in state.acceptTypeOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="不满意原因" prop="OrgNoSatisfiedReason">
-					<el-select v-model="state.queryParams.OrgNoSatisfiedReason" placeholder="请选择不满意原因" clearable class="w100" @change="handleQuery">
-						<el-option v-for="item in state.dissatisfiedReason" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+				<el-form-item label="工单状态" prop="Status">
+					<el-select v-model="state.queryParams.Status" placeholder="请选择工单状态" clearable @change="handleQuery">
+						<el-option v-for="item in state.orderStatusOptions" :value="item.key" :key="item.key" :label="item.value" />
 					</el-select>
 				</el-form-item>
 				<el-form-item label="事发地址" prop="AreaCode">
@@ -236,20 +182,45 @@
 					>
 					</el-cascader>
 				</el-form-item>
-				<el-form-item label="回访内容" prop="ContentRetrieval">
-					<el-input v-model="state.queryParams.ContentRetrieval" placeholder="回访内容" clearable @keyup.enter="handleQuery" />
-				</el-form-item>
-				<el-form-item label="回访方式" prop="VisitType">
-					<el-select v-model="state.queryParams.VisitType" placeholder="请选择回访方式" clearable class="w100" @change="handleQuery">
-						<el-option v-for="item in state.visitType" :value="item.key" :key="item.key" :label="item.value" />
+				<el-form-item label="来源渠道" prop="Channel">
+					<el-select v-model="state.queryParams.Channel" placeholder="请选择来源渠道" clearable @change="handleQuery">
+						<el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
 					</el-select>
 				</el-form-item>
 				<el-form-item label="是否甄别" prop="IsScreen">
-					<el-select v-model="state.queryParams.IsScreen" placeholder="请选择是否甄别" @change="handleQuery" clearable>
+					<el-select v-model="state.queryParams.IsScreen" placeholder="请选择是否甄别" clearable @change="handleQuery">
 						<el-option label="是" :value="true" />
 						<el-option label="否" :value="false" />
 					</el-select>
 				</el-form-item>
+				<el-form-item label="当前节点" prop="CurrentStepName">
+					<el-select v-model="state.queryParams.CurrentStepName" placeholder="请选择当前节点" clearable @change="handleQuery">
+						<el-option v-for="item in state.currentStepOptions" :value="item.value" :key="item.key" :label="item.value" />
+					</el-select>
+				</el-form-item>
+				<el-form-item label="办结时间" prop="doneTime">
+					<el-date-picker
+						v-model="state.queryParams.doneTime"
+						type="datetimerange"
+						unlink-panels
+						range-separator="至"
+						start-placeholder="开始时间"
+						end-placeholder="结束时间"
+						:shortcuts="shortcuts"
+						@change="handleQuery"
+						value-format="YYYY-MM-DD[T]HH:mm:ss"
+						:default-time="defaultTimeStartEnd"
+					/>
+				</el-form-item>
+				<el-form-item label="热点分类" prop="Hotspot">
+					<el-input v-model.trim="state.queryParams.Hotspot" placeholder="热点分类名称" clearable @keyup.enter="handleQuery" />
+				</el-form-item>
+				<el-form-item label="是否紧急" prop="IsUrgent">
+					<el-select v-model="state.queryParams.IsUrgent" placeholder="请选择是否紧急" clearable @change="handleQuery">
+						<el-option :value="true" label="紧急" />
+						<el-option :value="false" label="不紧急" />
+					</el-select>
+				</el-form-item>
 			</el-form>
 			<template #footer>
 				<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
@@ -263,10 +234,11 @@ import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import { FormInstance } from 'element-plus';
 import { formatDate } from '@/utils/formatTime';
 import { useRoute } from 'vue-router';
-import { departmentOverdueDetailExport } from '@/api/statistics/department';
 import { defaultDate, defaultTimeStartEnd, shortcuts } from '@/utils/constants';
-import { departmentVisitDetailSmart } from '@/api/statistics/order';
+import { departmentVisitZGDetail, departmentVisitZGDetailExport } from '@/api/statistics/order';
 import other from '@/utils/other';
+import { listBaseData } from '@/api/business/order';
+import { treeArea } from '@/api/auxiliary/area';
 
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
@@ -283,10 +255,39 @@ const state = reactive<any>({
 		crTime: defaultDate,
 		StartTime: null,
 		EndTime: null,
+		No: null, // 工单编码
+		Title: null, // 工单标题
+		ActualHandleOrgName: null, // 接办部门
+		AcceptType: null, // 受理类型
+		AcceptorName: null, // 受理人
+		ActualHandlerName: null, // 接办人
+		FromPhone: null, // 来电号码
+		Contact: null, // 联系电话
+		FromName: null, // 来电人姓名
+		slTime: [], // 受理时间
+		CreationTimeStart: null, // 受理时间开始
+		CreationTimeEnd: null, // 受理时间结束
+		qmTime: [], // 期满时间
+		ExpiredTimeStart: null, // 期满时间开始
+		ExpiredTimeEnd: null, // 期满时间结束
+		Status: null, // 工单状态
+		AreaCode: null, // 事发地址
+		Channel: null, // 来源渠道
+		IsScreen: null, // 是否甄别
+		CurrentStepName: null, // 当前节点
+		doneTime: [], // 办结时间
+		FiledTimeStart: null, // 办结时间开始
+		FiledTimeEnd: null, // 办结时间结束
+		Hotspot: null, // 热点分类
+		IsUrgent: null, // 是否紧急
 	},
 	tableData: [], //表单
 	loading: false, // 加载
 	total: 0, // 总数
+	acceptTypeOptions: [], // 受理类型
+	channelOptions: [], // 来源渠道
+	orderStatusOptions: [], // 工单状态
+	areaOptions: [], // 事发地址
 });
 // 手动查询,将页码设置为1
 const handleQuery = () => {
@@ -302,15 +303,11 @@ const queryList = () => {
 	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];
+	requestParams.value.UserId = routeQueryParams.UserId;
 	Reflect.deleteProperty(requestParams.value, 'crTime');
-	departmentVisitDetailSmart(requestParams.value)
+	departmentVisitZGDetail(requestParams.value)
 		.then((res) => {
 			state.tableData = res.result?.items ?? [];
-			state.tableData = state.tableData.map((item: any) => {
-				return {
-					...item.orderVisit,
-				};
-			});
 			state.total = res.result?.total ?? 0;
 			state.loading = false;
 		})
@@ -336,7 +333,26 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 // 回访详情
 const visitDetailRef = ref<RefType>();
 const visitDetail = (row: any) => {
-	visitDetailRef.value.openDialog({ ...row, id: row.visitId }, '回访详情');
+	visitDetailRef.value.openDialog(row, '回访详情');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+	try {
+		const { result } = await listBaseData();
+		const mappings: any = {
+			acceptTypeOptions: 'acceptTypeOptions',
+			channelOptions: 'channelOptions',
+			orderStatusOptions: 'orderStatusOptions',
+			currentStepOptions: 'currentStepOptions',
+		};
+		for (const key in mappings) {
+			state[key] = result?.[mappings[key]] ?? [];
+		}
+		const area = await treeArea();
+		state.areaOptions = area?.result ?? []; //省市区数据
+	} catch (error) {
+		console.log(error);
+	}
 };
 onMounted(async () => {
 	if (routeQueryParams.StartTime && routeQueryParams.EndTime) {
@@ -346,5 +362,6 @@ onMounted(async () => {
 	if (tableRef.value && toolbarRef.value) {
 		tableRef.value.connect(toolbarRef.value);
 	}
+	await getBaseData();
 });
 </script>