瀏覽代碼

reactor:415 在回访列表增加【修改记录】功能等

zhangchong 1 月之前
父節點
當前提交
f64662f170

+ 30 - 0
.env.demo

@@ -0,0 +1,30 @@
+# 演示
+VITE_MODE_NAME=demo
+# 防止部署多套系统到同一域名不同目录时,变量共用的问题 设置不同的前缀
+VITE_STORAGE_NAME=demo
+# 业务系统基础请求地址
+VITE_API_URL=http://110.188.24.28:50201
+# 业务系统socket请求地址
+VITE_API_SOCKET_URL=http://110.188.24.28:50201/hubs/hotline
+# 业务系统文件上传上传请求地址
+VITE_API_UPLOAD_URL=http://110.188.24.28:50120
+# 数据共享平台请求地址
+VITE_DATASHARE_API_YRL=http://110.188.24.28:50105
+# 高德地图安全密钥
+VITE_AMAP_SECURITYJSCODE=dd12ddafb11921dbcdc5b9c4484bb4e2
+# 高德地图KEY
+VITE_AMAP_KEY=83f51df235e4008e4eaf515cff63785c
+# 捷通华声智能客服登录地址
+VITE_VOICE_ASSISTANT_API_URL=http://118.121.59.30:19081
+# 捷通华声智能客服socket地址
+VITE_VOICE_ASSISTANT_SOCKET_URL=ws://118.121.59.30:19005
+# 捷通华声错别字检测请求地址
+VITE_JTHS_ERROR_WORD_URL=http://118.122.73.80:19102
+# 捷通华声错别字检测请求签名
+VITE_JTHS_ERROR_WORD_SIGN=327c474854be9e3c259b34b9df025236b7321a55
+# 捷通华声错别字检测请求Nonce
+VITE_JTHS_ERROR_WORD_NONCE=726061.054747415
+# 捷通华声错别字检测请求KEY
+VITE_JTHS_ERROR_WORD_KEY=MTAwMDAw
+# 12345大模型热线赋智请求地址
+VITE_RXFZ_API_URL=https://rxfz.scopenai.com:18027/third

+ 1 - 1
.env.development

@@ -3,7 +3,7 @@ VITE_MODE_NAME=development
 # 防止部署多套系统到同一域名不同目录时,变量共用的问题 设置不同的前缀
 VITE_STORAGE_NAME=dev
 # 业务系统基础请求地址
-VITE_API_URL=http://110.188.24.28:50300
+VITE_API_URL=http://110.188.24.28:50100
 # 业务系统socket请求地址
 VITE_API_SOCKET_URL=http://110.188.24.28:50100/hubs/hotline
 # 业务系统文件上传上传请求地址

+ 1 - 1
.env.production

@@ -1,7 +1,7 @@
 # 测试环境
 VITE_MODE_NAME=production
 # 防止部署多套系统到同一域名不同目录时,变量共用的问题 设置不同的前缀
-VITE_STORAGE_NAME=test
+VITE_STORAGE_NAME=production
 # 业务系统基础请求地址
 VITE_API_URL=http://110.188.24.28:50100
 # 业务系统socket请求地址

+ 30 - 0
.env.test

@@ -0,0 +1,30 @@
+# 测试环境
+VITE_MODE_NAME=test
+# 防止部署多套系统到同一域名不同目录时,变量共用的问题 设置不同的前缀
+VITE_STORAGE_NAME=test
+# 业务系统基础请求地址
+VITE_API_URL=http://110.188.24.28:50200
+# 业务系统socket请求地址
+VITE_API_SOCKET_URL=http://110.188.24.28:50200/hubs/hotline
+# 业务系统文件上传上传请求地址
+VITE_API_UPLOAD_URL=http://110.188.24.28:50120
+# 数据共享平台请求地址
+VITE_DATASHARE_API_YRL=http://110.188.24.28:50105
+# 高德地图安全密钥
+VITE_AMAP_SECURITYJSCODE=dd12ddafb11921dbcdc5b9c4484bb4e2
+# 高德地图KEY
+VITE_AMAP_KEY=83f51df235e4008e4eaf515cff63785c
+# 捷通华声智能客服登录地址
+VITE_VOICE_ASSISTANT_API_URL=http://118.121.59.30:19081
+# 捷通华声智能客服socket地址
+VITE_VOICE_ASSISTANT_SOCKET_URL=ws://118.121.59.30:19005
+# 捷通华声错别字检测请求地址
+VITE_JTHS_ERROR_WORD_URL=http://118.122.73.80:19102
+# 捷通华声错别字检测请求签名
+VITE_JTHS_ERROR_WORD_SIGN=327c474854be9e3c259b34b9df025236b7321a55
+# 捷通华声错别字检测请求Nonce
+VITE_JTHS_ERROR_WORD_NONCE=726061.054747415
+# 捷通华声错别字检测请求KEY
+VITE_JTHS_ERROR_WORD_KEY=MTAwMDAw
+# 12345大模型热线赋智请求地址
+VITE_RXFZ_API_URL=https://rxfz.scopenai.com:18027/third

+ 2 - 0
package.json

@@ -11,6 +11,8 @@
 		"build:zigong": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode zigong",
 		"build:luzhou": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode luzhou",
 		"build:st": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode st",
+		"build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test",
+		"build:demo": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode demo",
 		"preview": "vite preview",
 		"serve": "http-server ./dist",
 		"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"

+ 10 - 0
src/api/business/visit.ts

@@ -188,4 +188,14 @@ export const visitDepartmentSatisfactionListExport = (data: object) => {
     }, {
         reduce_data_format: false
     });
+}
+/**
+ * @description 部门满意度统计明细列表导出
+ * @param {string} id
+ */
+export const visitChangeRecord = (id: string) => {
+    return request({
+        url: `/api/v1/Order/getordervisitdetailcopy/${id}`,
+        method: 'get'
+    });
 }

+ 13 - 4
src/views/business/visit/components/Visit-detail.vue

@@ -80,7 +80,11 @@
 										type="primary"
 										class="ml8"
 										@click="recordFile"
-										v-if="['ZiGong','LuZhou'].includes(themeConfig.appScope) ? state.recordingAbsolutePath && userInfos.isCenter : state.recordingAbsolutePath"
+										v-if="
+											['ZiGong', 'LuZhou'].includes(themeConfig.appScope)
+												? state.recordingAbsolutePath && userInfos.isCenter
+												: state.recordingAbsolutePath
+										"
 										>人工回访录音</el-button
 									>
 								</el-form-item>
@@ -137,7 +141,9 @@
 											class="ml8"
 											@click="recordFile"
 											v-if="
-												['ZiGong','LuZhou'].includes(themeConfig.appScope) ? state.recordingAbsolutePath && userInfos.isCenter : state.recordingAbsolutePath
+												['ZiGong', 'LuZhou'].includes(themeConfig.appScope)
+													? state.recordingAbsolutePath && userInfos.isCenter
+													: state.recordingAbsolutePath
 											"
 											>人工回访录音</el-button
 										>
@@ -293,7 +299,9 @@
 											class="ml8"
 											@click="recordFile"
 											v-if="
-												['ZiGong','LuZhou'].includes(themeConfig.appScope) ? state.recordingAbsolutePath && userInfos.isCenter : state.recordingAbsolutePath
+												['ZiGong', 'LuZhou'].includes(themeConfig.appScope)
+													? state.recordingAbsolutePath && userInfos.isCenter
+													: state.recordingAbsolutePath
 											"
 											>人工回访录音</el-button
 										>
@@ -550,7 +558,7 @@
 				<template v-if="['ZiGong', 'LuZhou'].includes(themeConfig.appScope)">
 					<el-popconfirm title="您确定将当前回访设置为未接通?" @confirm="notConnected" width="260">
 						<template #reference>
-							<el-button type="primary" :loading="state.loading"  v-auth="'business:visit:notConnected'">设为未接通</el-button>
+							<el-button type="primary" :loading="state.loading" v-auth="'business:visit:notConnected'">设为未接通</el-button>
 						</template>
 					</el-popconfirm>
 				</template>
@@ -817,6 +825,7 @@ const onSubmit = (formEl: FormInstance | undefined) => {
 			// isPutThrough: !state.ruleForm.isPutThrough,
 			...state.visitDetails,
 			id: visitId.value,
+			isUpdate: dialogTitle.value === '修改回访结果',
 		};
 		if (callId.value) {
 			request.callId = callId.value;

+ 201 - 0
src/views/business/visit/components/Visit-edit-record.vue

@@ -0,0 +1,201 @@
+<template>
+	<el-dialog v-model="state.dialogVisible" draggable title="回访修改记录" @close="close" destroy-on-close>
+		<div v-loading="state.loading">
+			<p class="border-title">修改前</p>
+			<el-row :gutter="10" class="show-info-form pd15">
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-row v-for="item in state.orderVisitDetailCopyDtos" :key="item.id" :gutter="10">
+						<!-- 务员评价 -->
+						<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="['ZiGong'].includes(themeConfig.appScope) && item.visitTarget === 10">
+							<el-form-item label="语音评价"> {{ item.voiceEvaluateText }} </el-form-item>
+						</el-col>
+						<template v-if="item.visitTarget === 10 && isTelSource">
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="话务员评价">
+									{{ item.seatEvaluateText }}
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-form-item label="话务员回访内容">
+									{{ item.visitContent }}
+								</el-form-item>
+							</el-col>
+						</template>
+						<!-- 部门评价 -->
+						<template v-if="item.visitTarget === 20">
+							<div class="w100 mt10 mb10" style="height: 1px; border: 1px dashed #b2b2b2"></div>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-form-item label="回访部门">
+									{{ item.visitOrgName }}
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="部门办件结果">
+									{{ item.orgProcessingResultsText }}
+								</el-form-item>
+							</el-col>
+							<!-- 不满意才会选择不满意原因 -->
+							<el-col
+								:xs="24"
+								:sm="24"
+								:md="24"
+								:lg="12"
+								:xl="12"
+								v-if="item.orgNoSatisfiedReason && item.orgNoSatisfiedReason.length && item.orgProcessingResults?.value === '不满意'"
+							>
+								<el-form-item label="不满意原因">
+									{{ item.orgNoSatisfiedReasonText }}
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="['ZiGong'].includes(themeConfig.appScope)">
+								<el-form-item label="部门办件态度">
+									{{ item.orgHandledAttitude?.value }}
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-form-item label="部门回访内容">
+									{{ item.visitContent }}
+								</el-form-item>
+							</el-col>
+						</template>
+					</el-row>
+				</el-col>
+			</el-row>
+			<p class="border-title mt20">修改后</p>
+			<el-row :gutter="10" class="show-info-form pd20">
+				<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
+					<el-form-item label="修改人">
+						{{ state.orderVisitModel.creatorName }}
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
+					<el-form-item label="修改时间">
+						{{ formatDate(state.orderVisitModel.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+					<el-row v-for="item in state.orderVisitDetailDtos" :key="item.id" :gutter="10">
+						<!-- 务员评价 -->
+						<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="['ZiGong'].includes(themeConfig.appScope) && item.visitTarget === 10">
+							<el-form-item label="语音评价"> {{ item.voiceEvaluateText }} </el-form-item>
+						</el-col>
+						<template v-if="item.visitTarget === 10 && isTelSource">
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="话务员评价">
+									{{ item.seatEvaluateText }}
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-form-item label="话务员回访内容">
+									{{ item.visitContent }}
+								</el-form-item>
+							</el-col>
+						</template>
+						<!-- 部门评价 -->
+						<template v-if="item.visitTarget === 20">
+							<div class="w100 mt10 mb10" style="height: 1px; border: 1px dashed #b2b2b2"></div>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-form-item label="回访部门">
+									{{ item.visitOrgName }}
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="部门办件结果">
+									{{ item.orgProcessingResultsText }}
+								</el-form-item>
+							</el-col>
+							<!-- 不满意才会选择不满意原因 -->
+							<el-col
+								:xs="24"
+								:sm="24"
+								:md="24"
+								:lg="12"
+								:xl="12"
+								v-if="item.orgNoSatisfiedReason && item.orgNoSatisfiedReason.length && item.orgProcessingResults?.value === '不满意'"
+							>
+								<el-form-item label="不满意原因">
+									{{ item.orgNoSatisfiedReasonText }}
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="['ZiGong'].includes(themeConfig.appScope)">
+								<el-form-item label="部门办件态度">
+									{{ item.orgHandledAttitude?.value }}
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-form-item label="部门回访内容">
+									{{ item.visitContent }}
+								</el-form-item>
+							</el-col>
+						</template>
+					</el-row>
+				</el-col>
+			</el-row>
+		</div>
+		<template #footer>
+			<span class="dialog-footer">
+				<el-button @click="closeDialog" class="default-button">关 闭</el-button>
+			</span>
+		</template>
+	</el-dialog>
+</template>
+<script setup lang="tsx">
+import { computed, reactive } from 'vue';
+import { ElMessage } from 'element-plus';
+import { storeToRefs } from 'pinia';
+import { visitChangeRecord } from '@/api/business/visit';
+import { useThemeConfig } from '@/stores/themeConfig';
+import { formatDate } from '@/utils/formatTime';
+
+// 定义变量内容
+const state = reactive<any>({
+	dialogVisible: false, // 是否显示弹窗
+	loading: false, // 是否显示加载
+	ruleForm: {
+		visitDetails: {},
+		orgJudge: false, // 扭转部门满意度
+		seatJudge: false, // 扭转坐席满意度
+	},
+	orderVisitModel: {}, // 回访详情
+	orderVisitDetailCopyDtos: {}, // 修改前
+	orderVisitDetailDtos: {}, // 修改后
+});
+const storesThemeConfig = useThemeConfig();
+const { themeConfig } = storeToRefs(storesThemeConfig);
+const getBaseData = async (id: string) => {
+	state.loading = true;
+	try {
+		const { result } = await visitChangeRecord(id);
+		state.orderVisitModel = result;
+		state.orderVisitDetailCopyDtos = result.orderVisitDetailCopyDtos;
+		state.orderVisitDetailDtos = result.orderVisitDetailDtos;
+		state.loading = false;
+	} catch (error) {
+		console.log(error);
+		state.loading = false;
+	}
+};
+// 判断当前工单是否是电话来源
+const isTelSource = computed(() => {
+	return state.orderDetail?.sourceChannelCode === 'RGDH';
+});
+// 打开弹窗
+const openDialog = (row: any) => {
+	if (!row.id || !row) {
+		ElMessage.warning('传入回访ID不正确');
+		return;
+	}
+	state.dialogVisible = true;
+	getBaseData(row.id);
+};
+// 关闭弹窗
+const closeDialog = () => {
+	state.dialogVisible = false;
+};
+const close = () => {};
+
+defineExpose({
+	openDialog,
+	closeDialog,
+});
+</script>

+ 20 - 1
src/views/business/visit/index.vue

@@ -55,6 +55,9 @@
 					>
 						修改回访结果
 					</el-button>
+					<el-button link type="primary" @click="updateRecord(row)" title="修改记录" v-auth="'business:visit:visitEditRecord'" v-show="row.isUpdate">
+						修改记录
+					</el-button>
 				</template>
 				<template #pager>
 					<pagination
@@ -188,6 +191,12 @@
 						<el-option label="否" :value="false" />
 					</el-select>
 				</el-form-item>
+				<el-form-item label="是否有修改记录" prop="IsUpdate" v-if="['ZiGong','LuZhou'].includes(themeConfig.appScope)" label-width="110px">
+					<el-select v-model="state.queryParams.IsUpdate" placeholder="请选择是否有修改记录" class="w100" clearable @change="handleQuery">
+						<el-option label="是" :value="true" />
+						<el-option label="否" :value="false" />
+					</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>
@@ -196,6 +205,8 @@
 		</el-drawer>
 		<!-- 回访详情 -->
 		<visit-detail-com ref="visitDetailRef" @updateList="refreshList" />
+		<!-- 修改记录 -->
+		<visit-edit-record ref="visitEditRecordRef" />
 	</div>
 </template>
 
@@ -212,6 +223,7 @@ import { storeToRefs } from 'pinia';
 const VisitDetailCom = defineAsyncComponent(() => import('@/views/business/visit/components/Visit-detail.vue')); // 回访
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
 const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
+const VisitEditRecord = defineAsyncComponent(() => import('@/views/business/visit/components/Visit-edit-record.vue')); // 修改记录
 
 // 定义变量内容
 const fastSearch = ref('all'); // tab位置
@@ -261,6 +273,7 @@ const state = reactive<any>({
 		CreationTimeStart: null,
 		CreationTimeEnd: null,
 		OrderTagCode: null,
+		IsUpdate:null, // 是否有修改记录
 	},
 	tableData: [], //表单
 	loading: false, // 加载
@@ -381,10 +394,11 @@ if (['YiBin'].includes(themeConfig.value.appScope)) {
 	gridOptions.columns = gridOptions.columns.filter((item: any) => item.field !== 'isEffectiveAiVisitText');
 	gridOptions.columns.push({
 		title: '操作',
-		width: 200,
+		width: 260,
 		fixed: 'right',
 		align: 'center',
 		slots: { default: 'action' },
+		showOverflow: false,
 	});
 }
 // 获取基础数据
@@ -466,6 +480,11 @@ const visitDetail = (row: any) => {
 const updateVisitResult = (row: any) => {
 	visitDetailRef.value.openDialog(row, '修改回访结果');
 };
+// 查看修改记录
+const visitEditRecordRef = ref<RefType>();
+const updateRecord = (row: any) => {
+	visitEditRecordRef.value.openDialog(row);
+};
 onMounted(() => {
 	queryList().then(() => {
 		getBaseData();