Browse Source

reactor:智能回访菜单调整;

zhangchong 1 năm trước cách đây
mục cha
commit
668e723e08

+ 125 - 0
src/views/business/visit/component/Smart-visit-Detail.vue

@@ -0,0 +1,125 @@
+<template>
+	<el-dialog v-model="state.dialogVisible" width="60%" draggable title="回访明细" append-to-body destroy-on-close>
+		<el-form :model="state.queryParams" ref="queryParamsRef" inline @submit.native.prevent>
+			<el-form-item label="关键词" prop="Keyword">
+				<el-input v-model="state.queryParams.Keyword" placeholder="工单标题/工单编码" clearable @keyup.enter="queryList" />
+			</el-form-item>
+			<el-form-item>
+				<el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+				<el-button @click="resetQuery(queryParamsRef)" :loading="state.loading" class="default-button">
+					<SvgIcon name="ele-Refresh" class="mr5" />重置
+				</el-button>
+			</el-form-item>
+		</el-form>
+		<el-table :data="state.tableData" v-loading="state.loading">
+			<el-table-column prop="order.no" label="工单编码" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column label="标题" show-overflow-tooltip width="300">
+				<template #default="{ row }">
+					<order-detail :order="row.order">{{ row.order?.title }}</order-detail>
+				</template>
+			</el-table-column>
+			<el-table-column prop="aiOrderVisitStateText" label="外呼状态" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column prop="outerNo" label="外呼电话" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column prop="order.fromName" label="姓名" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column prop="order.fromGenderText" label="性别" show-overflow-tooltip width="150"></el-table-column>
+			<!--      <el-table-column label="短信发送时间" show-overflow-tooltip width="170">
+        <template #default="{ row }">
+          <span>{{ formatDate(row.order?.startTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+        </template>
+      </el-table-column>-->
+			<el-table-column label="受理时间" show-overflow-tooltip width="170">
+				<template #default="{ row }">
+					<span>{{ formatDate(row.order?.startTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column label="办结时间" show-overflow-tooltip width="170">
+				<template #default="{ row }">
+					<span>{{ formatDate(row.order?.filedTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column prop="order.actualOpinion" label="办件结果" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column label="话务员评价" show-overflow-tooltip width="120">
+				<template #default="{ row }">
+					<span v-for="item in row.orderVisit?.orderVisitDetails">
+						<span v-if="item.visitTarget === 10">{{ item.seatEvaluateText }}</span>
+					</span>
+				</template>
+			</el-table-column>
+			<el-table-column label="部门办件结果" show-overflow-tooltip width="170">
+				<template #default="{ row }">
+					<span v-for="item in row.orderVisit?.orderVisitDetails">
+						<span v-if="item.visitTarget === 20">{{ item.orgProcessingResults.value }}</span>
+					</span>
+				</template>
+			</el-table-column>
+			<el-table-column label="部门办件态度" show-overflow-tooltip width="170">
+				<template #default="{ row }">
+					<span v-for="item in row.orderVisit?.orderVisitDetails">
+						<span v-if="item.visitTarget === 20">{{ item.orgHandledAttitude.value }}</span>
+					</span>
+				</template>
+			</el-table-column>
+		</el-table>
+		<!-- 分页 -->
+		<pagination
+			@pagination="queryList"
+			:total="state.total"
+			v-model:current-page="state.queryParams.PageIndex"
+			v-model:page-size="state.queryParams.PageSize"
+		/>
+	</el-dialog>
+</template>
+<script setup lang="ts">
+import { formatDate } from '@/utils/formatTime';
+import { ElInput, FormInstance } from 'element-plus';
+import { defineAsyncComponent, reactive, ref } from 'vue';
+import { getSmartVisitDetail } from '@/api/smartVisit';
+
+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: 10,
+		Keyword: null, // 关键字
+		id: '',
+	},
+	tableData: [], //表格
+	loading: false, // 加载
+	total: 0, // 总数
+	dialogVisible: false, // 弹窗
+});
+// 打开弹窗
+const openDialog = (row?: any) => {
+	if (row) {
+		state.queryParams.id = row.id;
+		queryList();
+	}
+};
+// 查询智能回访明细表
+const queryList = async () => {
+	state.dialogVisible = true;
+	try {
+		state.loading = true;
+		const res = await getSmartVisitDetail(state.queryParams);
+		state.tableData = res.result.items ?? [];
+		state.total = res.result.total ?? 0;
+		state.loading = false;
+	} catch (e) {
+		console.log(e);
+		state.loading = false;
+	}
+};
+// 重置所有工单列表
+const queryParamsRef = ref<RefType>();
+const resetQuery = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	queryList();
+};
+
+defineExpose({
+	openDialog,
+});
+</script>

+ 191 - 0
src/views/business/visit/component/Smart-visit-add.vue

@@ -0,0 +1,191 @@
+<template>
+	<el-dialog v-model="state.dialogVisible" width="60%" draggable title="新增智能回访任务" @close="close" append-to-body destroy-on-close>
+		<el-form :model="state.ruleForm" label-width="90px" ref="ruleFormRef" v-loading="state.loading">
+			<el-row :gutter="10">
+				<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+					<el-form-item label="任务名称" prop="name" :rules="[{ required: true, message: '请输入任务名称', trigger: 'blur' }]">
+						<el-input v-model="state.ruleForm.name" placeholder="请输入任务名称" clearable></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+					<el-form-item label="时间段" prop="crTime" :rules="[{ required: true, message: '请选择时间段', trigger: 'change' }]">
+						<el-date-picker
+							v-model="state.ruleForm.crTime"
+							type="datetimerange"
+							unlink-panels
+							range-separator="至"
+							start-placeholder="开始时间"
+							end-placeholder="结束时间"
+							:shortcuts="shortcuts"
+							value-format="YYYY-MM-DD[T]HH:mm:ss"
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+					<el-form-item label="节日禁呼" prop="festivalBan" :rules="[{ required: true, message: '请选择节日禁呼', trigger: 'change' }]">
+						<el-radio-group v-model="state.ruleForm.festivalBan">
+							<el-radio :label="1">是</el-radio>
+							<el-radio :label="0">否</el-radio>
+						</el-radio-group>
+					</el-form-item>
+				</el-col>
+			</el-row>
+		</el-form>
+		<el-divider content-position="left" class="mb30">
+			<el-text tag="b" size="large"> 回访任务名单 </el-text>
+		</el-divider>
+		<el-table :data="state.tableData" v-loading="state.loading" row-key="id" @selection-change="handleSelectionChange" ref="multipleTableRef">
+			<el-table-column type="selection" label="" width="55" :reserve-selection="true" />
+			<el-table-column prop="order.no" label="工单编码" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column label="标题" show-overflow-tooltip width="300">
+				<template #default="{ row }">
+          <order-detail :order="row.order" @updateList="queryList">{{ row.order?.title }}</order-detail>
+				</template>
+			</el-table-column>
+			<el-table-column prop="order.sourceChannel" label="来源方式" show-overflow-tooltip></el-table-column>
+			<el-table-column prop="visitStateText" label="回访状态" show-overflow-tooltip></el-table-column>
+			<!--      <el-table-column label="短信发送时间" show-overflow-tooltip width="170">
+        <template #default="{ row }">
+          <span>{{ formatDate(row.order?.startTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+        </template>
+      </el-table-column>-->
+			<el-table-column prop="order.acceptType" label="受理类型" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column prop="order.hotspotName" label="热点分类" show-overflow-tooltip width="100"></el-table-column>
+			<el-table-column prop="order.actualHandleStepName" label="办理节点" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column prop="order.employeeName" label="受理人" show-overflow-tooltip width="120">
+				<template #default="{ row }">
+					<span
+						>{{ row.order?.acceptorName }} <span v-if="row.order?.acceptorStaffNo">[{{ row.order?.acceptorStaffNo }}]</span>
+					</span>
+				</template>
+			</el-table-column>
+			<el-table-column prop="order.orgLevelOneName" label="一级部门" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column prop="order.actualHandleOrgName" label="接办部门" show-overflow-tooltip width="150"></el-table-column>
+			<el-table-column label="受理时间" show-overflow-tooltip width="170">
+				<template #default="{ row }">
+					<span>{{ formatDate(row.order?.startTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column label="办结时间" show-overflow-tooltip width="170">
+				<template #default="{ row }">
+					<span>{{ formatDate(row.order?.filedTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column label="办结时间" show-overflow-tooltip width="170">
+				<template #default="{ row }">
+					<span>{{ formatDate(row.order?.filedTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column label="发布时间" show-overflow-tooltip width="170">
+				<template #default="{ row }">
+					<span>{{ formatDate(row.publishTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+				</template>
+			</el-table-column>
+			<el-table-column prop="employeeName" label="回访人" show-overflow-tooltip width="170"></el-table-column>
+			<template #empty>
+				<Empty />
+			</template>
+		</el-table>
+		<template #footer>
+			<span class="dialog-footer">
+				<el-button @click="state.dialogVisible = false" class="default-button">取 消</el-button>
+				<el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading" :disabled="!multipleSelection.length">确 定</el-button>
+			</span>
+		</template>
+	</el-dialog>
+</template>
+<script setup lang="ts">
+import { formatDate } from '@/utils/formatTime';
+import { ElMessage, FormInstance } from 'element-plus';
+import { reactive, ref,defineAsyncComponent } from 'vue';
+import { getSmartVisitRecord } from '@/api/smartVisit';
+import { shortcuts } from '@/utils/constants';
+import { smartVisitAdd } from '@/api/smartVisit';
+
+const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
+const emit = defineEmits(['updateList']);
+const state = reactive<any>({
+	queryParams: {
+		Keyword: null, // 关键字
+	},
+	tableData: [], //表格
+	loading: false, // 加载
+	dialogVisible: false, // 弹窗
+	ruleForm: {
+		name: '',
+		crTime: [],
+		festivalBan: 1,
+	}, // 表单数据
+});
+// 打开弹窗
+const openDialog = () => {
+	queryList();
+};
+const close = () => {
+	multipleSelection.value = [];
+	ruleFormRef.value?.clearValidate();
+	ruleFormRef.value?.resetFields();
+};
+// 获取所有工单列表
+const queryList = async () => {
+	state.dialogVisible = true;
+	try {
+		state.loading = true;
+		const res = await getSmartVisitRecord(state.queryParams);
+		state.tableData = res.result;
+		state.loading = false;
+	} catch (e) {
+		console.log(e);
+		state.loading = false;
+	}
+};
+// 重置所有工单列表
+const queryParamsRef = ref<RefType>();
+const resetQuery = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	queryList();
+};
+const multipleSelection = ref<EmptyArrayType>([]); // 重复件表格选中项
+const multipleTableRef = ref<RefType>(); // 重复件表格ref
+const handleSelectionChange = (row: any) => {
+	multipleSelection.value = row;
+};
+
+// 确定选择所有工单到重复工单
+const ruleFormRef = ref<RefType>();
+const onSubmit = async (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	await formEl.validate((valid: boolean) => {
+		if (!valid) return;
+		state.loading = true;
+		const request = {
+			name: state.ruleForm.name,
+			beginTime: state.ruleForm.crTime[0],
+			endTime: state.ruleForm.crTime[1],
+			festivalBan: state.ruleForm.festivalBan,
+			aiOrderVisitDetails: multipleSelection.value.map((item: any) => {
+				return {
+					orderId: item.order?.id,
+					orderVisitId: item.id,
+					outerNo: item.order?.contact,
+				};
+			}),
+		};
+		smartVisitAdd(request)
+			.then(() => {
+				state.loading = false;
+				state.dialogVisible = false;
+				ElMessage.success('操作成功');
+				emit('updateList');
+			})
+			.catch(() => {
+				state.loading = false;
+			});
+	});
+};
+defineExpose({
+	openDialog,
+});
+</script>
+<style scoped lang="scss"></style>

+ 124 - 0
src/views/business/visit/smart.vue

@@ -0,0 +1,124 @@
+<template>
+	<div class="quality-template-container layout-pd">
+		<el-card shadow="never">
+			<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
+				<el-form-item label="关键字" prop="Name">
+					<el-input v-model="state.queryParams.Name" placeholder="回访任务名称" clearable @keyup.enter="queryList" class="keyword-input" />
+				</el-form-item>
+				<el-form-item>
+					<el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+					<el-button @click="resetQuery(ruleFormRef)" class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+				</el-form-item>
+			</el-form>
+		</el-card>
+		<el-card shadow="never">
+			<ProTable
+				ref="proTableRef"
+				:columns="columns"
+				:data="state.tableData"
+				@updateTable="queryList"
+				:loading="state.loading"
+				:total="state.total"
+				v-model:page-index="state.queryParams.PageIndex"
+				v-model:page-size="state.queryParams.PageSize"
+			>
+				<template #tableHeader="scope">
+					<el-button type="primary" @click="onAddVisit" v-auth="'business:visit:smart:add'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
+				</template>
+				<!-- 表格操作 -->
+				<template #operation="{ row }">
+					<el-button link type="primary" @click="onDetail(row)" title="回访明细"> 回访明细 </el-button>
+					<!--            <el-button link type="primary" @click="onTemplateEdit(row)" title="终止回访任务" v-auth="'smart:visit:end'"> 终止 </el-button>-->
+				</template>
+			</ProTable>
+		</el-card>
+		<!--  选择需要智能回访的工单  -->
+		<smart-visit-add ref="smartVisitAddRef" @updateList="queryList" />
+		<!--  回访明细  -->
+		<smart-visit-detail ref="smartVisitDetailRef" @updateList="queryList" />
+	</div>
+</template>
+
+<script lang="tsx" setup name="businessVisitSmart">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { ElButton, FormInstance } from 'element-plus';
+import { formatDate } from '@/utils/formatTime';
+import { getSmartVisitList } from '@/api/smartVisit';
+
+// 引入组件
+const SmartVisitAdd = defineAsyncComponent(() => import('@/views/business/visit/component/Smart-visit-add.vue')); // 选择需要智能回访的工单
+const SmartVisitDetail = defineAsyncComponent(() => import('@/views/business/visit/component/Smart-visit-Detail.vue')); // 回访明细
+
+const proTableRef = ref<RefType>(); // 表格ref
+// 表格配置项
+const columns = ref<any[]>([
+	{ type: 'selection', fixed: 'left', width: 55 },
+	{ prop: 'name', label: '回访任务名称' },
+	{ prop: 'hasVisitCount', label: '回访任务总数量' },
+	{ prop: 'visitedCount', label: '回访任务成功数量' },
+	{ prop: 'visitedFailCount', label: '回访任务失败数量' },
+	{ prop: 'taskStateText', label: '任务完成状态' },
+	{ prop: 'creatorName', label: '创建人' },
+	{
+		prop: 'creationTime',
+		label: '创建时间',
+		width: 170,
+		render: (scope: any) => {
+			return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{ prop: 'operation', label: '操作', fixed: 'right', width: 140, align: 'center' },
+]);
+// 定义变量内容
+const state = reactive({
+	loading: false, // 加载状态
+	queryParams: {
+		// 查询参数
+		PageIndex: 1,
+		PageSize: 10,
+		Grouping: null,
+		Name: null,
+	},
+	total: 0, // 总条数
+	tableData: [], // 表格数据
+});
+const ruleFormRef = ref<RefType>(null); // 表单ref
+// 获取参数列表
+const queryList = () => {
+	state.loading = true;
+	getSmartVisitList(state.queryParams)
+		.then((res) => {
+			state.loading = false;
+			state.tableData = res.result.items ?? [];
+			state.total = res.result.total ?? 0;
+		})
+		.finally(() => {
+			state.loading = false;
+		});
+};
+// 重置表单
+const resetQuery = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	queryList();
+};
+// 新增回访任务
+const smartVisitAddRef = ref<RefType>();
+const onAddVisit = () => {
+	smartVisitAddRef.value.openDialog();
+};
+// 回访明细
+const smartVisitDetailRef = ref<RefType>();
+const onDetail = (row: any) => {
+	smartVisitDetailRef.value.openDialog(row);
+};
+// 页面加载时
+onMounted(() => {
+	queryList();
+});
+</script>
+
+<style lang="scss" scoped>
+.quality-template-container {
+}
+</style>

+ 1 - 1
src/views/smartVisit/index.vue

@@ -39,7 +39,7 @@
 	</div>
 </template>
 
-<script lang="tsx" setup name="smartVisit">
+<script lang="tsx" setup name="businessVisitSmart">
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import { ElButton, FormInstance } from 'element-plus';
 import { formatDate } from '@/utils/formatTime';