Jelajahi Sumber

reactor:新增工单修改菜单;

zhangchong 6 bulan lalu
induk
melakukan
885d6656bd
3 mengubah file dengan 350 tambahan dan 4 penghapusan
  1. 4 3
      src/layout/component/main.vue
  2. 1 1
      src/utils/signalR.ts
  3. 345 0
      src/views/todo/edit/index.vue

+ 4 - 3
src/layout/component/main.vue

@@ -11,7 +11,7 @@
 </template>
 
 <script setup lang="tsx" name="layoutMain">
-import { defineAsyncComponent, onMounted, computed, ref } from 'vue';
+import { defineAsyncComponent, onMounted, computed, ref, nextTick } from 'vue';
 import { useRoute } from 'vue-router';
 import { storeToRefs } from 'pinia';
 import { useTagsViewRoutes } from '@/stores/tagsViewRoutes';
@@ -64,13 +64,14 @@ const setBackTopClass = computed(() => {
 	else return `.layout-backtop .el-scrollbar__wrap`;
 });
 // 页面加载前
-onMounted(() => {
+onMounted(async () => {
 	NextLoading.done(600);
 	// 监听页面需要滚动事件
 	mittBus.on('scrollTopEmit', (res: any) => {
 		layoutMainScrollbarRef.value?.scrollTo(res.top ? res.top : 0, res.left ? res.left : 0)// 滚动到一组特定坐标(x,y)
 	});
-	signalR.joinGroup('CallCenter'); // 加入分组
+	await nextTick();
+	await signalR.joinGroup('CallCenter'); // 加入分组
 });
 // 暴露变量
 defineExpose({

+ 1 - 1
src/utils/signalR.ts

@@ -100,7 +100,7 @@ export default {
 	async start() {
 		try {
 			//使用async和await 或 promise的then 和catch 处理来自服务端的异常
-			await this.SR.start();
+			await this.SR?.start();
 			const name: string = `业务系统的websocket链接成功`;
 			const remark: string = `业务系统的websocket链接成功`;
 			const request = {

+ 345 - 0
src/views/todo/edit/index.vue

@@ -0,0 +1,345 @@
+<template>
+	<div class="todo-center-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<ProTable
+				ref="proTableRef"
+				:columns="columns"
+				:data="state.tableData"
+				@updateTable="queryList"
+				:loading="state.loading"
+				:total="state.total"
+				v-model:page-index="state.queryParams.PageIndex"
+				v-model:page-size="state.queryParams.PageSize"
+			>
+				<template #table-search>
+					<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mb10" inline>
+						<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" />
+						</el-form-item>
+
+						<el-form-item label="">
+							<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="drawer = true" class="default-button"> <SvgIcon name="ele-Search" class="mr5" />更多查询</el-button>
+						</el-form-item>
+					</el-form>
+				</template>
+				<template #tableHeader="scope">
+					<el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'todo:edit:jbdExport'"
+						><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
+					</el-button>
+				</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="onOrderEdit(row)" title="编辑工单" v-if="row.canEdit" v-auth="'todo:edit:edit'"> 工单修改 </el-button>
+				</template>
+			</ProTable>
+		</div>
+		<!--	更多查询	-->
+		<el-drawer v-model="drawer" title="更多查询" size="500px">
+			<el-form :model="state.queryParams" ref="drawerRuleFormRef" @submit.native.prevent label-width="100px">
+				<el-form-item label="生成时间" prop="scTime">
+					<el-date-picker
+						v-model="state.queryParams.scTime"
+						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="slTime">
+					<el-date-picker
+						v-model="state.queryParams.slTime"
+						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="StepName">
+					<el-select v-model="state.queryParams.StepName" placeholder="请选择当前节点" clearable class="w100" @change="handleQuery">
+						<el-option v-for="item in state.stepNamesOptions" :value="item" :key="item" :label="item" />
+					</el-select>
+				</el-form-item>
+				<el-form-item label="派单员" prop="CenterToOrgHandlerName">
+					<el-input v-model="state.queryParams.CenterToOrgHandlerName" placeholder="派单员" clearable @keyup.enter="handleQuery" />
+				</el-form-item>
+				<el-form-item label="是否紧急" prop="IsUrgent">
+					<el-select v-model="state.queryParams.IsUrgent" placeholder="请选择是否紧急" clearable class="w100" @change="handleQuery">
+						<el-option :value="true" label="紧急" />
+						<el-option :value="false" label="不紧急" />
+					</el-select>
+				</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="Status">
+					<el-select v-model="state.queryParams.Status" placeholder="请选择工单状态" clearable class="w100" @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="AcceptorName">
+					<el-input v-model="state.queryParams.AcceptorName" placeholder="受理人" clearable @keyup.enter="handleQuery" />
+				</el-form-item>
+				<el-form-item label="超期状态" prop="ExpiredStatus">
+					<el-select v-model="state.queryParams.ExpiredStatus" placeholder="请选择超期状态" clearable class="w100" @change="handleQuery">
+						<el-option v-for="item in state.expiredStatusOptions" :value="item.key" :key="item.key" :label="item.value" />
+					</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>
+				<el-button @click="resetQuery(drawerRuleFormRef)" class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+			</template>
+		</el-drawer>
+	</div>
+</template>
+<script setup lang="tsx" name="todoEdit">
+import { defineAsyncComponent, onActivated, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
+import type { FormInstance } from 'element-plus';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { defaultTimeStartEnd, shortcuts } from '@/utils/constants';
+import other from '@/utils/other';
+import { 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 mittBus from '@/utils/mitt';
+
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
+
+// 定义变量内容
+const state = reactive<any>({
+	queryParams: {
+		PageIndex: 1, // 当前页
+		PageSize: 20, // 每页条数
+		Title: null, // 标题
+		No: null, // 工单编号
+		scTime: [], // 生成时间
+		StCreationTime: null, // 生成开始时间
+		EnCreationTime: null, // 生成结束时间
+		slTime: [], // 受理时间
+		StartTimeSt: null, // 受理开始时间
+		StartTimeEnd: null, // 受理结束时间
+		AcceptorName: null, // 受理人
+		ActualHandleOrgName: null, // 接办部门
+		Status: null, // 工单状态
+		ExpiredStatus: null, // 超期状态
+		StepName: null, // 当前节点名称
+		IsUrgent: null,
+		CenterToOrgHandlerName: null, // 派单员
+	},
+	tableData: [], //表单
+	loading: false, // 加载
+	total: 0, // 总数
+	expiredStatusOptions: [], //超期状态
+	orderStatusOptions: [], //工单状态
+	stepNamesOptions: [], //步骤名称
+});
+const router = useRouter(); // 路由
+const proTableRef = ref<RefType>(); // 表格ref
+// 表格配置项
+const columns = ref<any[]>([
+	{ type: 'selection', minWidth: 40, align: 'center' },
+	{ prop: 'expiredStatusText', label: '超期状态', minWidth: 80, align: 'center' },
+	{ prop: 'no', label: '工单编码', minWidth: 140 },
+	{ prop: 'isProvinceText', label: '省/市工单', minWidth: 90 },
+	{
+		prop: 'isUrgentText',
+		label: '是否紧急',
+		render: (scope:any) => {
+			return <span class="color-danger font-bold">{scope.row.isUrgentText}</span>;
+		},
+	},
+	{ prop: 'currentStepName', label: '当前节点', minWidth: 100 },
+	{ prop: 'statusText', label: '工单状态', minWidth: 100 },
+	{ prop: 'title', label: '工单标题', minWidth: 200 },
+	{ prop: 'centerToOrgHandlerName', label: '派单员', minWidth: 120 },
+	{
+		prop: 'startTime',
+		label: '受理时间',
+		minWidth: 160,
+		render: (scope:any) => {
+			return <span>{formatDate(scope.row.startTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{
+		prop: 'expiredTime',
+		label: '工单期满时间',
+		minWidth: 160,
+		render: (scope:any) => {
+			return <span>{formatDate(scope.row.expiredTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{
+		prop: 'filedTime',
+		label: '办结时间',
+		minWidth: 160,
+		render: (scope:any) => {
+			return <span>{formatDate(scope.row.filedTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
+		},
+	},
+	{ prop: 'orgLevelOneName', label: '一级部门', minWidth: 140 },
+	{ prop: 'actualHandleOrgName', label: '接办部门', minWidth: 140 },
+	{ prop: 'acceptType', label: '受理类型', minWidth: 100 },
+	{ prop: 'counterSignTypeText', label: '是否会签', minWidth: 90 },
+	{ prop: 'sourceChannel', label: '来源渠道', minWidth: 100 },
+	{ prop: 'hotspotName', label: '热点分类', minWidth: 150 },
+	{
+		prop: 'sensitive',
+		label: '敏感词',
+		minWidth: 150,
+	},
+	{ prop: 'acceptorName', label: '受理人', minWidth: 120 },
+	{
+		prop: 'reTransactNum',
+		label: '重办次数',
+	},
+	{ prop: 'operation', label: '操作', fixed: 'right', minWidth: 90, align: 'center' },
+]);
+// 获取查询条件基础信息
+const getBaseData = async () => {
+	try {
+		const res: any = await centerTodoBase();
+		const mappings: any = {
+			expiredStatusOptions: 'expiredStatus',
+			orderStatusOptions: 'orderStatus',
+			stepNamesOptions: 'stepNames',
+		};
+		for (const key in mappings) {
+			state[key] = res.result?.[mappings[key]] ?? [];
+		}
+	} catch (error) {
+		console.log(error);
+	}
+};
+// 手动查询,将页码设置为1
+const handleQuery = () => {
+	state.queryParams.PageIndex = 1;
+	queryList();
+};
+/** 获取列表 */
+const requestParams = ref<EmptyObjectType>({});
+const queryList = () => {
+	requestParams.value = other.deepClone(state.queryParams);
+	requestParams.value.StCreationTime = state.queryParams.scTime === null ? null : state.queryParams.scTime[0];
+	requestParams.value.EndCreationTime = state.queryParams.scTime === null ? null : state.queryParams.scTime[1];
+	Reflect.deleteProperty(requestParams.value, 'scTime');
+	requestParams.value.StartTimeSt = state.queryParams.slTime === null ? null : state.queryParams.slTime[0];
+	requestParams.value.StartTimeEnd = state.queryParams.slTime === null ? null : state.queryParams.slTime[1];
+	Reflect.deleteProperty(requestParams.value, 'slTime');
+	state.loading = true;
+	centerTodo(requestParams.value)
+		.then((response: any) => {
+			state.tableData = response?.result.items ?? [];
+
+			state.total = response?.result.total;
+			state.loading = false;
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
+/** 重置按钮操作 */
+const drawerRuleFormRef = ref();
+const ruleFormRef = ref<RefType>(); // 表单ref
+const drawer = ref(false);
+const resetQuery = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	ruleFormRef.value?.resetFields();
+	queryList();
+};
+// 签收工单
+const onSign = (row: any) => {
+	ElMessageBox.confirm(`您确定要要签收【${row.title}】,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			orderSign(row.id).then(() => {
+				ElMessage.success('签收成功');
+				queryList();
+			});
+		})
+		.catch(() => {});
+};
+// 编辑工单
+const onOrderEdit = (row: any) => {
+	router.push({
+		name: 'orderAccept',
+		query: {
+			id: row.id,
+			tagsViewName: `编辑工单-${row.title}`,
+		},
+	});
+};
+// 交办单导出
+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 orderMigrationRef = ref<RefType>();
+const onMigration = (row: any) => {
+	orderMigrationRef.value.openDialog('centerTodo', row);
+};
+onMounted(() => {
+	getBaseData();
+	queryList();
+});
+onActivated(() => {
+	mittBus.on('clearCachePage', () => {
+		//清除缓存
+		queryList();
+	});
+});
+onBeforeUnmount(() => {
+	mittBus.off('clearCachePage');
+});
+</script>