Преглед изворни кода

refactor:类型文件规范调整;
feat:业务管理新增:退回申请,重办查询,催办查询,会签查询等列表;
feat:三方通话;

zhangchong пре 1 година
родитељ
комит
d701569946
43 измењених фајлова са 6904 додато и 1108 уклоњено
  1. 315 0
      src/components/CommonAdvice/index.vue
  2. 4 4
      src/components/ProcessApproval/index.vue
  3. 318 322
      src/layout/navBars/breadcrumb/telControl.vue
  4. 1 1
      src/stores/telStatus.ts
  5. 1 0
      src/types/axios.d.ts
  6. 0 1
      src/types/global.d.ts
  7. 1 1
      src/types/mitt.d.ts
  8. 1 11
      src/types/pinia.d.ts
  9. 35 4
      src/utils/PhoneScript.ts
  10. 0 1
      src/utils/mitt.ts
  11. 7 7
      src/utils/theme.ts
  12. 1 1
      src/utils/websocket.ts
  13. 324 0
      src/views/business/countersign/detail/index.vue
  14. 328 0
      src/views/business/countersign/index.vue
  15. 370 0
      src/views/business/delay/backlog/index.vue
  16. 2 2
      src/views/business/delay/index.vue
  17. 325 0
      src/views/business/discern/apply/index.vue
  18. 343 0
      src/views/business/discern/backlog/index.vue
  19. 7 7
      src/views/business/discern/index.vue
  20. 336 0
      src/views/business/followUp/backlog/index.vue
  21. 461 0
      src/views/business/followUp/component/Follow-up-detail.vue
  22. 0 367
      src/views/business/followUp/component/Follow-up-phone.vue
  23. 328 0
      src/views/business/followUp/followedUp/index.vue
  24. 33 21
      src/views/business/followUp/index.vue
  25. 12 12
      src/views/business/order/accept/orderAdd.vue
  26. 11 11
      src/views/business/order/accept/orderEdit.vue
  27. 28 11
      src/views/business/order/backlog/index.vue
  28. 0 300
      src/views/business/order/components/Order-comment.vue
  29. 9 9
      src/views/business/order/components/Order-process.vue
  30. 319 0
      src/views/business/overdue/index.vue
  31. 323 0
      src/views/business/overdue/node/index.vue
  32. 319 0
      src/views/business/overdueSoon/index.vue
  33. 329 0
      src/views/business/overdueSoon/node/index.vue
  34. 334 0
      src/views/business/redo/index.vue
  35. 2 3
      src/views/business/release/index.vue
  36. 335 0
      src/views/business/return/backlog/index.vue
  37. 334 0
      src/views/business/return/index.vue
  38. 323 0
      src/views/business/revocation/index.vue
  39. 346 0
      src/views/business/supervise/backlog/index.vue
  40. 2 2
      src/views/business/supervise/index.vue
  41. 327 0
      src/views/business/urge/index.vue
  42. 1 1
      src/views/home/index.vue
  43. 9 9
      src/views/knowledge/component/Knowledge-process.vue

+ 315 - 0
src/components/CommonAdvice/index.vue

@@ -0,0 +1,315 @@
+<template>
+  <div class="textarea w100">
+    <el-input v-model="value" type="textarea" :autosize="{ minRows: props.minRows, maxRows: props.maxRows }" :placeholder="placeholder" :maxlength="props.maxlength"> </el-input>
+    <span class="buttons">
+			<el-button @click="showAdvice" class="default-button" :loading="loading">常用意见</el-button>
+			<el-button type="primary" @click="onAddAdvice" :loading="loading">添加到常用意见</el-button>
+		</span>
+    <el-drawer v-model="state.showDrawer" :size="props.drawerWidth" title="" :show-close="false" :modal="modal">
+      <template #header="{ close }">
+        <div class="comments-header">
+          <div>
+            <el-button link @click="state.active = 'default'" :class="{ active: state.active === 'default' }"> 常用意见 </el-button>
+            <el-button link @click="state.active = 'add'" :class="{ active: state.active === 'add' }"> 新增意见 </el-button>
+            <span></span>
+          </div>
+        </div>
+        <div class="flex-center-align">
+          <el-button link @click="state.manage = true" v-if="!state.manage && state.active === 'default' && state.adviceList.length"
+          >管理</el-button
+          >
+          <el-button link @click="state.manage = false" type="primary" v-if="state.manage && state.active === 'default'">返回</el-button>
+          <el-button link @click="close">
+            <SvgIcon name="ele-Close" class="mr5" @click="close" size="16px" />
+          </el-button>
+        </div>
+      </template>
+      <div class="comments-container" v-loading="state.loading">
+        <template v-if="state.adviceList.length">
+          <!-- 默认状态 -->
+          <template v-if="state.active === 'default' && !state.manage">
+            <ul class="comments-box">
+              <li class="comments-item" v-for="(item, index) in state.adviceList" :key="index" @click="chooseAdvice(item)">
+                <p class="text-ellipsis2" :title="item.content">{{ item.content }}</p>
+              </li>
+            </ul>
+          </template>
+          <!-- 管理 -->
+          <template v-if="state.active === 'default' && state.manage">
+            <ul class="comments-box">
+              <li
+                  class="comments-item"
+                  v-for="(item, index) in state.adviceList"
+                  :class="[item.ischeck === true ? 'chose' : '']"
+                  :key="index"
+                  @click="handleAdvice(item, <number>index)"
+              >
+                <p class="text-ellipsis2" :title="item.content">{{ item.content }}</p>
+                <el-checkbox v-model="item.ischeck" class="check-icon" label="" v-if="item.ischeck" size="large" />
+              </li>
+            </ul>
+          </template>
+        </template>
+        <template v-if="!state.adviceList.length && state.active !== 'add'">
+          <Empty description="暂无常用语" />
+        </template>
+        <!-- 新增意见 -->
+        <template v-if="state.active === 'add'">
+          <div>
+            <el-form :model="state.adviceForm" ref="adviceFormRef">
+              <el-form-item label="" prop="content" :rules="[{ required: true, message: '请填写新增常用意见', trigger: 'blur' }]">
+                <el-input
+                    v-model="state.adviceForm.content"
+                    type="textarea"
+                    :autosize="{ minRows: 10, maxRows: 10 }"
+                    placeholder="请填写新增常用意见"
+                    clearable
+                >
+                </el-input>
+              </el-form-item>
+            </el-form>
+          </div>
+        </template>
+      </div>
+      <template #footer v-if="state.active === 'add' || state.manage">
+        <div style="flex: auto">
+          <el-button @click="deleteAdvice" class="default-button" :disabled="!state.chooseAdvice.length" v-if="state.active === 'default' && state.manage">删 除</el-button>
+          <el-button type="primary" @click="adviceSave(adviceFormRef)" v-if="state.active === 'add'">保 存</el-button>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+
+<script setup lang="ts" name="commonAdvice">
+import { reactive, ref, computed } from 'vue';
+import {ElMessage, ElMessageBox, FormInstance} from 'element-plus';
+import { commonList, addCommon, deleteCommon } from '/@/api/business/commonP';
+import { commonEnum } from '/@/utils/constants';
+const emit = defineEmits(['chooseAdvice', 'update:modelValue']);
+const props = defineProps({
+  modal: {
+    type: Boolean,
+    default: false,
+  },
+  modelValue: {
+    type: String,
+    default: '',
+  },
+  placeholder: {
+    type: String,
+    default: '请填写内容',
+  },
+  loading: {
+    type: Boolean,
+    default: false,
+  },
+  commonEnum: {
+    type: String,
+    default: commonEnum.Seat,
+  },
+  minRows:{
+    type: [Number , String , undefined],
+    default: 10,
+  },
+  maxRows:{
+    type: [Number , String , undefined],
+    default: 20,
+  },
+  maxlength:{
+    type: [Number , String , undefined],
+    default: 2000,
+  },
+  drawerWidth:{
+    type: [Number , String],
+    default: '35%',
+  },
+});
+const value = computed({
+  get() {
+    return props.modelValue;
+  },
+  set(value) {
+    emit('update:modelValue', value);
+  },
+});
+// 定义变量内容
+const state = reactive<any>({
+  showDrawer: false,  // 是否显示弹窗
+  adviceList: [], // 常用意见列表
+  adviceForm: { // 新增常用意见
+    content: '',
+  },
+  chooseAdvice: [],  // 选中的常用意见
+  active: 'default',  // 当前状态
+  manage: false,  // 是否是管理状态
+  loading: false, // 是否显示loading
+  typecode: '', // 类型
+});
+
+// 打开常用意见管理
+const showAdvice = () => {
+  openDialog();
+};
+// 添加到常用意见
+const onAddAdvice = async () => {
+  if (!props.modelValue) {
+    ElMessage.warning(props.placeholder);
+    return;
+  }
+  await addCommon({
+    typeCode: props.commonEnum,
+    content: props.modelValue,
+  });
+  ElMessage.success('操作成功');
+  closeDialog();
+};
+// 打开弹窗
+const adviceFormRef = ref<RefType>();
+const openDialog = async () => {
+  state.typecode = props.commonEnum;
+  state.active = 'default';
+  adviceFormRef.value?.resetFields();
+  state.manage = false;
+  await getList();
+  state.showDrawer = true;
+};
+const getList = async () => {
+  try {
+    state.loading = true;
+    const res: any = await commonList({ typecode: props.commonEnum });
+    state.adviceList = res.result;
+    state.loading = false;
+  } catch (error) {
+    state.loading = false;
+  }
+};
+// 选中常用意见(管理)
+const handleAdvice= (item: any, index: number) => {
+  const repeatData = [...state.adviceList];
+  const repeatSolar = [...state.chooseAdvice];
+  if (!repeatData[index].ischeck) {
+    repeatData[index].ischeck = true;
+    repeatSolar.push(item);
+  } else {
+    repeatData[index].ischeck = false;
+    if (!repeatSolar || repeatSolar.length == 0) {
+      return '';
+    }
+    repeatSolar.splice(index, 1);
+  }
+  state.chooseAdvice = repeatSolar.filter((item: any) => item.ischeck);
+};
+// 重置状态
+const resetState = () => {
+  state.active = 'default';
+  state.manage = false;
+  state.chooseAdvice = [];
+  state.adviceForm.content = '';
+  getList();
+};
+// 删除常用意见
+const deleteAdvice = () => {
+  if (!state.chooseAdvice.length) {
+    ElMessage.warning('请选择要删除的常用意见');
+    return;
+  }
+  ElMessageBox.confirm(`确定要删除选中的常用意见,是否继续?`, '提示', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    draggable: true,
+    cancelButtonClass: 'default-button',
+    type: 'warning',
+  })
+      .then(() => {
+        const chooseAdvice = state.chooseAdvice.map((item: any) => {
+          return item.id;
+        });
+        deleteCommon({ ids: chooseAdvice }).then(() => {
+          ElMessage.success('操作成功');
+          resetState();
+          state.loading = false;
+        });
+      })
+      .catch(() => {});
+};
+// 添加常用意见 保存
+const adviceSave = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.validate((valid: boolean) => {
+    if (!valid) return;
+    state.loading = true;
+    addCommon({
+      typeCode: state.typecode,
+      content: state.adviceForm.content,
+    }).then(() => {
+      ElMessage.success('操作成功');
+      resetState();
+      state.loading = false;
+    });
+  })
+};
+// 选择常用意见 填入填写框
+const chooseAdvice = (item: any) => {
+  emit('chooseAdvice', item);
+  closeDialog();
+};
+// 关闭弹窗
+const closeDialog = () => {
+  state.showDrawer = false;
+};
+// 暴露变量
+defineExpose({
+  openDialog,
+  closeDialog,
+});
+</script>
+<style lang="scss" scoped>
+.textarea {
+  position: relative;
+  .buttons {
+    position: absolute;
+    right: 10px;
+    bottom: 10px;
+  }
+  :deep(.el-textarea__inner) {
+    padding-bottom: 40px;
+  }
+}
+.comments-container {
+  .comments-box {
+    .comments-item {
+      border: var(--el-border);
+      border-radius: var(--el-border-radius-base);
+      margin-bottom: 10px;
+      padding: 8px 15px;
+      cursor: pointer;
+      position: relative;
+      line-height: 18px;
+      &:hover {
+        box-shadow: 0 0 0 1px var(--el-color-primary) inset;
+        background-color: var(--hotline-bg-main-color);
+      }
+      .check-icon {
+        position: absolute;
+        right: 0;
+        top: -13px;
+      }
+    }
+    .chose {
+      box-shadow: 0 0 0 1px var(--el-color-primary) inset;
+    }
+  }
+}
+.comments-header {
+  .active {
+    color: var(--el-color-primary);
+    font-size: var(--el-font-size-medium);
+  }
+}
+:deep(.el-drawer__footer) {
+  box-shadow: 0px -4px 10px 0px rgb(0 0 0 / 10%);
+  border-radius: 0 0 8px 0;
+  padding: 10px 20px;
+}
+</style>

+ 4 - 4
src/components/ProcessApproval/index.vue

@@ -72,8 +72,8 @@
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
             <el-form-item :label="state.title + '意见'" prop="opinion" :rules="[{ required: true, message: '请填写常用意见', trigger: 'blur' }]">
-              <Comment
-                  @chooseComment="chooseComment"
+              <common-advice
+                  @chooseAdvice="chooseAdvice"
                   v-model="state.ruleForm.opinion"
                   placeholder="请填写常用意见"
                   :loading="state.loading"
@@ -106,7 +106,7 @@ import { OrderFlowParams, orderStartFlow } from '/@/api/business/order';
 import { workflowNextSteps, workflowNext, workflowRecall, workflowPrevious, workflowRecallParams, workflowStepOptions } from '/@/api/system/workflow';
 
 // 引入组件
-const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Order-comment.vue')); // 常用意见
+const CommonAdvice = defineAsyncComponent(() => import('/@/components/CommonAdvice/index.vue')); // 常用意见
 const AnnexList = defineAsyncComponent(() => import('/@/components/AnnexList/index.vue'));  // 附件列表
 // 定义子组件向父组件传值/事件
 const emit = defineEmits(['orderProcessSuccess', 'orderProcessFailed']);
@@ -254,7 +254,7 @@ const onCancel = () => {
   closeDialog();
 };
 // 选择常用意见 填入填写框
-const chooseComment = (item: any) => {
+const chooseAdvice = (item: any) => {
   state.ruleForm.opinion += item.content;
 };
 // 提交

+ 318 - 322
src/layout/navBars/breadcrumb/telControl.vue

@@ -169,7 +169,7 @@
 
 			<!-- 三方会议 可用(两个通话 一个取消保持 一个保持 才能使用三方通话) -->
 			<!--    && activeArr.includes('conference')   -->
-			<template v-if="telStatusInfo.isDutyOn">
+			<template v-if="telStatusInfo.isDutyOn && activeArr.includes('conference')">
 				<div
 					class="item active"
 					@mouseenter="onHover('conferenceSrc', 'phoneControls/conference_white.png')"
@@ -210,9 +210,8 @@
 				</div>
 			</template>
 
-
 			<!-- 评价 可用 来电才可以评价 callType === 3 -->
-<!--			<template v-if="telStatusInfo.isDutyOn && activeArr.includes('evaluate') && telStatusInfo.telType === 3">
+			<!--			<template v-if="telStatusInfo.isDutyOn && activeArr.includes('evaluate') && telStatusInfo.telType === 3">
 				<div
 					class="item active"
 					@mouseenter="onHover('evaluateSrc', 'phoneControls/evaluate_white.png')"
@@ -225,7 +224,7 @@
 				</div>
 			</template>-->
 			<!-- 评价 不可用 -->
-<!--			<template v-else>
+			<!--			<template v-else>
 				<div class="item disabled" title="评价">
 					<img :src="getImageUrl('phoneControls/evaluate_grey.png')" alt="" />
 					<span>评价</span>
@@ -240,13 +239,7 @@
 	<el-dialog v-model="state.dutyDialogVisible" draggable title="签入" width="500px" :show-close="false">
 		<el-form :model="state.dutyForm" label-width="80px" ref="dutyFormRef">
 			<el-form-item label="分机" prop="telNo" :rules="[{ required: true, message: '请选择需要签入的分机', trigger: 'change' }]">
-        <el-select-v2
-            v-model="state.dutyForm.telNo"
-            :options="state.telsList"
-            placeholder="选择要签入的分机"
-            filterable
-            class="w100"
-        />
+				<el-select-v2 v-model="state.dutyForm.telNo" :options="state.telsList" placeholder="选择要签入的分机" filterable class="w100" />
 			</el-form-item>
 		</el-form>
 		<template #footer>
@@ -266,7 +259,7 @@
 		:width="AppConfigInfo.IsRestApproval ? '60%' : '500px'"
 		@mouseup="mouseup"
 		:style="'transform: ' + state.transform + ';'"
-    @opend="restFormOpened"
+		@opend="restFormOpened"
 	>
 		<!-- 需要审核 -->
 		<template v-if="AppConfigInfo.IsRestApproval">
@@ -319,25 +312,29 @@
 							<el-checkbox v-model="state.restForm.acceptSms" label="短信通知" />
 						</el-form-item>
 					</el-col> -->
-          <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
-            <el-form-item label="是否发起会签" prop="isStartCountersign" :rules="[{ required: false, message: '请选择是否发起会签', trigger: 'change' }]">
-              <el-switch v-model="state.restForm.isStartCountersign" inline-prompt active-text="是" inactive-text="否" />
-            </el-form-item>
-          </el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
+						<el-form-item
+							label="是否发起会签"
+							prop="isStartCountersign"
+							:rules="[{ required: false, message: '请选择是否发起会签', trigger: 'change' }]"
+						>
+							<el-switch v-model="state.restForm.isStartCountersign" inline-prompt active-text="是" inactive-text="否" />
+						</el-form-item>
+					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 						<el-form-item label="办理意见" prop="opinion" :rules="[{ required: true, message: '请填写小休办理意见', trigger: 'blur' }]">
-							<Comment
-								@chooseComment="chooseComment"
+							<common-advice
+								@chooseAdvice="chooseAdvice"
 								v-model="state.restForm.opinion"
-								:loading="state.loading"
 								placeholder="请填写小休办理意见"
+								:loading="state.loading"
 								:commonEnum="commonEnum.RestReason"
 							/>
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 						<el-form-item label="附件" prop="remark" :rules="[{ required: false, message: '请填写诉求内容', trigger: 'change' }]">
-              <annex-list />
+							<annex-list />
 						</el-form-item>
 					</el-col>
 				</el-row>
@@ -370,15 +367,15 @@
 	<el-dialog v-model="state.transferDialogVisible" draggable title="转接" width="500px">
 		<el-form :model="state.transferForm" label-width="100px" ref="transferFormRef">
 			<el-form-item label="转接号码" prop="telNo" :rules="[{ required: true, message: '请选择转接分机或输入外部电话', trigger: 'blur' }]">
-        <el-select-v2
-            v-model="state.transferForm.telNo"
-            :options="state.telsList"
-            placeholder="请选择转接分机或输入外部电话"
-            filterable
-            class="w100"
-            allow-create
-            default-first-option
-        />
+				<el-select-v2
+					v-model="state.transferForm.telNo"
+					:options="state.telsList"
+					placeholder="请选择转接分机或输入外部电话"
+					filterable
+					class="w100"
+					allow-create
+					default-first-option
+				/>
 			</el-form-item>
 		</el-form>
 		<template #footer>
@@ -393,15 +390,15 @@
 	<el-dialog v-model="state.outboundDialogVisible" draggable title="呼叫" width="450px">
 		<el-form :model="state.outboundForm" label-width="80px" ref="outboundFormRef">
 			<el-form-item label="呼叫号码" prop="telNo" :rules="[{ required: true, message: '请选择或输入呼叫号码', trigger: 'blur' }]">
-        <el-select-v2
-            v-model="state.outboundForm.telNo"
-            :options="state.telsList"
-            placeholder="请选择或输入呼叫号码"
-            filterable
-            class="w100"
-            allow-create
-            default-first-option
-        />
+				<el-select-v2
+					v-model="state.outboundForm.telNo"
+					:options="state.telsList"
+					placeholder="请选择或输入呼叫号码"
+					filterable
+					class="w100"
+					allow-create
+					default-first-option
+				/>
 			</el-form-item>
 		</el-form>
 		<template #footer>
@@ -432,72 +429,75 @@
 </template>
 
 <script setup lang="ts" name="telControl">
-import {reactive, ref, computed, watch, defineAsyncComponent, onMounted, onBeforeMount,} from 'vue';
+import { reactive, ref, computed, watch, defineAsyncComponent, onMounted, onBeforeMount } from 'vue';
 import { useRouter } from 'vue-router';
-import {ElMessageBox, ElNotification, ElMessage, FormInstance} from 'element-plus';
+import { ElMessageBox, ElNotification, ElMessage, FormInstance } from 'element-plus';
 import { storeToRefs } from 'pinia';
-import { useTelStatus,TelStates, RestStates } from '/@/stores/telStatus';
+import { useTelStatus, TelStates, RestStates } from '/@/stores/telStatus';
 import { useUserInfo } from '/@/stores/userInfo';
 import { useAppConfig } from '/@/stores/appConfig';
-import {debounce, getImageUrl} from '/@/utils/tools';
+import { debounce, getImageUrl } from '/@/utils/tools';
 import { formatDuration } from '/@/utils/formatTime';
 import { commonEnum } from '/@/utils/constants';
 import other from '/@/utils/other';
 import mittBus from '/@/utils/mitt';
 import { workflowStepOptions } from '/@/api/system/workflow';
-import { restFlowStart,restFlowDel,restFlowStartWex,getTelList } from '/@/api/public/wex'
+import { restFlowStart, restFlowDel, restFlowStartWex, getTelList } from '/@/api/public/wex';
 import { commonList } from '/@/api/business/commonP';
 import { auth } from '/@/utils/authFunction';
 import { VoiceInterfaceObject } from '/@/utils/PhoneScript';
 import { WebsocketInterface } from '/@/utils/websocket';
 import signalR from '/@/utils/signalR';
-import {Local} from "/@/utils/storage";
-
+import { Local } from '/@/utils/storage';
 const storesUserInfo = useUserInfo();
 const { userInfos } = storeToRefs(storesUserInfo);
+
 // 引入组件
-const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Order-comment.vue'));
+const CommonAdvice = defineAsyncComponent(() => import('/@/components/CommonAdvice/index.vue')); // 常用意见
 const AnnexList = defineAsyncComponent(() => import('/@/components/AnnexList/index.vue'));
 
 const state = reactive<any>({
 	active: <EmptyArrayType>[], // 当前选中
 	currentStatus: '', //当前通话状态
 	dutyDialogVisible: false, //签入选分机弹窗
-	dutyForm: { //签入选分机表单
+	dutyForm: {
+		//签入选分机表单
 		telNo: null, //分机号
 	},
 	telsList: <EmptyArrayType>[], // 分机列表
 	loading: false,
 	showHangupList: false, //是否展示挂断列表
 	restDialogVisible: false, //小休弹窗
-	restForm: {//小休表单
-		opinion: '',//小休原因
+	restForm: {
+		//小休表单
+		opinion: '', //小休原因
 		nextStepCode: '', //下一步
 		nextHandlers: [], //下一步处理人
 		acceptSms: false, //是否接收短信
-		nextMainHandler: '',//下一步主办人
+		nextMainHandler: '', //下一步主办人
 		reason: '', //小休原因
-    expiredTime: '', //期满时间
-    isStartCountersign: false, //是否发起会签
+		expiredTime: '', //期满时间
+		isStartCountersign: false, //是否发起会签
 	},
 	handlerMainOptions: [], // 主办
-  transferDialogVisible: false, // 转接弹窗
+	transferDialogVisible: false, // 转接弹窗
 	transferForm: {
 		//转接表单
 		telNo: null,
 	},
 	outboundDialogVisible: false, //外呼弹窗
-	outboundForm: {		// 外呼表单
+	outboundForm: {
+		// 外呼表单
 		telNo: null, //外呼号码
 	},
-  talkTime:0, //通话时长
-  talkTimer:null, //通话时长定时器
+	talkTime: 0, //通话时长
+	talkTimer: null, //通话时长定时器
 	dutyOnSrc: getImageUrl('phoneControls/dutyOn_blue.png'), //签入图片
 	dutyOffSrc: getImageUrl('phoneControls/dutyOff_blue.png'), //签出图片
 	hangupSrc: getImageUrl('phoneControls/hangup_blue.png'), //挂断图片
 	restSrc: getImageUrl('phoneControls/rest_blue.png'), //小休图片
 	holdSrc: getImageUrl('phoneControls/hold_blue.png'), //保持图片
-  talkingDealSrc: getImageUrl('phoneControls/talkingDeal_blue.png'), //时候处理图片
+	talkingDealSrc: getImageUrl('phoneControls/talkingDeal_blue.png'), //时候处理图片
 	transferSrc: getImageUrl('phoneControls/transfer_blue.png'), //转接图片
 	conferenceSrc: getImageUrl('phoneControls/conference_blue.png'), //三方会议图片
 	outboundSrc: getImageUrl('phoneControls/outbound_blue.png'), //外呼图片
@@ -509,7 +509,8 @@ const state = reactive<any>({
 	transform: 'translate(0px, 0px)',
 	fileList: [], // 文件上传列表
 	metingDialogVisible: false, // 三方会议弹窗
-	metingForm: {// 三方会议表单
+	metingForm: {
+		// 三方会议表单
 		metingId: '', // 三方会议ID
 		phoneNo: '', // 三方会议号码
 	},
@@ -528,25 +529,25 @@ const router = useRouter();
 
 // 开始计时
 const startTime = debounce(() => {
-  let talkTime = Local.get('talkTime');
-  if (talkTime) {
-    state.talkTime = Number(talkTime);
-    state.talkTimer = setInterval(() => {
-      state.talkTime++;
-      Local.set('talkTime', String(state.talkTime));
-    }, 1000);
-  } else {
-    state.talkTimer = setInterval(() => {
-      state.talkTime++;
-      Local.set('talkTime', String(state.talkTime));
-    }, 1000);
-  }
+	let talkTime = Local.get('talkTime');
+	if (talkTime) {
+		state.talkTime = Number(talkTime);
+		state.talkTimer = setInterval(() => {
+			state.talkTime++;
+			Local.set('talkTime', String(state.talkTime));
+		}, 1000);
+	} else {
+		state.talkTimer = setInterval(() => {
+			state.talkTime++;
+			Local.set('talkTime', String(state.talkTime));
+		}, 1000);
+	}
 }, 1000);
 // 结束计时
 const removeTimer = debounce(() => {
-  state.talkTime = 0;
-  Local.remove('talkTime');
-  clearInterval(state.talkTimer);
+	state.talkTime = 0;
+	Local.remove('talkTime');
+	clearInterval(state.talkTimer);
 }, 1000);
 
 // 小休审批通过消息
@@ -560,16 +561,18 @@ const RestApplyPassFn = (data: any) => {
 };
 // 链接websocket
 const initWebsocket = () => {
-  if(!userInfos.value.staffNo){
-    ElMessage.warning('账号暂无工号,请设置工号后重新登录后重试');
-    return;
-  }
-  let telNo:string|number;
-  if(telStatusInfo.value.isDutyOn){ // 如果已签入
-    telNo = telStatusInfo.value.telsNo;
-  }else{ // 如果未签入
-    telNo = state.dutyForm.telNo;
-  }
+	if (!userInfos.value.staffNo) {
+		ElMessage.warning('账号暂无工号,请设置工号后重新登录后重试');
+		return;
+	}
+	let telNo: string | number;
+	if (telStatusInfo.value.isDutyOn) {
+		// 如果已签入
+		telNo = telStatusInfo.value.telsNo;
+	} else {
+		// 如果未签入
+		telNo = state.dutyForm.telNo;
+	}
 	// 设置变量
 	VoiceInterfaceObject.SetSendModel({
 		GongHao: userInfos.value.staffNo,
@@ -588,7 +591,8 @@ const initWebsocket = () => {
 		onOpen: async () => {
 			//登录语音系统
 			VoiceInterfaceObject.Login();
-      await checkTelStatus(); // 检查签入状态
+      VoiceInterfaceObject.GetOnUserState(); //获取用户状态
+			await checkTelStatus(); // 检查签入状态
 		},
 		onMessage: (e: any) => {
 			// 收到消息调用方法
@@ -606,7 +610,7 @@ const initWebsocket = () => {
 	};
 	//初始化WebSocket
 	WebsocketInterface(wsParams);
-  return Promise.resolve();
+	return Promise.resolve();
 };
 
 //  signalR 初始化signalr
@@ -635,9 +639,9 @@ const activeArr = computed(() => {
 		ring: ['hangup'], //振铃中
 		onCall: ['hangup', 'hold', 'transfer', 'evaluate'], // 单个通话中
 		onHold: ['hangup', 'hold', 'transfer', 'evaluate'], // 保持中
-		oneHoldOneCall: ['hangup', 'hold', 'transfer', 'conference'], // 通话一保持通话二通话中(可用三方通话)
-		onTalkingDeal: ['dutyOff', 'rest', 'outbound', 'callForwarding','TalkingDeal'], // 事后处理中
-		onConference: ['hangup', 'hold', 'transfer', 'conference'], // 三方会议中
+		onTalkingDeal: ['dutyOff', 'rest', 'outbound', 'callForwarding', 'TalkingDeal'], // 事后处理中
+    onTransferSuccess:['hangup','conference'], // 转接成功
+		onConference: ['hangup'], // 三方会议中 只能挂断
 	};
 	let arr = <EmptyArrayType>[];
 	if (telStatusInfo.value.phoneControlState in switchCases) {
@@ -654,26 +658,26 @@ const currentStatusText = computed(() => {
 		ring: '振铃中',
 		onHold: '保持中',
 		onCall: '通话中',
-		oneCallHold: '通话保持',
 		onTalkingDeal: '事后处理',
 		onConference: '会议中',
+    onTransferSuccess:'转接成功'
 	};
 	return statusMap[telStatusInfo.value.phoneControlState] || '';
 });
 // 查询所有分机
-const getTelsLists = async (object?:object) => {
-  try {
-    const res: any = await getTelList(object);
-    state.telsList = res?.data ?? [];
-    state.telsList = state.telsList.map((item: any) => ({
-      value: item.device,
-      label: item.device,
-      ...item
-    }))
-    return Promise.resolve(state.telsList);
-  }catch(err){
-    console.log(err);
-  }
+const getTelsLists = async (object?: object) => {
+	try {
+		const res: any = await getTelList(object);
+		state.telsList = res?.data ?? [];
+		state.telsList = state.telsList.map((item: any) => ({
+			value: item.device,
+			label: item.device,
+			...item,
+		}));
+		return Promise.resolve(state.telsList);
+	} catch (err) {
+		console.log(err);
+	}
 };
 // 鼠标移入移出改变图标
 const onHover = (val: string, path: string) => {
@@ -746,26 +750,27 @@ const onControlClick = (val: string) => {
 const onDutyFn = async () => {
 	dutyFormRef.value?.resetFields();
 	// 获取所有分机列表(未签入的)
-	const list = await getTelsLists({sigin:0});
-  const isDefaultTelNo = list.some((item: any) => item.value === userInfos.value.defaultTelNo);
-  if(isDefaultTelNo) { // 如果默认分机号是空闲的,就默认选中
-    state.dutyForm.telNo = userInfos.value.defaultTelNo;
-  }
+	const list = await getTelsLists({ sigin: 0 });
+	const isDefaultTelNo = list.some((item: any) => item.value === userInfos.value.defaultTelNo);
+	if (isDefaultTelNo) {
+		// 如果默认分机号是空闲的,就默认选中
+		state.dutyForm.telNo = userInfos.value.defaultTelNo;
+	}
 	state.dutyDialogVisible = true;
 };
 // 确认签入
 const clickOnDuty = (formEl: FormInstance | undefined) => {
-  if(!formEl) return;
-  formEl.validate((valid: boolean) => {
-    if (!valid) return;
-    state.loading = true;
-    // {telNo:state.dutyForm.telNo}
-    setTimeout(() => {
-      state.loading = false;
-      state.dutyDialogVisible = false;
-      initWebsocket(); //开启消息监听
-    }, 300);
-  })
+	if (!formEl) return;
+	formEl.validate((valid: boolean) => {
+		if (!valid) return;
+		state.loading = true;
+		// {telNo:state.dutyForm.telNo}
+		setTimeout(() => {
+			state.loading = false;
+			state.dutyDialogVisible = false;
+			initWebsocket(); //开启消息监听
+		}, 300);
+	});
 };
 // 签出
 const offDutyFn = () => {
@@ -821,8 +826,8 @@ const onRest = async () => {
 };
 // 打开弹窗清空表单
 const restFormOpened = () => {
-  restFormRef.value?.resetFields();
-  restFormRef.value?.clearValidate();
+	restFormRef.value?.resetFields();
+	restFormRef.value?.clearValidate();
 };
 // 小休流程选择下一个环节
 const selectNextStep = (val: any) => {
@@ -848,68 +853,57 @@ state.handlerMainOptions = computed(() => {
 });
 // 确定小休(示忙)
 const clickOnRest = (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  formEl.validate((valid: boolean) => {
-    if (!valid) return;
-    ElMessageBox.confirm(`确认提交?`, '提示', {
-      confirmButtonText: '确认',
-      cancelButtonText: '取消',
-      type: 'warning',
-      draggable: true,
-      cancelButtonClass: 'default-button',
-      autofocus: false,
-    })
-        .then(() => {
-          state.loading = true;
-          if (AppConfigInfo.value.IsRestApproval) {
-            //如果需要审核
-            state.restForm.additions = state.fileList;
-            let submitObj = other.deepClone(state.restForm);
-            if (submitObj.nextHandlers && submitObj.nextHandlers.length) {
-              submitObj.nextHandlers = submitObj.nextHandlers.map((item: any) => {
-                return {
-                  id: item.key,
-                  name: item.value,
-                };
-              });
-              if (submitObj.nextHandlers.length === 1) {
-                submitObj.nextMainHandler = submitObj.nextHandlers[0].id;
-              }
-            }
-            restFlowStartWex(submitObj)
-                .then(() => {
-                  ElNotification({
-                    title: '成功',
-                    message: '申请小休成功',
-                    type: 'success',
-                  });
-                  // 设置休息状态 审核中
-                  useTelStatusStore.setRest(RestStates.InReview);
-                  state.restDialogVisible = false;
-                  state.loading = false;
-                })
-                .catch(() => {
-                  restFlowDel().then(() => {
-                    state.loading = false;
-                    state.restDialogVisible = false;
-                  });
-                });
-          } else {
-            //不需要审核直接开始小休
-            VoiceInterfaceObject.SetBusy(state.restForm.reason); //设置忙碌
-            state.restDialogVisible = false;
-            state.loading = false;
-          }
-        })
-        .catch(() => {});
-  })
+	if (!formEl) return;
+	formEl.validate((valid: boolean) => {
+		if (!valid) return;
+		state.loading = true;
+		if (AppConfigInfo.value.IsRestApproval) {
+			//如果需要审核
+			state.restForm.additions = state.fileList;
+			let submitObj = other.deepClone(state.restForm);
+			if (submitObj.nextHandlers && submitObj.nextHandlers.length) {
+				submitObj.nextHandlers = submitObj.nextHandlers.map((item: any) => {
+					return {
+						id: item.key,
+						name: item.value,
+					};
+				});
+				if (submitObj.nextHandlers.length === 1) {
+					submitObj.nextMainHandler = submitObj.nextHandlers[0].id;
+				}
+			}
+			restFlowStartWex(submitObj)
+				.then(() => {
+					ElNotification({
+						title: '成功',
+						message: '申请小休成功',
+						type: 'success',
+					});
+					// 设置休息状态 审核中
+					useTelStatusStore.setRest(RestStates.InReview);
+					state.restDialogVisible = false;
+					state.loading = false;
+				})
+				.catch(() => {
+					restFlowDel().then(() => {
+						state.loading = false;
+						state.restDialogVisible = false;
+					});
+				});
+		} else {
+			//不需要审核直接开始小休
+			VoiceInterfaceObject.SetBusy(state.restForm.reason); //设置忙碌
+			state.restDialogVisible = false;
+			state.loading = false;
+		}
+	});
 };
 // 设置抽屉
 const mouseup = () => {
 	state.transform = dialogRestRef.value.dialogContentRef.$el.style.transform;
 };
 // 选择常用意见 填入填写框
-const chooseComment = (item: any) => {
+const chooseAdvice = (item: any) => {
 	state.restForm.opinion += item.content;
 };
 // 小休结束
@@ -999,60 +993,54 @@ const unTalkingDeal = () => {
 			useTelStatusStore.setTalkingDeal(false);
 			// 设置话机状态 取消时候处理修改为空闲状态
 			useTelStatusStore.setPhoneControlState(TelStates.dutyOn);
-      VoiceInterfaceObject.EndTalkingDeal(); //结束事后处理
+			VoiceInterfaceObject.EndTalkingDeal(); //结束事后处理
 			state.loading = false;
 		})
 		.catch(() => {});
 };
 // 打开转接弹窗
 const onTransfer = () => {
-  //  重置表单
-  transferFormRef.value?.resetFields();
+	//  重置表单
+	transferFormRef.value?.resetFields();
 	// 获取所有分机列表
 	getTelsLists();
 	state.transferDialogVisible = true;
 };
 // 确认转接
 const clickOnTransfer = (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  formEl.validate((valid: boolean) => {
-    if (!valid) return;
-    VoiceInterfaceObject.TeleSwitch(state.transferForm.telNo);
-    state.transferDialogVisible = false;
-  })
+	if (!formEl) return;
+	formEl.validate((valid: boolean) => {
+		if (!valid) return;
+		VoiceInterfaceObject.TeleSwitch(state.transferForm.telNo);
+		state.transferDialogVisible = false;
+	});
 };
 // 三方会议开始
 const onConference = () => {
-	// state.loading = true;
-	state.metingDialogVisible = true;
-	// meeting({ telNo: telStatusInfo.value.telsNo })
-	// 	.then(() => {
-	// 		ElNotification({
-	// 			title: '成功',
-	// 			message: '三方会议开始',
-	// 			type: 'success',
-	// 		});
-	// 		// 设置三方会议状态
-	// 		useTelStatusStore.setMetTing(true);
-	// 		// 设置话机状态 取消静音修改为会议状态
-	// 		useTelStatusStore.setPhoneControlState(TelStates.onConference);
-	// 		state.loading = false;
-	// 	})
-	// 	.catch(() => {
-	// 		state.loading = false;
-	// 	});
+  ElMessageBox.confirm(`确定确定要开启三方会议,是否继续?`, '提示', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning',
+    draggable: true,
+    cancelButtonClass: 'default-button',
+    autofocus: false,
+  })
+      .then(() => {
+          VoiceInterfaceObject.Dtmf('0'); // 开启dtmf 三方通话
+      })
+      .catch(() => {});
 };
 const onMetingSubmit = (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  formEl.validate((valid: boolean) => {
-    if (!valid) return;
-    state.loading = true;
-    setTimeout(() => {
-      VoiceInterfaceObject.StartMeeting(state.metingForm.metingId, state.metingForm.phoneNo);
-      state.metingDialogVisible = false;
-      state.loading = false;
-    }, 300);
-  })
+	if (!formEl) return;
+	formEl.validate((valid: boolean) => {
+		if (!valid) return;
+		state.loading = true;
+		setTimeout(() => {
+			VoiceInterfaceObject.StartMeeting(state.metingForm.metingId, state.metingForm.phoneNo);
+			state.metingDialogVisible = false;
+			state.loading = false;
+		}, 300);
+	});
 };
 // 确定要结束三方会议
 const onConferenceEnd = () => {
@@ -1088,16 +1076,16 @@ const onOutbound = () => {
 };
 // 外呼保存
 const clickOnOutbound = (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  formEl.validate((valid: boolean) => {
-    if (!valid) return;
-    state.loading = true;
-    setTimeout(() => {
-      VoiceInterfaceObject.DialOut(state.outboundForm.telNo);
-      state.outboundDialogVisible = false;
-      state.loading = false;
-    }, 300);
-  })
+	if (!formEl) return;
+	formEl.validate((valid: boolean) => {
+		if (!valid) return;
+		state.loading = true;
+		setTimeout(() => {
+			VoiceInterfaceObject.DialOut(state.outboundForm.telNo);
+			state.outboundDialogVisible = false;
+			state.loading = false;
+		}, 300);
+	});
 };
 
 // 评价
@@ -1122,106 +1110,114 @@ watch(
 		console.log(`状态改变了:${oldVal}=====>${newVal}`);
 	}
 );
-const checkTelStatus = async ()=>{ // 检查话机状态
-  let telNo:string|number;
-  if(telStatusInfo.value.isDutyOn){ // 如果已签入
-    telNo = telStatusInfo.value.telsNo;
-  }else{ // 如果未签入
-    telNo = state.dutyForm.telNo;
-  }
-  const res = await getTelList({device:telNo});
-  // {
-  //   "device":"8000", //设备
-  //     "psw":"Wex12345",  //注册密码
-  //     "regGroup":"users", //注册组
-  //     "status":0,//分机状态  0离线 1空闲 2振铃 3通话 4值守 5保持 6响铃 7监听中 8会议呼叫中 9会议通话中 10会议禁言
-  //
-  //     "callGuid":"",//呼叫标识
-  //     "meetId":"",//会议号码
-  //     "loginType":"",//登录方式
-  //     "sigin":0,//是否签入  0为签出 1签入
-  //     "agentStatus":0,//座席状态 1空闲 2振铃 3通话 4示忙 5保持 6响铃
-  //     "zloginer":"",//座席员
-  //     "zrole":"",//座席组
-  //     "zloginNumber":""//座席工号
-  // },
-  const agent:any = {
-    0:'签出',
-    1:'签入'
-  }
-  const telStatus:any = {
-    0:'离线',
-    1:'空闲',
-    2:'振铃',
-    3:'通话',
-    4:'值守',
-    5:'保持',
-    6:'响铃',
-    7:'监听中',
-    8:'会议呼叫中',
-    9:'会议通话中',
-    10:'会议禁言'
-  }
-  const {device,status,sigin} = res.data[0];
-console.log('是否签入:',agent[sigin],'分机状态:',telStatus[status],res.data[0])
-  if(sigin === 1){ // 已签入
-    switch (status) { // 以分机状态为准
-      case 1: // 空闲
-        // useTelStatusStore.resetCallInfo();// 重置电话信息
-        // 设置分机号
-        useTelStatusStore.setCallInfo({telsNo: device});
-        // 设置签入状态
-        useTelStatusStore.setDutyState(true);
-        // 设置电话状态
-        useTelStatusStore.setPhoneControlState(TelStates.dutyOn);
-        break;
-      case 2: // 振铃
-        // 设置电话状态 振铃中
-        useTelStatusStore.setPhoneControlState(TelStates.ring);
-        break;
-      case 3: // 通话
-        console.log('通话中,121')
-        // 开始计时
-        startTime();
-        // 设置电话状态 通话中
-        useTelStatusStore.setPhoneControlState(TelStates.onCall);
-        break;
-      case 4: // 示忙
-        // 设置电话状态小休中
-        useTelStatusStore.setPhoneControlState(TelStates.rest);
-        useTelStatusStore.setRest(RestStates.resting);
-        break;
-      case 5: // 保持
-        // 设置电话状态
-        useTelStatusStore.setHold(true);
-        // 设置电话状态
-        useTelStatusStore.setPhoneControlState(TelStates.onHold);
-        break;
-      case 6: // 响铃
-        // useTelStatusStore.setPhoneControlState(TelStates.ringing);
-        break;
-    }
-  }else{ // 未签入 重置电话控件状态
-    // 重置所有状态
-    useTelStatusStore.resetState();
-  }
-}
+const checkTelStatus = async () => {
+	// 检查话机状态
+	let telNo: string | number;
+	if (telStatusInfo.value.isDutyOn) {
+		// 如果已签入
+		telNo = telStatusInfo.value.telsNo;
+	} else {
+		// 如果未签入
+		telNo = state.dutyForm.telNo;
+	}
+	const res = await getTelList({ device: telNo });
+	// {
+	//   "device":"8000", //设备
+	//     "psw":"Wex12345",  //注册密码
+	//     "regGroup":"users", //注册组
+	//     "status":0,//分机状态  0离线 1空闲 2振铃 3通话 4值守 5保持 6响铃 7监听中 8会议呼叫中 9会议通话中 10会议禁言
+	//
+	//     "callGuid":"",//呼叫标识
+	//     "meetId":"",//会议号码
+	//     "loginType":"",//登录方式
+	//     "sigin":0,//是否签入  0为签出 1签入
+	//     "agentStatus":0,//座席状态 1空闲 2振铃 3通话 4示忙 5保持 6响铃
+	//     "zloginer":"",//座席员
+	//     "zrole":"",//座席组
+	//     "zloginNumber":""//座席工号
+	// },
+	const agent: any = {
+		0: '签出',
+		1: '签入',
+	};
+	const telStatus: any = {
+		0: '离线',
+		1: '空闲',
+		2: '振铃',
+		3: '通话',
+		4: '值守',
+		5: '保持',
+		6: '响铃',
+		7: '监听中',
+		8: '会议呼叫中',
+		9: '会议通话中',
+		10: '会议禁言',
+	};
+	const { device, status, sigin } = res.data[0];
+	console.log('是否签入:', agent[sigin], '分机状态:', telStatus[status], res.data[0]);
+	if (sigin === 1) {
+		// 已签入
+		switch (
+			status // 以分机状态为准
+		) {
+			case 1: // 空闲
+				// useTelStatusStore.resetCallInfo();// 重置电话信息
+				// 设置分机号
+				useTelStatusStore.setCallInfo({ telsNo: device });
+				// 设置签入状态
+				useTelStatusStore.setDutyState(true);
+				// 设置电话状态
+				useTelStatusStore.setPhoneControlState(TelStates.dutyOn);
+				break;
+			case 2: // 振铃
+				// 设置电话状态 振铃中
+				useTelStatusStore.setPhoneControlState(TelStates.ring);
+				break;
+			case 3: // 通话
+				console.log('通话中,121');
+				// 开始计时
+				startTime();
+				// 设置电话状态 通话中
+				useTelStatusStore.setPhoneControlState(TelStates.onCall);
+				break;
+			case 4: // 示忙
+				// 设置电话状态小休中
+				useTelStatusStore.setPhoneControlState(TelStates.rest);
+				useTelStatusStore.setRest(RestStates.resting);
+				break;
+			case 5: // 保持
+				// 设置电话状态
+				useTelStatusStore.setHold(true);
+				// 设置电话状态
+				useTelStatusStore.setPhoneControlState(TelStates.onHold);
+				break;
+			case 6: // 响铃
+				// useTelStatusStore.setPhoneControlState(TelStates.ringing);
+				break;
+		}
+	} else {
+		// 未签入 重置电话控件状态
+		// 重置所有状态
+		useTelStatusStore.resetState();
+	}
+};
 onMounted(() => {
-  signalRStart(); //开启消息监听
-  if(telStatusInfo.value.telsNo){// 有分机号
-    initWebsocket(); // 初始化websocket
-  }
-  mittBus.on('startTalkTime', () => {
-    startTime();
-  });
-  mittBus.on('endTalkTime', () => {
-    removeTimer();
-  });
+	signalRStart(); //开启消息监听
+	if (telStatusInfo.value.telsNo) {
+		// 有分机号
+		initWebsocket(); // 初始化websocket
+	}
+	mittBus.on('startTalkTime', () => {
+		startTime();
+	});
+	mittBus.on('endTalkTime', () => {
+		removeTimer();
+	});
 });
 onBeforeMount(() => {
-  mittBus.off('startTalkTime');
-  mittBus.off('endTalkTime');
-  signalR.leaveGroup('CallCenter');
+	mittBus.off('startTalkTime');
+	mittBus.off('endTalkTime');
+	signalR.leaveGroup('CallCenter');
 });
 </script>
 

+ 1 - 1
src/stores/telStatus.ts

@@ -17,7 +17,7 @@ export enum TelStates {
 	rest = 'rest',  // 小休
 	ring = 'ring', // 来电响铃
 	onHold = 'onHold', // 保持中
-	oneHoldOneCall = 'oneHoldOneCall', // 一通电话保持中,一通电话通话中 可以三方通话
+	onTransferSuccess = 'onTransferSuccess', // 转接成功,可以开始三方通话
 	onCall = 'onCall', // 一通电话通话中
 	onTalkingDeal = 'onTalkingDeal', 		// 事后处理中
 	onConference = 'onConference' // 一通电话通话中,会议中

+ 1 - 0
src/types/axios.d.ts

@@ -1,3 +1,4 @@
+import * as axios from 'axios';
 // 扩展 axios 数据返回类型,可自行扩展
 declare module 'axios' {
 	export interface AxiosResponse<T = any> {

+ 0 - 1
src/types/global.d.ts

@@ -23,7 +23,6 @@ declare module '*.vue' {
 }
 
 // 声明文件,定义全局变量
-/* eslint-disable */
 declare interface Window {
 	nextLoading: boolean;
 	versionMonitor:any

+ 1 - 1
src/types/mitt.d.ts

@@ -1,5 +1,5 @@
 // mitt 事件类型定义
-export type MittType = {
+declare type MittType = {
 	openSetingsDrawer?: string; // 打开布局设置弹窗
 	restoreDefault?: string; // 分栏布局,鼠标移入、移出数据显示
 	setSendColumnsChildren?: string; // 分栏布局,鼠标移入、移出菜单数据传入到 navMenu 下的菜单中

+ 1 - 11
src/types/pinia.d.ts

@@ -1,17 +1,7 @@
-/*
- * @Author: zc
- * @Description:
- * @version:
- * @Date: 2022-08-09 16:19:56
- * @LastEditors: Please set LastEditors
- * @LastEditTime: 2022-11-16 15:10:29
- */
 /**
  * 定义接口来定义对象的类型
  * `stores` 全部类型定义在这里
  */
-
-// 用户信息
 declare interface UserInfosState {
 	authBtnList: string[];
 	photo: string;
@@ -119,7 +109,7 @@ enum TelStates {
 	rest = 'rest',  // 小休
 	ring = 'ring', // 来电响铃
 	onHold = 'onHold', // 保持中
-	oneHoldOneCall = 'oneHoldOneCall', // 一通电话保持中,一通电话通话中 可以三方通话
+	onTransferSuccess = 'onTransferSuccess', // 转接成功,可以开始三方通话
 	onCall = 'onCall', // 一通电话通话中
 	onTalkingDeal = 'onTalkingDeal', 		// 事后处理中
 	onConference = 'onConference' // 一通电话通话中,会议中

+ 35 - 4
src/utils/PhoneScript.ts

@@ -54,7 +54,7 @@ export const VoiceInterfaceObject: any = {
 	 */
 	//弹屏 回调
 	Back_TelPhoneEvent: function (returnVal: { Message: string; Params: any }) {
-		let DialArray = returnVal.Message.split(',');
+		let DialArray:EmptyArrayType = returnVal.Message.split(',');
 		let DialInfo: any = <EmptyObjectType>{};
 		DialInfo.fromTel = DialArray[0]; //来电号码
 		DialInfo.telGongHao = DialArray[1]; //来电工号
@@ -370,6 +370,7 @@ export const VoiceInterfaceObject: any = {
 		const returnVal = WebsocketInterface('Send', JSON.stringify(modelJson));
 		if (returnVal != 1) {
 			console.info(WebsocketInterface('GetError', returnVal));
+			ElMessage.error(WebsocketInterface('GetError', returnVal));
 		}
 	},
 	// 语音呼叫 回调
@@ -484,6 +485,7 @@ export const VoiceInterfaceObject: any = {
 		if (returnVal.Params == '0') {
 			console.info(returnVal.Message, '转接成功');
 			ElMessage.success(returnVal.Message);
+
 		} else {
 			console.info(returnVal.Message);
 			ElMessage.error(returnVal.Message);
@@ -509,9 +511,9 @@ export const VoiceInterfaceObject: any = {
 			telType: '', //来电 外呼 转接
 			fromTel: '', // 来电号码
 		});
-		// 设置电话状态
-		useTelStatusStore.setPhoneControlState(TelStates.dutyOn);
-		mittBus.emit('endTalkTime');
+		// 转接成功可以开启三方通话
+		useTelStatusStore.setPhoneControlState(TelStates.onTransferSuccess);
+		// mittBus.emit('endTalkTime');
 	},
 	//代接
 	InsteadOfTele: function (gonghao: any) {
@@ -843,4 +845,33 @@ export const VoiceInterfaceObject: any = {
 			});
 		}
 	},
+	// 获取座席状态
+	GetOnUserState: function () {
+		const param: string = '';
+		const modelJson = this.GetSendModel('GetOnUserState', param);
+		const returnVal = WebsocketInterface('Send', JSON.stringify(modelJson));
+		if (returnVal != 1) {
+			ElMessage(WebsocketInterface('GetError', returnVal));
+		}
+	},
+	// 获取座席状态 回调
+	Back_GetOnUserState: function (returnVal: any) {
+		console.log(returnVal,'当前坐席状态');
+	},
+	//  通话DTMF 在通话过程中,需要给运营商或者对方方式按键信息,可用该接口
+	Dtmf: function (param: string) {
+		const modelJson = this.GetSendModel('Dtmf', param);
+		const returnVal = WebsocketInterface('Send', JSON.stringify(modelJson));
+		if (returnVal != 1) {
+			ElMessage(WebsocketInterface('GetError', returnVal));
+		}
+	},
+	// 通话DTMF 回调
+	Back_Dtmf: function (returnVal: any) {
+		console.log(returnVal,'通话DTMF 回调');
+		// 设置三方会议状态
+		useTelStatusStore.setMetTing(true);
+		// 设置话机状态 设置为会议状态
+		useTelStatusStore.setPhoneControlState(TelStates.onConference);
+	}
 };

+ 0 - 1
src/utils/mitt.ts

@@ -1,6 +1,5 @@
 // https://www.npmjs.com/package/mitt 全局事件总线
 import mitt, { Emitter } from 'mitt';
-import { MittType } from '/@/types/mitt';
 
 // 类型
 const emitter: Emitter<MittType> = mitt<MittType>();

+ 7 - 7
src/utils/theme.ts

@@ -6,13 +6,13 @@ import { ElMessage } from 'element-plus';
  * @returns {string} 返回处理后的颜色值
  */
 export function hexToRgb(str: any) {
-	let hexs: any = '';
+	let hexes: any = '';
 	let reg = /^\#?[0-9A-Fa-f]{6}$/;
 	if (!reg.test(str)) return ElMessage.warning('输入错误的hex');
 	str = str.replace('#', '');
-	hexs = str.match(/../g);
-	for (let i = 0; i < 3; i++) hexs[i] = parseInt(hexs[i], 16);
-	return hexs;
+	hexes = str.match(/../g);
+	for (let i = 0; i < 3; i++) hexes[i] = parseInt(hexes[i], 16);
+	return hexes;
 }
 
 /**
@@ -25,9 +25,9 @@ export function hexToRgb(str: any) {
 export function rgbToHex(r: any, g: any, b: any) {
 	let reg = /^\d{1,3}$/;
 	if (!reg.test(r) || !reg.test(g) || !reg.test(b)) return ElMessage.warning('输入错误的rgb颜色值');
-	let hexs = [r.toString(16), g.toString(16), b.toString(16)];
-	for (let i = 0; i < 3; i++) if (hexs[i].length == 1) hexs[i] = `0${hexs[i]}`;
-	return `#${hexs.join('')}`;
+	let hexes = [r.toString(16), g.toString(16), b.toString(16)];
+	for (let i = 0; i < 3; i++) if (hexes[i].length == 1) hexes[i] = `0${hexes[i]}`;
+	return `#${hexes.join('')}`;
 }
 
 /**

+ 1 - 1
src/utils/websocket.ts

@@ -56,7 +56,7 @@ export const WebsocketInterface = (function () {
                     msgStr = "您的浏览器不支持WebSocket";
                     break;
                 case 0:
-                    msgStr = "WebSocket连接尚未创建";
+                    msgStr = "WebSocket连接尚未创建,请先签入";
                     break;
                 case 1:
                     msgStr = "WebSocket连接已经建立";

+ 324 - 0
src/views/business/countersign/detail/index.vue

@@ -0,0 +1,324 @@
+<template>
+  <div class="business-countersignDetail-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:countersign:detail:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="会签编码" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="节点期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="工单期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="接办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="会签发起部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="会签发起人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="会签发起时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="被会签部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="会签处理人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="会签处理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="orderCountersignDetail">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:Countersign:detail:query')) ElMessage.error('抱歉,您没有权限查看会签明细列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-countersignDetail-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

+ 328 - 0
src/views/business/countersign/index.vue

@@ -0,0 +1,328 @@
+<template>
+  <div class="business-countersign-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:countersign:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="会签编码" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="节点期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="工单期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="接办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="会签发起部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="会签发起人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="会签发起时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="160" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" @click="onDetail(row)" title="查看会签明细" v-auth="'business:countersign:detail'"> 会签明细 </el-button>
+            <el-button link type="primary" @click="onDetail(row)" title="查看工单详情" v-auth="'business:order:countersign:detail'"> 工单详情 </el-button>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="orderCountersign">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:Countersign:query')) ElMessage.error('抱歉,您没有权限查看工单会签列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+// 查看工单详情
+const OrderDetailRef = ref<RefType>(); // 工单详情ref
+const onDetail = (row: any) => {
+  OrderDetailRef.value.openDialog()
+};
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-countersign-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

+ 370 - 0
src/views/business/delay/backlog/index.vue

@@ -0,0 +1,370 @@
+<template>
+	<div class="business-delay-backlog-container layout-pd">
+		<!-- 搜索  -->
+		<el-card shadow="never">
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+				<el-row :gutter="10">
+					<el-col :span="8">
+						<el-form-item label="发布状态" prop="AcceptType">
+							<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+								<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="8">
+						<el-form-item label="工单标题" prop="Keyword">
+							<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+						</el-form-item>
+					</el-col>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布人" prop="Content">
+								<el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布范围" prop="AcceptType">
+								<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+									<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理类型" prop="Channel">
+								<el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+									<el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="热点分类" prop="HotspotId">
+								<el-tree-select
+									class="w100"
+									v-model="state.queryParams.HotspotId"
+									filterable
+									clearable
+									multiple
+									:render-after-expand="false"
+									show-checkbox
+									placeholder="请选择热点分类"
+									:props="HotspotProps"
+									lazy
+									:load="load"
+									node-key="id"
+									check-strictly
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理时间" prop="crTime">
+								<el-date-picker
+									v-model="state.queryParams.crTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeCr"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="归档时间" prop="exTime">
+								<el-date-picker
+									v-model="state.queryParams.exTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeEx"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<el-col :span="8">
+						<div class="flex-end w100">
+							<el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+							<el-button link type="primary" @click="closeSearch">
+								{{ searchCol ? '展开' : '收起' }}
+								<SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+							</el-button>
+						</div>
+					</el-col>
+				</el-row>
+			</el-form>
+		</el-card>
+		<el-card shadow="never">
+      <el-tabs v-model="state.queryParams.status" class="demo-tabs" @tab-change="handleClick">
+        <el-tab-pane :name="item.value" v-for="item in state.tabPaneList" :key="item.value" :label="item.label"></el-tab-pane>
+      </el-tabs>
+			<!-- 表格 -->
+			<el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+				<el-table-column type="selection" width="55" />
+				<el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+				<el-table-column label="工单标题" show-overflow-tooltip width="400">
+					<template #default="{ row }">
+						<el-button link type="primary">{{ row.title }}</el-button>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="employeeName" label="受理人" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ row.employeeName + '[' + row.employeeStaffNo + ']' }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="expiredTime" label="接办时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="acceptTypeText" label="延期申请状态" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="expiredTime" label="延期申请时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="acceptTypeText" label="延期申请人" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="延期申请部门" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="延期申请时限" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="延期申请单位" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="申请理由" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="expiredTime" label="申请前期满时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="通过后期满时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column label="操作" width="240" fixed="right" align="center">
+					<template #default="{ row }">
+						<el-button link type="primary" @click="onOrderDetail(row)" title="查看工单详情" v-auth="'business:delay:backlog:detail'"> 工单详情 </el-button>
+            <el-button link type="primary" @click="approve(row)" title="延期审批" v-auth="'business:delay:backlog:approve'"> 延期审批 </el-button>
+						<el-button link type="primary" @click="processDetail(row)" title="查看流程明细" v-auth="'business:delay:backlog:processDetail'">
+							流程明细
+						</el-button>
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+			<!-- 分页 -->
+			<pagination
+				:total="state.total"
+				v-model:page="state.queryParams.PageIndex"
+				v-model:limit="state.queryParams.PageSize"
+				@pagination="queryList"
+			/>
+		</el-card>
+		<!-- 工单详情 -->
+		<order-detail ref="OrderDetailRef" @updateList="queryList" />
+		<!--  工单延期  -->
+		<order-delay ref="OrderDelayRef" @updateList="queryList" />
+    <!-- 审核记录 -->
+    <audit-record ref="auditRecordRef" />
+	</div>
+</template>
+<script setup lang="ts" name="orderDelayBacklog">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import { ElButton, ElMessage, ElMessageBox, FormInstance } from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import { useRouter } from 'vue-router';
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));  // 工单详情
+const OrderDelay = defineAsyncComponent(() => import('/@/views/business/delay/components/Order-delay.vue'));  // 工单延期
+const AuditRecord = defineAsyncComponent(() => import('/@/components/AuditRecord/index.vue'));  // 流程明细
+
+// 定义变量内容
+const state = reactive(<any>{
+	queryParams: {
+		// 查询条件
+		PageIndex: 1,
+		PageSize: 10,
+		Keyword: '', // 关键字
+		Content: '', // 工单内容
+		AcceptType: '', // 受理类型
+		Channel: '', // 渠道
+		HotspotId: [], // 热点
+		OrgCode: [], // 机构
+		NameOrNo: '', // 受理坐席
+		crTime: [], // 创建时间
+		CreationTimeStart: '', // 创建时间 开始
+		CreationTimeEnd: '', // 创建时间 结束
+		TransferPhone: '', // 转派人
+		EmergencyLevel: [], // 紧急程度
+		exTime: [], // 办理期限
+		ExpiredTimeStart: '', //办理期限 开始
+		ExpiredTimeEnd: '', //办理期限 结束
+		PhoneNo: '', // 手机号
+		Status: [], // 状态
+		pushTypeOptions: '', //
+		PushTypeCode: '', //推送类型
+    status:'0', // 延期状态
+	},
+	tableList: [{}], //表单
+	loading: false, // 加载
+	total: 0, // 总数
+	acceptTypeOptions: [], //受理类型
+	channelOptions: [], // 来源频道
+	emergencyLevelOptions: [], // 紧急程度
+	orderStatusOptions: [], // 工单状态
+	orgsOptions: [], // 部门
+	pushTypeOptions: [], //推送分类
+	orgData: [], // 机构数据
+  tabPaneList: [
+    {
+      label:'延期待办',
+      value:'0',
+    },
+    {
+      label:'延期已办',
+      value:'1',
+    },
+  ], // tab列表
+});
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 展开/收起
+const OrderDetailRef = ref<RefType>(); // 工单详情ref
+const router = useRouter(); // 路由
+// 热点分类远程搜索
+const HotspotProps = {
+	label: 'hotSpotName',
+	children: 'children',
+	isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+	if (node.isLeaf) return resolve([]);
+	let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+	resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+	searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+	if (val) {
+		state.queryParams[startKey] = val[0];
+		state.queryParams[endKey] = val[1];
+	} else {
+		state.queryParams[startKey] = '';
+		state.queryParams[endKey] = '';
+	}
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+	handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+	handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+	const res: any = await listBaseData();
+	state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+	state.channelOptions = res.result?.channelOptions ?? [];
+	state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+	state.orgsOptions = res.result?.orgsOptions ?? [];
+	state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+	state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+	if (!auth('business:delay:backlog:query')) ElMessage.error('抱歉,您没有权限查看工单延期待办!');
+	else {
+	}
+}, 500);
+// 切换tab 查询列表
+const handleClick = () => {
+  queryList();
+};
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	state.queryParams.CreationTimeStart = '';
+	state.queryParams.CreationTimeEnd = '';
+	state.queryParams.ExpiredTimeStart = '';
+	state.queryParams.ExpiredTimeStart = '';
+	queryList();
+}, 500);
+// 导出
+const onExport = () => {
+	console.log('导出');
+};
+const OrderDelayRef = ref<RefType>();
+// 查看延期详情
+const onOrderDetail = (row: any) => {
+	OrderDelayRef.value.openDialog();
+};
+// 流程明细
+const auditRecordRef = ref<RefType>();  // 审核记录ref
+const processDetail = (row:any) => {
+  const params = {
+    title: `审核记录 (${row.title})`,
+    ...row,
+  };
+  auditRecordRef.value.openDialog(params);
+};
+// 延期审批
+const approve = (row: any) => {
+
+};
+// 表格多选
+const multipleTableRef = ref<RefType>();
+const multipleSelection = ref<any>([]);
+const handleSelectionChange = (val: any[]) => {
+	multipleSelection.value = val;
+};
+onMounted(async () => {
+	await getBaseData();
+	queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-delay-backlog-container {
+	.arrow {
+		transition: transform var(--el-transition-duration);
+		cursor: pointer;
+	}
+	.arrow.is-reverse {
+		transform: rotateZ(-180deg);
+	}
+}
+</style>

+ 2 - 2
src/views/business/delay/index.vue

@@ -173,7 +173,7 @@
 						<el-button link type="primary" @click="processDetail(row)" title="查看流程明细" v-auth="'business:delay:processDetail'">
 							流程明细
 						</el-button>
-						<el-button link type="primary" @click="revocation(row)" title="撤销延期申请" v-auth="'business:delay:revocation'"> 撤销 </el-button>
+						<el-button link type="primary" @click="revocation(row)" title="撤销延期申请" v-auth="'business:delay:revoke'"> 撤销 </el-button>
 					</template>
 				</el-table-column>
 				<template #empty>
@@ -294,7 +294,7 @@ const getBaseData = async () => {
 };
 /** 获取列表 */
 const queryList = throttle(() => {
-	if (!auth('business:backlog:query')) ElMessage.error('抱歉,您没有权限查看工单待办!');
+	if (!auth('business:backlog:query')) ElMessage.error('抱歉,您没有权限查看工单延期申请!');
 	else {
 	}
 }, 500);

+ 325 - 0
src/views/business/discern/apply/index.vue

@@ -0,0 +1,325 @@
+<template>
+	<div class="business-discern-apply-container layout-pd">
+		<!-- 搜索  -->
+		<el-card shadow="never">
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+				<el-row :gutter="10">
+					<el-col :span="8">
+						<el-form-item label="发布状态" prop="AcceptType">
+							<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+								<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="8">
+						<el-form-item label="工单标题" prop="Keyword">
+							<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+						</el-form-item>
+					</el-col>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布人" prop="Content">
+								<el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布范围" prop="AcceptType">
+								<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+									<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理类型" prop="Channel">
+								<el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+									<el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="热点分类" prop="HotspotId">
+								<el-tree-select
+									class="w100"
+									v-model="state.queryParams.HotspotId"
+									filterable
+									clearable
+									multiple
+									:render-after-expand="false"
+									show-checkbox
+									placeholder="请选择热点分类"
+									:props="HotspotProps"
+									lazy
+									:load="load"
+									node-key="id"
+									check-strictly
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理时间" prop="crTime">
+								<el-date-picker
+									v-model="state.queryParams.crTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeCr"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="归档时间" prop="exTime">
+								<el-date-picker
+									v-model="state.queryParams.exTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeEx"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<el-col :span="8">
+						<div class="flex-end w100">
+							<el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+							<el-button link type="primary" @click="closeSearch">
+								{{ searchCol ? '展开' : '收起' }}
+								<SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+							</el-button>
+						</div>
+					</el-col>
+				</el-row>
+			</el-form>
+		</el-card>
+		<el-card shadow="never">
+			<!-- 功能按钮 -->
+			<div class="mb20">
+				<el-button type="primary" @click="onExport" v-auth="'business:screen:export'" :disabled="!multipleSelection.length">
+					<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+				</el-button>
+			</div>
+			<!-- 表格 -->
+			<el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+				<el-table-column type="selection" width="55" />
+				<el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="来源方式" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="中心会签" show-overflow-tooltip></el-table-column>
+				<el-table-column label="标题" show-overflow-tooltip width="400">
+					<template #default="{ row }">
+						<el-button link type="primary">{{ row.title }}</el-button>
+					</template>
+				</el-table-column>
+				<el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="employeeName" label="受理人" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ row.employeeName + '[' + row.employeeStaffNo + ']' }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="acceptTypeText" label="一级部门" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="办结时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="回访时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="acceptTypeText" label="被回访部门" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="部门办件结果" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="acceptTypeText" label="不满意原因" show-overflow-tooltip></el-table-column>
+				<el-table-column label="操作" width="150" fixed="right" align="center">
+					<template #default="{ row }">
+						<el-button link type="primary" @click="submitDiscern(row)" title="提交甄别申请" v-auth="'business:discern:apply:submit'"> 提交甄别 </el-button>
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+			<!-- 分页 -->
+			<pagination
+				:total="state.total"
+				v-model:page="state.queryParams.PageIndex"
+				v-model:limit="state.queryParams.PageSize"
+				@pagination="queryList"
+			/>
+		</el-card>
+	</div>
+</template>
+<script setup lang="ts" name="orderDiscernApply">
+import { onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import { ElButton, ElMessage, FormInstance } from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import { useRouter } from 'vue-router';
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+	queryParams: {
+		// 查询条件
+		PageIndex: 1,
+		PageSize: 10,
+		Keyword: '', // 关键字
+		Content: '', // 工单内容
+		AcceptType: '', // 受理类型
+		Channel: '', // 渠道
+		HotspotId: [], // 热点
+		OrgCode: [], // 机构
+		NameOrNo: '', // 受理坐席
+		crTime: [], // 创建时间
+		CreationTimeStart: '', // 创建时间 开始
+		CreationTimeEnd: '', // 创建时间 结束
+		TransferPhone: '', // 转派人
+		EmergencyLevel: [], // 紧急程度
+		exTime: [], // 办理期限
+		ExpiredTimeStart: '', //办理期限 开始
+		ExpiredTimeEnd: '', //办理期限 结束
+		PhoneNo: '', // 手机号
+		Status: [], // 状态
+		pushTypeOptions: '', //
+		PushTypeCode: '', //推送类型
+	},
+	tableList: [{}], //表单
+	loading: false, // 加载
+	total: 0, // 总数
+	acceptTypeOptions: [], //受理类型
+	channelOptions: [], // 来源频道
+	emergencyLevelOptions: [], // 紧急程度
+	orderStatusOptions: [], // 工单状态
+	orgsOptions: [], // 部门
+	pushTypeOptions: [], //推送分类
+	orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+	label: 'hotSpotName',
+	children: 'children',
+	isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+	if (node.isLeaf) return resolve([]);
+	let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+	resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+	searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+	if (val) {
+		state.queryParams[startKey] = val[0];
+		state.queryParams[endKey] = val[1];
+	} else {
+		state.queryParams[startKey] = '';
+		state.queryParams[endKey] = '';
+	}
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+	handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+	handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+	const res: any = await listBaseData();
+	state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+	state.channelOptions = res.result?.channelOptions ?? [];
+	state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+	state.orgsOptions = res.result?.orgsOptions ?? [];
+	state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+	state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+	if (!auth('business:discern:apply:query')) ElMessage.error('抱歉,您没有权限查看甄别待申请!');
+	else {
+	}
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	state.queryParams.CreationTimeStart = '';
+	state.queryParams.CreationTimeEnd = '';
+	state.queryParams.ExpiredTimeStart = '';
+	state.queryParams.ExpiredTimeStart = '';
+	queryList();
+}, 500);
+// 新增工单
+const onAddWorkOrder = () => {
+	// 跳转到录入工单页面
+	router.push('/business/order/accept');
+};
+// 表格多选
+const multipleTableRef = ref<RefType>();
+const multipleSelection = ref<any>([]);
+const handleSelectionChange = (val: any[]) => {
+	multipleSelection.value = val;
+};
+// 导出
+const onExport = () => {
+	console.log('导出');
+};
+// 提交甄别申请
+const submitDiscern = (row: any) => {
+	console.log('提交甄别申请');
+};
+onMounted(async () => {
+	await getBaseData();
+	queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-discern-apply-container {
+	.arrow {
+		transition: transform var(--el-transition-duration);
+		cursor: pointer;
+	}
+	.arrow.is-reverse {
+		transform: rotateZ(-180deg);
+	}
+}
+</style>

+ 343 - 0
src/views/business/discern/backlog/index.vue

@@ -0,0 +1,343 @@
+<template>
+	<div class="business-discern-backlog-container layout-pd">
+		<!-- 搜索  -->
+		<el-card shadow="never">
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+				<el-row :gutter="10">
+					<el-col :span="8">
+						<el-form-item label="发布状态" prop="AcceptType">
+							<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+								<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="8">
+						<el-form-item label="工单标题" prop="Keyword">
+							<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+						</el-form-item>
+					</el-col>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布人" prop="Content">
+								<el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布范围" prop="AcceptType">
+								<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+									<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理类型" prop="Channel">
+								<el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+									<el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="热点分类" prop="HotspotId">
+								<el-tree-select
+									class="w100"
+									v-model="state.queryParams.HotspotId"
+									filterable
+									clearable
+									multiple
+									:render-after-expand="false"
+									show-checkbox
+									placeholder="请选择热点分类"
+									:props="HotspotProps"
+									lazy
+									:load="load"
+									node-key="id"
+									check-strictly
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理时间" prop="crTime">
+								<el-date-picker
+									v-model="state.queryParams.crTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeCr"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="归档时间" prop="exTime">
+								<el-date-picker
+									v-model="state.queryParams.exTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeEx"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<el-col :span="8">
+						<div class="flex-end w100">
+							<el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+							<el-button link type="primary" @click="closeSearch">
+								{{ searchCol ? '展开' : '收起' }}
+								<SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+							</el-button>
+						</div>
+					</el-col>
+				</el-row>
+			</el-form>
+		</el-card>
+		<el-card shadow="never">
+			<!-- 功能按钮 -->
+      <el-tabs v-model="state.queryParams.status" class="demo-tabs" @tab-change="handleClick">
+        <el-tab-pane :name="item.value" v-for="item in state.tabPaneList" :key="item.value" :label="item.label"></el-tab-pane>
+      </el-tabs>
+			<!-- 表格 -->
+			<el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="当前节点" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="处理人" show-overflow-tooltip></el-table-column>
+        <el-table-column label="标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="employeeName" label="受理人" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ row.employeeName + '[' + row.employeeStaffNo + ']' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="一级部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="接办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="回访时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="甄别申请时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="甄别申请人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="甄别申请部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="甄别申请类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="甄别申请原因" show-overflow-tooltip></el-table-column>
+				<el-table-column label="操作" width="150" fixed="right" align="center">
+					<template #default="{ row }">
+						<el-button link type="primary" @click="approve(row)" title="查看甄别详情" v-auth="'business:discern:backlog:approve'"> 甄别审批 </el-button>
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+			<!-- 分页 -->
+			<pagination
+				:total="state.total"
+				v-model:page="state.queryParams.PageIndex"
+				v-model:limit="state.queryParams.PageSize"
+				@pagination="queryList"
+			/>
+		</el-card>
+	</div>
+</template>
+<script setup lang="ts" name="orderDiscernBacklog">
+import { onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import { ElButton, ElMessage, FormInstance } from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import { useRouter } from 'vue-router';
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+	queryParams: {
+		// 查询条件
+		PageIndex: 1,
+		PageSize: 10,
+		Keyword: '', // 关键字
+		Content: '', // 工单内容
+		AcceptType: '', // 受理类型
+		Channel: '', // 渠道
+		HotspotId: [], // 热点
+		OrgCode: [], // 机构
+		NameOrNo: '', // 受理坐席
+		crTime: [], // 创建时间
+		CreationTimeStart: '', // 创建时间 开始
+		CreationTimeEnd: '', // 创建时间 结束
+		TransferPhone: '', // 转派人
+		EmergencyLevel: [], // 紧急程度
+		exTime: [], // 办理期限
+		ExpiredTimeStart: '', //办理期限 开始
+		ExpiredTimeEnd: '', //办理期限 结束
+		PhoneNo: '', // 手机号
+		Status: [], // 状态
+		pushTypeOptions: '', //
+		PushTypeCode: '', //推送类型
+    status:'0'
+	},
+	tableList: [{}], //表单
+	loading: false, // 加载
+	total: 0, // 总数
+	acceptTypeOptions: [], //受理类型
+	channelOptions: [], // 来源频道
+	emergencyLevelOptions: [], // 紧急程度
+	orderStatusOptions: [], // 工单状态
+	orgsOptions: [], // 部门
+	pushTypeOptions: [], //推送分类
+	orgData: [], // 机构数据
+  tabPaneList: [
+    {
+      label:'甄别待办',
+      value:'0',
+    },
+    {
+      label:'甄别已办',
+      value:'1',
+    },
+  ], // tab列表
+});
+// 热点分类远程搜索
+const HotspotProps = {
+	label: 'hotSpotName',
+	children: 'children',
+	isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+	if (node.isLeaf) return resolve([]);
+	let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+	resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+	searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+	if (val) {
+		state.queryParams[startKey] = val[0];
+		state.queryParams[endKey] = val[1];
+	} else {
+		state.queryParams[startKey] = '';
+		state.queryParams[endKey] = '';
+	}
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+	handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+	handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+	const res: any = await listBaseData();
+	state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+	state.channelOptions = res.result?.channelOptions ?? [];
+	state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+	state.orgsOptions = res.result?.orgsOptions ?? [];
+	state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+	state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+	if (!auth('business:discern:backlog:query')) ElMessage.error('抱歉,您没有权限查看甄别待办!');
+	else {
+	}
+}, 500);
+// 切换tab 查询列表
+const handleClick = () => {
+  queryList();
+};
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	state.queryParams.CreationTimeStart = '';
+	state.queryParams.CreationTimeEnd = '';
+	state.queryParams.ExpiredTimeStart = '';
+	state.queryParams.ExpiredTimeStart = '';
+	queryList();
+}, 500);
+// 新增工单
+const onAddWorkOrder = () => {
+	// 跳转到录入工单页面
+	router.push('/business/order/accept');
+};
+// 表格多选
+const multipleTableRef = ref<RefType>();
+const multipleSelection = ref<any>([]);
+const handleSelectionChange = (val: any[]) => {
+	multipleSelection.value = val;
+};
+// 导出
+const onExport = () => {
+	console.log('导出');
+};
+// 甄别审批
+const approve = (row: any) => {
+	console.log('甄别审批');
+};
+onMounted(async () => {
+	await getBaseData();
+	queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-discern-backlog-container {
+	.arrow {
+		transition: transform var(--el-transition-duration);
+		cursor: pointer;
+	}
+	.arrow.is-reverse {
+		transform: rotateZ(-180deg);
+	}
+}
+</style>

+ 7 - 7
src/views/business/screen/index.vue → src/views/business/discern/index.vue

@@ -1,5 +1,5 @@
 <template>
-	<div class="business-screen-container layout-pd">
+	<div class="business-discern-container layout-pd">
 		<!-- 搜索  -->
 		<el-card shadow="never">
 			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
@@ -114,7 +114,7 @@
 		<el-card shadow="never">
 			<!-- 功能按钮 -->
 			<div class="mb20">
-				<el-button type="primary" @click="onExport" v-auth="'business:screen:export'" :disabled="!multipleSelection.length">
+				<el-button type="primary" @click="onExport" v-auth="'business:discern:export'" :disabled="!multipleSelection.length">
 					<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
 				</el-button>
 			</div>
@@ -172,7 +172,7 @@
 				<el-table-column prop="acceptTypeText" label="甄别申请原因" show-overflow-tooltip></el-table-column>
 				<el-table-column label="操作" width="150" fixed="right" align="center">
 					<template #default="{ row }">
-						<el-button link type="primary" @click="onDetail(row)" title="查看甄别详情" v-auth="'business:screen:detail'"> 甄别详情 </el-button>
+						<el-button link type="primary" @click="onDetail(row)" title="查看甄别详情" v-auth="'business:discern:detail'"> 甄别详情 </el-button>
 					</template>
 				</el-table-column>
 				<template #empty>
@@ -189,7 +189,7 @@
 		</el-card>
 	</div>
 </template>
-<script setup lang="ts" name="businessScreen">
+<script setup lang="ts" name="orderDiscern">
 import { onMounted, reactive, ref } from 'vue';
 import { hotSpotType, listBaseData } from '/@/api/business/order';
 import { ElButton, ElMessage, FormInstance } from 'element-plus';
@@ -228,7 +228,7 @@ const state = reactive(<any>{
 		pushTypeOptions: '', //
 		PushTypeCode: '', //推送类型
 	},
-	tableList: [], //表单
+	tableList: [{}], //表单
 	loading: false, // 加载
 	total: 0, // 总数
 	acceptTypeOptions: [], //受理类型
@@ -285,7 +285,7 @@ const getBaseData = async () => {
 };
 /** 获取列表 */
 const queryList = throttle(() => {
-	if (!auth('business:screen:query')) ElMessage.error('抱歉,您没有权限查看工单待办!');
+	if (!auth('business:discern:query')) ElMessage.error('抱歉,您没有权限查看工单待办!');
 	else {
 	}
 }, 500);
@@ -326,7 +326,7 @@ onMounted(async () => {
 </script>
 
 <style scoped lang="scss">
-.business-screen-container {
+.business-discern-container {
 	.arrow {
 		transition: transform var(--el-transition-duration);
 		cursor: pointer;

+ 336 - 0
src/views/business/followUp/backlog/index.vue

@@ -0,0 +1,336 @@
+<template>
+	<div class="business-followUp-backlog-container layout-pd">
+		<!-- 搜索  -->
+		<el-card shadow="never">
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+				<el-row :gutter="10">
+					<el-col :span="8">
+						<el-form-item label="关键字" prop="Keyword">
+							<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="8">
+						<el-form-item label="回访状态" prop="AcceptType">
+							<el-select v-model="state.queryParams.AcceptType" placeholder="请选择回访状态" multiple clearable class="w100">
+								<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理时间" prop="crTime">
+								<el-date-picker
+									v-model="state.queryParams.crTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeCr"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="归档时间" prop="exTime">
+								<el-date-picker
+									v-model="state.queryParams.exTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeEx"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="回访时间" prop="exTime">
+								<el-date-picker
+									v-model="state.queryParams.exTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeEx"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="回访方式" prop="AcceptType">
+								<el-select v-model="state.queryParams.AcceptType" placeholder="请选择回访方式" multiple clearable class="w100">
+									<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<el-col :span="8">
+						<div class="flex-end w100">
+							<el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+							<el-button link type="primary" @click="closeSearch">
+								{{ searchCol ? '展开' : '收起' }}
+								<SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+							</el-button>
+						</div>
+					</el-col>
+				</el-row>
+			</el-form>
+		</el-card>
+		<el-card shadow="never">
+			<!-- 功能按钮 -->
+			<div class="mb20">
+				<el-button type="primary" @click="onTextMessageFollowUp" :disabled="!multipleSelection.length" v-auth="'business:followUp:backlog:textMessage'">
+					<SvgIcon name="ele-Message" class="mr5" />短信回访</el-button
+				>
+				<el-button type="primary" @click="multiplePeople" :disabled="!multipleSelection.length" v-auth="'business:followUp:backlog:multiplePeople'">
+					<SvgIcon name="ele-User" class="mr5" />批量分配</el-button
+				>
+				<el-button type="primary" @click="smartFollowUp" :disabled="!multipleSelection.length" v-auth="'business:followUp:backlog:smart'">
+					<SvgIcon name="iconfont icon-diannao1" class="mr5" />智能回访</el-button
+				>
+				<el-button type="primary" @click="onExport" :disabled="!multipleSelection.length" v-auth="'business:followUp:backlog:export'">
+					<SvgIcon name="iconfont icon-daochu" class="mr5" />导出</el-button
+				>
+			</div>
+			<!-- 表格 -->
+			<el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+				<el-table-column type="selection" width="55" />
+				<el-table-column prop="no" label="工单编码" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="回访状态" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="回访方式" show-overflow-tooltip></el-table-column>
+				<el-table-column label="工单标题" show-overflow-tooltip width="400">
+					<template #default="{ row }">
+						<el-button link type="primary">{{ row.title }}</el-button>
+					</template>
+				</el-table-column>
+				<el-table-column prop="no" label="受理类型" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="热点分类" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="expiredTime" label="受理人" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ row.employeeName + '[' + row.employeeStaffNo + ']' }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="no" label="一级部门" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="接办部门" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="办结时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="发布时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="回访任务创建时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="no" label="回访人" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="是否接通" show-overflow-tooltip></el-table-column>
+				<el-table-column label="操作" width="150" fixed="right" align="center">
+					<template #default="{ row }">
+						<el-button link type="primary" @click="onOrderDetail(row)" title="查看工单详情" v-auth="'business:waitFollowUp:detail'"> 工单详情 </el-button>
+						<el-button link type="primary" @click="onManpower(row)" title="工单回访" v-auth="'business:followUp:backlog:manpower'"> 回访 </el-button>
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+			<!-- 分页 -->
+			<pagination
+				:total="state.total"
+				v-model:page="state.queryParams.PageIndex"
+				v-model:limit="state.queryParams.PageSize"
+				@pagination="queryList"
+			/>
+		</el-card>
+		<!-- 回访 -->
+		<follow-up-detail ref="followUpDetailRef" @updateList="queryList" />
+		<!-- 工单详情 -->
+		<order-detail ref="OrderDetailRef" @updateList="queryList" />
+	</div>
+</template>
+
+<script setup lang="ts" name="orderFollowUpBacklog">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { ElButton, ElMessage, ElMessageBox, FormInstance } from 'element-plus';
+import { listBaseData } from '/@/api/business/order';
+import { auth } from '/@/utils/authFunction';
+import { throttle } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import { useRouter } from 'vue-router';
+// 引入组件
+const FollowUpDetail = defineAsyncComponent(() => import('/@/views/business/followUp/component/Follow-up-detail.vue'));   // 回访
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));  // 工单详情
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+	queryParams: {
+		// 查询条件
+		PageIndex: 1,
+		PageSize: 10,
+		Keyword: '', // 关键字
+		Content: '', // 工单内容
+		AcceptType: '', // 受理类型
+		Channel: '', // 渠道
+		HotspotId: [], // 热点
+		OrgCode: [], // 机构
+		NameOrNo: '', // 受理坐席
+		crTime: [], // 创建时间
+		CreationTimeStart: '', // 创建时间 开始
+		CreationTimeEnd: '', // 创建时间 结束
+		TransferPhone: '', // 转派人
+		EmergencyLevel: [], // 紧急程度
+		exTime: [], // 办理期限
+		ExpiredTimeStart: '', //办理期限 开始
+		ExpiredTimeEnd: '', //办理期限 结束
+		PhoneNo: '', // 手机号
+		Status: [], // 状态
+		pushTypeOptions: '', //
+		PushTypeCode: '', //推送类型
+	},
+	tableList: [{}], //表单
+	loading: false, // 加载
+	total: 0, // 总数
+	acceptTypeOptions: [], //受理类型
+	channelOptions: [], // 来源频道
+	emergencyLevelOptions: [], // 紧急程度
+	orderStatusOptions: [], // 工单状态
+	orgsOptions: [], // 部门
+	pushTypeOptions: [], //推送分类
+	orgData: [], // 机构数据
+});
+// 展开/收起
+const closeSearch = () => {
+	searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+	if (val) {
+		state.queryParams[startKey] = val[0];
+		state.queryParams[endKey] = val[1];
+	} else {
+		state.queryParams[startKey] = '';
+		state.queryParams[endKey] = '';
+	}
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+	handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+	handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+	const res: any = await listBaseData();
+	state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+	state.channelOptions = res.result?.channelOptions ?? [];
+	state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+	state.orgsOptions = res.result?.orgsOptions ?? [];
+	state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+	state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+	if (!auth('business:followUp:backlog:query')) ElMessage.error('抱歉,您没有权限查看待回访列表!');
+	else {
+	}
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	state.queryParams.CreationTimeStart = '';
+	state.queryParams.CreationTimeEnd = '';
+	state.queryParams.ExpiredTimeStart = '';
+	state.queryParams.ExpiredTimeStart = '';
+	queryList();
+}, 500);
+// 短信回访
+const onTextMessageFollowUp = () => {
+	ElMessageBox.confirm('您确定要短信回访吗?', '提示', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+		type: 'warning',
+	})
+		.then(() => {
+			state.loading = true;
+		})
+		.catch(() => {
+			// 取消
+		});
+};
+// 批量分配
+const multiplePeople = () => {
+	console.log('批量分配');
+};
+// 智能回访
+const smartFollowUp = () => {
+	console.log('智能回访');
+};
+// 表格多选
+const multipleTableRef = ref<RefType>();
+const multipleSelection = ref<any>([]);
+const handleSelectionChange = (val: any[]) => {
+	multipleSelection.value = val;
+};
+// 导出
+const onExport = () => {
+	console.log('导出');
+};
+// 工单详情
+const OrderDetailRef = ref<RefType>();
+const onOrderDetail = (row: any) => {
+	OrderDetailRef.value.openDialog(row);
+};
+// 回访
+const followUpDetailRef = ref<RefType>();
+const onManpower = (row: any) => {
+  followUpDetailRef.value.openDialog(row);
+};
+onMounted(async () => {
+	await getBaseData();
+	queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-followUp-backlog-container {
+	.arrow {
+		transition: transform var(--el-transition-duration);
+		cursor: pointer;
+	}
+	.arrow.is-reverse {
+		transform: rotateZ(-180deg);
+	}
+}
+</style>

+ 461 - 0
src/views/business/followUp/component/Follow-up-detail.vue

@@ -0,0 +1,461 @@
+<template>
+    <el-dialog
+        v-model="state.dialogVisible"
+        draggable
+        title="回访"
+        ref="dialogRef"
+        width="50%"
+        append-to-body
+        @mouseup="mouseup"
+        :style="'transform: ' + state.transform + ';'"
+    >
+      <el-collapse v-model="state.collapseArr" class="collapse-box" v-loading="state.loading">
+        <!-- 工单信息 -->
+        <el-collapse-item name="1">
+          <template #title>
+            <p class="pl20">
+              <b class="font14">工单信息</b>
+            </p>
+          </template>
+          <div class="collapse-container pb1">
+            <el-form label-width="100px">
+              <el-row :gutter="10">
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="工单编号"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="受理时间"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="受理人"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="来源方式"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="受理类型"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="热点分类"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="工单标题"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="工单内容"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="办理结果"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form>
+          </div>
+        </el-collapse-item>
+        <el-collapse-item name="2">
+          <template #title>
+            <p class="pl20">
+              <b class="font14">来电人信息</b>
+            </p>
+          </template>
+          <div class="collapse-container pb1">
+            <el-form label-width="100px">
+              <el-row :gutter="10">
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="来电人姓名"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="来电号码">
+                    {{ state.ruleForm.channelText }} <el-button link type="primary" class="ml5" title="录音文件" @click="onCall">录音文件</el-button>
+                    <!-- <el-popover :width="480" trigger="hover">
+                        <template #reference>
+                          <el-button link type="primary" class="ml5" title="播放录音"><SvgIcon name="ele-Headset" size="16px" /></el-button>
+                        </template>
+                        <AudioPlayer ref="AudioPlayerRef" :url="state.ruleForm.url" />
+                      </el-popover> -->
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="来电人性别"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="号码归属地"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="邮箱"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="联系电话">
+                    {{ state.ruleForm.channelText }}
+                    <el-checkbox-group v-model="checkedCities" :min="0" :max="1" class="ml10">
+                      <el-checkbox v-for="city in cities" :key="city.value" :label="city.value">{{ city.label }}</el-checkbox>
+                    </el-checkbox-group>
+                    <el-button link type="primary" class="ml5" title="呼叫" @click="onCall"><SvgIcon name="ele-Phone" size="16px" /></el-button>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="联系地址"> {{ state.ruleForm.channelText }} </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form>
+          </div>
+        </el-collapse-item>
+        <el-collapse-item name="3">
+          <template #title>
+            <p class="pl20">
+              <b class="font14">回访信息</b>
+            </p>
+          </template>
+          <div class="collapse-container pb1">
+            <el-form label-width="140px" ref="ruleFormRef" :model="state.ruleForm" label-position="left">
+              <el-row :gutter="10">
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="当前回访人">
+                    {{ state.ruleForm.title }}
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="当前工单已回访次数">
+                    {{ state.ruleForm.title }}次 <el-button type="primary" class="ml5" title="查看回访记录" link>查看回访记录</el-button>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="回访标签">
+                    <el-checkbox v-model="state.ruleForm.switch">未接通</el-checkbox>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="是否重办">
+                    <el-radio-group v-model="state.ruleForm.switch" class="ml-4">
+                      <el-radio :label="true">是</el-radio>
+                      <el-radio :label="false">否</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="当前工单已重办次数">
+                    {{ state.ruleForm.title }}次 <el-button type="primary" class="ml5" title="查看重办记录" link>查看重办记录</el-button>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="语音评价">
+                    <el-radio-group v-model="state.ruleForm.radio">
+                      <el-radio :label="item.value" v-for="item in seatRateArray" :key="item.value">{{ item.label }}</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="话务员评价">
+                    <el-radio-group v-model="state.ruleForm.radio">
+                      <el-radio :label="item.value" v-for="item in seatRateArray" :key="item.value">{{ item.label }}</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="话务员回访内容">
+                    <common-advice
+                        @chooseAdvice="chooseAdvice"
+                        v-model="state.ruleForm.handleResult"
+                        placeholder="请填写话务员回访内容"
+                        :loading="state.loading"
+                        :commonEnum="commonEnum.Seat"
+                        :minRows="5"
+                        :maxRows="10"
+                        drawerWidth="40%"
+                    />
+                  </el-form-item>
+                </el-col>
+              </el-row>
+              <el-row v-for="item in list" :key="item.id" :gutter="20">
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-divider content-position="left"><span class="font18 bold">{{item.name}}</span></el-divider>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="部门办件结果" prop="licenceTypeObj" :rules="[{ required: true, message: '请选择部门办件结果', trigger: 'change' }]">
+                    <el-select
+                        v-model="state.ruleForm.licenceTypeObj"
+                        placeholder="请选择部门办件结果"
+                        class="w100"
+                        clearable
+                    >
+                      <el-option v-for="item in state.licenceTypeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="不满意原因" prop="licenceTypeObj" :rules="[{ required: true, message: '请选择不满意原因', trigger: 'change' }]">
+                    <el-select
+                        v-model="state.ruleForm.licenceTypeObj"
+                        placeholder="请选择不满意原因"
+                        class="w100"
+                        clearable
+                    >
+                      <el-option v-for="item in state.licenceTypeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+                  <el-form-item label="部门办件态度" prop="licenceTypeObj" :rules="[{ required: true, message: '请选择部门办件态度', trigger: 'change' }]">
+                    <el-select
+                        v-model="state.ruleForm.licenceTypeObj"
+                        placeholder="请选择部门办件态度"
+                        class="w100"
+                        clearable
+                    >
+                      <el-option v-for="item in state.licenceTypeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                  <el-form-item label="部门回访内容" prop="handleResult" :rules="[{ required: true, message: '请选择部门办件结果', trigger: 'change' }]">
+                    <common-advice
+                        @chooseAdvice="chooseAdvice"
+                        v-model="state.ruleForm.handleResult"
+                        placeholder="请填写部门回访内容"
+                        :loading="state.loading"
+                        :commonEnum="commonEnum.Seat"
+                        :minRows="5"
+                        :maxRows="10"
+                        drawerWidth="40%"
+                    />
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form>
+          </div>
+        </el-collapse-item>
+      </el-collapse>
+
+      <template #footer>
+			<span class="dialog-footer">
+				<el-button @click="onCancel" class="default-button">取 消</el-button>
+				<el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading" v-auth="'business:waitFollowUp:manpower'">保存</el-button>
+			</span>
+      </template>
+    </el-dialog>
+</template>
+<script setup lang="ts" name="orderFollowUpDetail">
+import { defineAsyncComponent, reactive, ref } from 'vue';
+import { FormInstance} from 'element-plus';
+import { VoiceInterfaceObject } from '/@/utils/PhoneScript';
+import { commonEnum } from '/@/utils/constants';
+
+// 引入组件
+const CommonAdvice = defineAsyncComponent(() => import('/@/components/CommonAdvice/index.vue')); // 常用意见
+// 定义子组件向父组件传值/事件
+const emit = defineEmits(['updateList']);
+// 定义变量内容
+const state = reactive<any>({
+	collapseArr: ['1', '2', '3'], // 折叠面板
+	dialogVisible: false, // 是否显示弹窗
+	loading: false, // 是否显示加载
+  transform: 'translate(0px, 0px)', // 附件弹窗位置
+	ruleForm: {
+		// 表单数据
+		title: '标题内容',
+		content: '内容内容内容内容内容内容内容内容内容内容内容内容内容',
+		result: '办理结果内容',
+		handleResult: '办理结果内容',
+		radio1: '1',
+		departmentList: [
+			{
+				departmentName: '部门名称1',
+				radio: '1',
+			},
+			{
+				departmentName: '部门名称2',
+				radio: '1',
+			},
+			{
+				departmentName: '部门名称3',
+				radio: '1',
+			},
+		],
+		channelText: '212',
+		switch: false,
+	},
+  licenceTypeOptions:[]
+});
+const ruleFormRef = ref<RefType>();
+const checkedCities = ref([]);
+const cities = [
+	{ label: '加0', value: '1' },
+	{ label: '去0', value: '2' },
+];
+const list = ref([
+  {
+    name:'市交通局',
+licenceTypeObj:'',
+    id:1
+  }
+])
+const seatRateArray = ref<EmptyArrayType>([
+	{
+		label: '非常满意',
+		value: '1',
+	},
+	{
+		label: '满意',
+		value: '2',
+	},
+	{
+		label: '一般',
+		value: '3',
+	},
+	{
+		label: '不满意',
+		value: '4',
+	},
+	{
+		label: '非常不满意',
+		value: '5',
+	},
+	{
+		label: '未评价',
+		value: '6',
+	},
+]); // 坐席评价列表
+const departmentRateArray = ref<EmptyArrayType>([
+	{
+		label: '非常满意',
+		value: '1',
+	},
+	{
+		label: '满意',
+		value: '2',
+	},
+	{
+		label: '基本满意',
+		value: '3',
+	},
+	{
+		label: '不满意',
+		value: '4',
+	},
+	{
+		label: '非常不满意',
+		value: '5',
+	},
+	{
+		label: '未评价',
+		value: '6',
+	},
+]); // 部门评价列表
+const departmentAtiAttitude = ref<EmptyArrayType>([
+	{
+		label: '非常满意',
+		value: '1',
+	},
+	{
+		label: '满意',
+		value: '2',
+	},
+	{
+		label: '基本满意',
+		value: '3',
+	},
+	{
+		label: '不满意',
+		value: '4',
+	},
+	{
+		label: '非常不满意',
+		value: '5',
+	},
+	{
+		label: '未评价',
+		value: '6',
+	},
+]); // 部门态度列表
+// 打开弹窗
+const openDialog = () => {
+	state.loading = false;
+	state.dialogVisible = true;
+}
+// 设置抽屉
+const dialogRef = ref<RefType>(); // 弹窗ref
+const mouseup = () => {
+  state.transform = dialogRef.value.dialogContentRef.$el.style.transform;
+};
+// 关闭弹窗
+const closeDialog = () => {
+	state.dialogVisible = false;
+	state.ruleForm = {};
+};
+// 取消
+const onCancel = () => {
+	closeDialog();
+};
+// 呼叫
+const onCall = () => {
+	// 呼叫外部电话
+	VoiceInterfaceObject.DialOut(state.ruleForm.fromPhone);
+};
+// 提交
+const onSubmit = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.validate((valid: boolean) => {
+    if (!valid) return;
+    state.loading = true;
+    setTimeout(() => {
+      state.loading = false;
+      state.dialogVisible = false;
+      emit('updateList');
+    }, 1000);
+  })
+};
+// 选中常用意见
+const chooseAdvice = (item: any) => {
+	state.ruleForm.handleResult += item.content;
+};
+defineExpose({
+	openDialog,
+	closeDialog,
+});
+</script>
+
+<style lang="scss" scoped>
+.collapse-box {
+	:deep(.el-collapse-item__header) {
+		background-color: var(--hotline-bg-main-color);
+		height: 40px;
+		border-radius: var(--el-border-radius-base);
+	}
+	:deep(.el-collapse-item__content) {
+		padding-bottom: 10px !important;
+		.el-form-item {
+			margin-bottom: 5px;
+			.el-form-item__content {
+				line-height: 24px;
+			}
+		}
+	}
+	.collapse-container {
+		padding: 10px;
+		.plug-container {
+			border: var(--el-border);
+			border-radius: var(--el-border-radius-base);
+			margin-bottom: 15px;
+			&:last-child {
+				margin-bottom: 0;
+			}
+			.plug-container-title {
+				padding: 10px 15px;
+				font-weight: bold;
+				border-bottom: var(--el-border);
+				font-size: var(--el-font-size-medium);
+			}
+		}
+	}
+}
+</style>
+<style lang="scss">
+.demo-tabs-form {
+	.title {
+		font-size: var(--el-font-size-medium);
+		padding: 10px 15px 20px 15px;
+	}
+	.el-form-item {
+		margin-bottom: 0 !important;
+	}
+}
+</style>

+ 0 - 367
src/views/business/followUp/component/Follow-up-phone.vue

@@ -1,367 +0,0 @@
-<template>
-  <el-dialog v-model="state.dialogVisible" draggable title="电话回访" ref="dialogRef" width="80%" append-to-body destroy-on-close>
-    <el-collapse v-model="state.collapseArr" class="collapse-box" v-loading="state.loading">
-      <!-- 工单信息 -->
-      <el-collapse-item name="1">
-        <template #title>
-          <p class="pl20">
-            <b class="font14">工单信息</b>
-          </p>
-        </template>
-        <div class="collapse-container pb1">
-          <!--  待回访进行操作 -->
-          <el-form label-width="100px" ref="ruleFormRef">
-            <el-row :gutter="35">
-              <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-                <el-form-item label="来电/来信人"> {{ state.ruleForm.channelText }} </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-                <el-form-item label="联系电话">
-                  {{ state.ruleForm.fromPhone }}
-                  <el-button link type="primary" class="ml5" title="呼叫" @click="onCall"><SvgIcon name="ele-Phone" size="16px" /></el-button>
-                  <!-- <el-popover :width="480" trigger="hover">
-                    <template #reference>
-                      <el-button link type="primary" class="ml5" title="播放录音"><SvgIcon name="ele-Headset" size="16px" /></el-button>
-                    </template>
-                    <AudioPlayer ref="AudioPlayerRef" :url="state.ruleForm.url" />
-                  </el-popover> -->
-                </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-                <el-form-item label="服务坐席"> {{ state.ruleForm.employeeName }}[{{ state.ruleForm.employeeStaffNo }}] </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item label="热点分类"> {{ state.ruleForm.hotspotSpliceName }} </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item label="工单标题"> {{ state.ruleForm.title }} </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item label="诉求详情"> {{ state.ruleForm.content }} </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item label="接办部门"> {{ state.ruleForm.content }} </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item label="办理结果"> {{ state.ruleForm.content }} </el-form-item>
-              </el-col>
-            </el-row>
-          </el-form>
-        </div>
-      </el-collapse-item>
-      <!-- 发布详情 -->
-      <el-collapse-item name="2">
-        <template #title>
-          <p class="pl20">
-            <b class="font14">回访记录</b>
-          </p>
-        </template>
-        <div class="collapse-container pb1">
-          <el-form label-width="100px" ref="ruleFormRef" :model="state.ruleForm"  label-position="left">
-            <el-row :gutter="35">
-              <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-                <el-form-item label="回访人">
-                  {{ state.ruleForm.title }}
-                </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-                <el-form-item label="回访状态">
-                  <span class="mr5">待回访</span>
-                  <el-switch
-                      v-model="state.ruleForm.switch"
-                      class="ml-2"
-                      inline-prompt
-                      active-text="已接通"
-                      inactive-text="未接通"
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-                <el-form-item label="回访方式">
-                  {{ state.ruleForm.title }}
-                </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-                <el-form-item label="回访时间">
-                  {{ state.ruleForm.title }}
-                </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item style="border-bottom: 1px solid var(--el-border-color);" class="mt10">
-                  <template #label>
-                    <p class="border-title mt10 mb10" > 坐席 </p>
-                  </template>
-                </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item label="坐席评价">
-                  <el-radio-group v-model="state.ruleForm.radio">
-                    <el-radio :label="item.value" v-for="(item) in seatRateArray" :key="item.value">{{item.label}}</el-radio>
-                  </el-radio-group>
-                </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item label="评价情况">
-                  <el-input type="textarea" :autosize="{ minRows: 6, maxRows: 10 }" maxlength="2000" placeholder="请填写评价情况" v-model="state.ruleForm.handleResult"></el-input>
-                </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item style="border-bottom: 1px solid var(--el-border-color);" class="mt10">
-                  <template #label>
-                    <p class="border-title mt10 mb10" > 接办部门 </p>
-                  </template>
-                </el-form-item>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" v-for="(item, index) in state.ruleForm.departmentList" :key="index">
-                <el-row :gutter="10">
-                  <el-col :span="4">
-                    {{ item.departmentName }}
-                  </el-col>
-                  <el-col :span="8">
-                    <el-form-item label="办理结果">
-                      <el-select v-model="item.radio">
-                        <el-option
-                            v-for="item in departmentRateArray"
-                            :key="item.value"
-                            :label="item.label"
-                            :value="item.value"
-                        />
-                      </el-select>
-                    </el-form-item>
-                  </el-col>
-                  <el-col :span="8">
-                    <el-form-item label="办件态度">
-                      <el-select v-model="item.radio1">
-                        <el-option
-                            v-for="item in departmentAtiAttitude"
-                            :key="item.value"
-                            :label="item.label"
-                            :value="item.value"
-                        />
-                      </el-select>
-                    </el-form-item>
-                  </el-col>
-                </el-row>
-              </el-col>
-              <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                <el-form-item label="评价情况">
-                  <el-input type="textarea" :autosize="{ minRows: 6, maxRows: 10 }" maxlength="2000" placeholder="请填写评价情况" v-model="state.ruleForm.handleResult"></el-input>
-                </el-form-item>
-              </el-col>
-            </el-row>
-          </el-form>
-        </div>
-      </el-collapse-item>
-    </el-collapse>
-
-    <template #footer>
-			<span class="dialog-footer">
-        <el-button @click="onCancel" class="default-button">取 消</el-button>
-				<el-button type="primary" @click="onSubmit" :loading="state.loading" v-auth="'business:order:release'">提交</el-button>
-			</span>
-    </template>
-  </el-dialog>
-</template>
-<script setup lang="ts" name="orderFollowUpPhone">
-import { reactive, ref } from 'vue';
-import {ElMessageBox} from 'element-plus';
-import { VoiceInterfaceObject } from '/@/utils/PhoneScript';
-
-// 定义子组件向父组件传值/事件
-const emit = defineEmits(['updateList']);
-// 定义变量内容
-const state = reactive<any>({
-  collapseArr:['1','2'], // 折叠面板
-  dialogVisible: false, // 是否显示弹窗
-  loading: false, // 是否显示加载
-  ruleForm: {// 表单数据
-    title:"标题内容",
-    content:"内容内容内容内容内容内容内容内容内容内容内容内容内容",
-    result:'办理结果内容',
-    handleResult:'办理结果内容',
-    radio1:'1',
-    departmentList:[
-      {
-        departmentName:'部门名称1',
-        radio:'1',
-      },
-      {
-        departmentName:'部门名称2',
-        radio:'1',
-      },
-      {
-        departmentName:'部门名称3',
-        radio:'1',
-      },
-    ]
-  },
-});
-const ruleFormRef = ref<RefType>();
-const seatRateArray = ref<EmptyArrayType>([
-  {
-    label: '非常满意',
-    value: '1',
-  },
-  {
-    label: '满意',
-    value: '2',
-  },
-  {
-    label: '一般',
-    value: '3',
-  },
-  {
-    label: '不满意',
-    value: '4',
-  },
-  {
-    label: '非常不满意',
-    value: '5',
-  },
-  {
-    label: '未评价',
-    value: '6',
-  }
-]);// 坐席评价列表
-const departmentRateArray = ref<EmptyArrayType>([
-  {
-    label: '非常满意',
-    value: '1',
-  },
-  {
-    label: '满意',
-    value: '2',
-  },
-  {
-    label: '基本满意',
-    value: '3',
-  },
-  {
-    label: '不满意',
-    value: '4',
-  },
-  {
-    label: '非常不满意',
-    value: '5',
-  },
-  {
-    label: '未评价',
-    value: '6',
-  }
-]);// 部门评价列表
-const departmentAtiAttitude = ref<EmptyArrayType>([
-  {
-    label: '非常满意',
-    value: '1',
-  },
-  {
-    label: '满意',
-    value: '2',
-  },
-  {
-    label: '基本满意',
-    value: '3',
-  },
-  {
-    label: '不满意',
-    value: '4',
-  },
-  {
-    label: '非常不满意',
-    value: '5',
-  },
-  {
-    label: '未评价',
-    value: '6',
-  }
-]);// 部门态度列表
-// 打开弹窗
-const openDialog = () => {
-  state.loading = false;
-  state.dialogVisible = true;
-};
-// 关闭弹窗
-const closeDialog = () => {
-  state.dialogVisible = false;
-  state.ruleForm = {};
-};
-// 取消
-const onCancel = () => {
-  closeDialog();
-};
-// 呼叫
-const onCall = ()=>{
-  // 呼叫外部电话
-  VoiceInterfaceObject.DialOut(state.ruleForm.fromPhone);
-}
-// 提交
-const onSubmit = () => {
-  ElMessageBox.confirm('您确定要提交吗?', '提示', {
-    confirmButtonText: '确定',
-    cancelButtonText: '取消',
-    type: 'warning',
-  })
-      .then(() => {
-        state.loading = true;
-        setTimeout(() => {
-          state.loading = false;
-          state.dialogVisible = false;
-          emit('updateList');
-        }, 1000);
-      })
-      .catch(() => {
-        // 取消
-      });
-};
-defineExpose({
-  openDialog,
-  closeDialog,
-});
-</script>
-
-<style lang="scss" scoped>
-.collapse-box {
-  :deep(.el-collapse-item__header) {
-    background-color: var(--hotline-bg-main-color);
-    height: 40px;
-    border-radius: var(--el-border-radius-base);
-  }
-  :deep(.el-collapse-item__content) {
-    padding-bottom: 10px !important;
-    .el-form-item {
-      margin-bottom: 5px;
-      .el-form-item__content {
-        line-height: 24px;
-      }
-    }
-  }
-  .collapse-container {
-    padding: 10px;
-    .plug-container {
-      border: var(--el-border);
-      border-radius: var(--el-border-radius-base);
-      margin-bottom: 15px;
-      &:last-child {
-        margin-bottom: 0;
-      }
-      .plug-container-title {
-        padding: 10px 15px;
-        font-weight: bold;
-        border-bottom: var(--el-border);
-        font-size: var(--el-font-size-medium);
-      }
-    }
-  }
-}
-</style>
-<style lang="scss">
-.demo-tabs-form {
-  .title {
-    font-size: var(--el-font-size-medium);
-    padding: 10px 15px 20px 15px;
-  }
-  .el-form-item {
-    margin-bottom: 0 !important;
-  }
-}
-</style>

+ 328 - 0
src/views/business/followUp/followedUp/index.vue

@@ -0,0 +1,328 @@
+<template>
+	<div class="business-followUp-followedUp-container layout-pd">
+		<!-- 搜索  -->
+		<el-card shadow="never">
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+				<el-row :gutter="10">
+					<el-col :span="8">
+						<el-form-item label="关键字" prop="Keyword">
+							<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="8">
+						<el-form-item label="回访状态" prop="AcceptType">
+							<el-select v-model="state.queryParams.AcceptType" placeholder="请选择回访状态" multiple clearable class="w100">
+								<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理时间" prop="crTime">
+								<el-date-picker
+									v-model="state.queryParams.crTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeCr"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="归档时间" prop="exTime">
+								<el-date-picker
+									v-model="state.queryParams.exTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeEx"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="回访时间" prop="exTime">
+								<el-date-picker
+									v-model="state.queryParams.exTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeEx"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="回访方式" prop="AcceptType">
+								<el-select v-model="state.queryParams.AcceptType" placeholder="请选择回访方式" multiple clearable class="w100">
+									<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<el-col :span="8">
+						<div class="flex-end w100">
+							<el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+							<el-button link type="primary" @click="closeSearch">
+								{{ searchCol ? '展开' : '收起' }}
+								<SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+							</el-button>
+						</div>
+					</el-col>
+				</el-row>
+			</el-form>
+		</el-card>
+		<el-card shadow="never">
+			<!-- 功能按钮 -->
+			<div class="mb20">
+				<el-button type="primary" @click="onTextMessageFollowUp" :disabled="!multipleSelection.length" v-auth="'business:followUp:textMessage'">
+					<SvgIcon name="ele-Message" class="mr5" />短信回访</el-button
+				>
+				<el-button type="primary" @click="multiplePeople" :disabled="!multipleSelection.length" v-auth="'business:followUp:multiplePeople'">
+					<SvgIcon name="ele-User" class="mr5" />批量分配</el-button
+				>
+				<el-button type="primary" @click="smartFollowUp" :disabled="!multipleSelection.length" v-auth="'business:followUp:smart'">
+					<SvgIcon name="iconfont icon-diannao1" class="mr5" />智能回访</el-button
+				>
+				<el-button type="primary" @click="onExport" :disabled="!multipleSelection.length" v-auth="'business:followUp:export'">
+					<SvgIcon name="iconfont icon-daochu" class="mr5" />导出</el-button
+				>
+			</div>
+			<!-- 表格 -->
+			<el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+				<el-table-column type="selection" width="55" />
+				<el-table-column prop="no" label="工单编码" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="中心会签" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="回访状态" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="回访方式" show-overflow-tooltip></el-table-column>
+				<el-table-column label="工单标题" show-overflow-tooltip width="400">
+					<template #default="{ row }">
+						<el-button link type="primary">{{ row.title }}</el-button>
+					</template>
+				</el-table-column>
+				<el-table-column prop="no" label="受理类型" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="热点分类" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="expiredTime" label="受理人" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ row.employeeName + '[' + row.employeeStaffNo + ']' }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="no" label="一级部门" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="接办部门" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="办结时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="发布时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="expiredTime" label="回访任务创建时间" show-overflow-tooltip width="170">
+					<template #default="{ row }">
+						<span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="no" label="回访人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="回访时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="no" label="语音评价" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="话务员满意度" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="被回访部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="部门办件结果" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="部门办件态度" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="不满意原因" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="是否可甄别" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="是否甄别" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="甄别结果" show-overflow-tooltip></el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+			<!-- 分页 -->
+			<pagination
+				:total="state.total"
+				v-model:page="state.queryParams.PageIndex"
+				v-model:limit="state.queryParams.PageSize"
+				@pagination="queryList"
+			/>
+		</el-card>
+	</div>
+</template>
+
+<script setup lang="ts" name="OrderFollowedUp">
+import {  onMounted, reactive, ref } from 'vue';
+import { ElButton, ElMessage, ElMessageBox, FormInstance } from 'element-plus';
+import { listBaseData } from '/@/api/business/order';
+import { auth } from '/@/utils/authFunction';
+import { throttle } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import { useRouter } from 'vue-router';
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+	queryParams: {
+		// 查询条件
+		PageIndex: 1,
+		PageSize: 10,
+		Keyword: '', // 关键字
+		Content: '', // 工单内容
+		AcceptType: '', // 受理类型
+		Channel: '', // 渠道
+		HotspotId: [], // 热点
+		OrgCode: [], // 机构
+		NameOrNo: '', // 受理坐席
+		crTime: [], // 创建时间
+		CreationTimeStart: '', // 创建时间 开始
+		CreationTimeEnd: '', // 创建时间 结束
+		TransferPhone: '', // 转派人
+		EmergencyLevel: [], // 紧急程度
+		exTime: [], // 办理期限
+		ExpiredTimeStart: '', //办理期限 开始
+		ExpiredTimeEnd: '', //办理期限 结束
+		PhoneNo: '', // 手机号
+		Status: [], // 状态
+		pushTypeOptions: '', //
+		PushTypeCode: '', //推送类型
+	},
+	tableList: [{}], //表单
+	loading: false, // 加载
+	total: 0, // 总数
+	acceptTypeOptions: [], //受理类型
+	channelOptions: [], // 来源频道
+	emergencyLevelOptions: [], // 紧急程度
+	orderStatusOptions: [], // 工单状态
+	orgsOptions: [], // 部门
+	pushTypeOptions: [], //推送分类
+	orgData: [], // 机构数据
+});
+// 展开/收起
+const closeSearch = () => {
+	searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+	if (val) {
+		state.queryParams[startKey] = val[0];
+		state.queryParams[endKey] = val[1];
+	} else {
+		state.queryParams[startKey] = '';
+		state.queryParams[endKey] = '';
+	}
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+	handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+	handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+	const res: any = await listBaseData();
+	state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+	state.channelOptions = res.result?.channelOptions ?? [];
+	state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+	state.orgsOptions = res.result?.orgsOptions ?? [];
+	state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+	state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+	if (!auth('business:followedUp:query')) ElMessage.error('抱歉,您没有权限查看已回访列表!');
+	else {
+	}
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	state.queryParams.CreationTimeStart = '';
+	state.queryParams.CreationTimeEnd = '';
+	state.queryParams.ExpiredTimeStart = '';
+	state.queryParams.ExpiredTimeStart = '';
+	queryList();
+}, 500);
+// 短信回访
+const onTextMessageFollowUp = () => {
+	ElMessageBox.confirm('您确定要短信回访吗?', '提示', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+		type: 'warning',
+	})
+		.then(() => {
+			state.loading = true;
+		})
+		.catch(() => {
+			// 取消
+		});
+};
+// 批量分配
+const multiplePeople = () => {
+	console.log('批量分配');
+};
+// 智能回访
+const smartFollowUp = () => {
+	console.log('智能回访');
+};
+// 表格多选
+const multipleTableRef = ref<RefType>();
+const multipleSelection = ref<any>([]);
+const handleSelectionChange = (val: any[]) => {
+	multipleSelection.value = val;
+};
+// 导出
+const onExport = () => {
+	console.log('导出');
+};
+onMounted(async () => {
+	await getBaseData();
+	queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-followUp-followedUp-container {
+	.arrow {
+		transition: transform var(--el-transition-duration);
+		cursor: pointer;
+	}
+	.arrow.is-reverse {
+		transform: rotateZ(-180deg);
+	}
+}
+</style>

+ 33 - 21
src/views/business/followUp/index.vue

@@ -111,8 +111,11 @@
 			<el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
 				<el-table-column type="selection" width="55" />
 				<el-table-column prop="no" label="工单编码" show-overflow-tooltip></el-table-column>
-				<el-table-column prop="no" label="回访状态" show-overflow-tooltip></el-table-column>
-				<el-table-column prop="no" label="回访方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="来源方式" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="省/市工单" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="no" label="中心会签" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="回访状态" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="回访方式" show-overflow-tooltip></el-table-column>
 				<el-table-column label="工单标题" show-overflow-tooltip width="400">
 					<template #default="{ row }">
 						<el-button link type="primary">{{ row.title }}</el-button>
@@ -148,11 +151,22 @@
 					</template>
 				</el-table-column>
 				<el-table-column prop="no" label="回访人" show-overflow-tooltip></el-table-column>
-				<el-table-column prop="no" label="是否接通" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="回访时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="回访标签" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+				<el-table-column prop="no" label="语音评价" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="话务员满意度" show-overflow-tooltip></el-table-column>
 				<el-table-column label="操作" width="150" fixed="right" align="center">
 					<template #default="{ row }">
-						<el-button link type="primary" @click="onOrderDetail(row)" title="查看工单详情" v-auth="'business:followUp:detail'"> 工单详情 </el-button>
-						<el-button link type="primary" @click="onManpower(row)" title="工单回访" v-auth="'business:followUp:manpower'"> 回访 </el-button>
+						<el-button link type="primary" @click="followUpDetail(row)" title="查看回访详情" v-auth="'business:followUp:detail'"> 回访详情 </el-button>
+						<el-button link type="primary" @click="editFollowUp(row)" title="修改回访" v-auth="'business:followUp:edit'"> 修改 </el-button>
 					</template>
 				</el-table-column>
 				<template #empty>
@@ -167,25 +181,23 @@
 				@pagination="queryList"
 			/>
 		</el-card>
-		<!-- 回访 -->
-		<follow-up-phone ref="followUpPhoneRef" @updateList="queryList" />
-		<!-- 工单详情 -->
-		<order-detail ref="OrderDetailRef" @updateList="queryList" />
+    <!-- 回访详情 -->
+    <FollowUpDetail ref="followUpDetailRef" @updateList="queryList" />
 	</div>
 </template>
 
 <script setup lang="ts" name="orderFollowUp">
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
-import { listBaseData } from '/@/api/business/order';
 import { ElButton, ElMessage, ElMessageBox, FormInstance } from 'element-plus';
+import { listBaseData } from '/@/api/business/order';
 import { auth } from '/@/utils/authFunction';
 import { throttle } from '/@/utils/tools';
 import { shortcuts } from '/@/utils/constants';
 import { formatDate } from '/@/utils/formatTime';
 import { useRouter } from 'vue-router';
+
 // 引入组件
-const FollowUpPhone = defineAsyncComponent(() => import('/@/views/business/followUp/component/Follow-up-phone.vue'));
-const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+const FollowUpDetail = defineAsyncComponent(() => import('/@/views/business/followUp/component/Follow-up-detail.vue'));   // 回访
 
 // 定义变量内容
 const ruleFormRef = ref<RefType>(); // 表单ref
@@ -216,7 +228,7 @@ const state = reactive(<any>{
 		pushTypeOptions: '', //
 		PushTypeCode: '', //推送类型
 	},
-	tableList: [], //表单
+	tableList: [{}], //表单
 	loading: false, // 加载
 	total: 0, // 总数
 	acceptTypeOptions: [], //受理类型
@@ -260,7 +272,7 @@ const getBaseData = async () => {
 };
 /** 获取列表 */
 const queryList = throttle(() => {
-	if (!auth('business:followUp:query')) ElMessage.error('抱歉,您没有权限查看工单回访列表!');
+	if (!auth('business:followUp:query')) ElMessage.error('抱歉,您没有权限查看回访列表!');
 	else {
 	}
 }, 500);
@@ -307,14 +319,14 @@ const handleSelectionChange = (val: any[]) => {
 const onExport = () => {
 	console.log('导出');
 };
-// 工单详情
-const OrderDetailRef = ref<RefType>();
-const onOrderDetail = (row: any) => {
-	OrderDetailRef.value.openDialog(row);
+// 回访详情
+const followUpDetailRef = ref<RefType>();
+const followUpDetail = (row: any) => {
+  followUpDetailRef.value.openDialog(row);
 };
-// 人工回访
-const onManpower = (row: any) => {
-	followUpPhoneRef.value.openDialog(row);
+// 修改回访
+const editFollowUp = (row: any) => {
+
 };
 onMounted(async () => {
 	await getBaseData();

+ 12 - 12
src/views/business/order/accept/orderAdd.vue

@@ -383,14 +383,14 @@
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 								<el-form-item label="诉求详情" prop="content" :rules="[{ required: true, message: '请填写诉求详情', trigger: 'blur' }]">
-									<Comment
-										@chooseComment="chooseComment"
-										v-model="state.ruleForm.content"
-										placeholder="请填写诉求详情"
-										:loading="state.formLoading"
-										:commonEnum="commonEnum.Seat"
-										modal
-									/>
+                  <common-advice
+                      @chooseAdvice="chooseAdvice"
+                      v-model="state.ruleForm.content"
+                      placeholder="请填写诉求详情"
+                      :loading="state.formLoading"
+                      :commonEnum="commonEnum.Seat"
+                      modal
+                  />
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
@@ -578,7 +578,7 @@ import mittBus from '/@/utils/mitt';
 const OrderProcess = defineAsyncComponent(() => import('/@/views/business/order/components/Order-process.vue'));  // 提交流程
 const OrderExpandForm = defineAsyncComponent(() => import('/@/views/business/order/components/Order-expand-form.vue')); // 拓展表单
 const OrderHistory = defineAsyncComponent(() => import('/@/views/business/order/components/Order-history.vue'));  // 历史工单
-const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Order-comment.vue')); // 常用意见
+const CommonAdvice = defineAsyncComponent(() => import('/@/components/CommonAdvice/index.vue')); // 常用意见
 const OrderSupply = defineAsyncComponent(() => import('/@/views/business/order/components/Order-supply.vue')); // 补充信息
 const AnnexList = defineAsyncComponent(() => import('/@/components/AnnexList/index.vue'));  // 附件列表
 // 定义变量内容
@@ -793,7 +793,7 @@ const save = throttle((formEl: FormInstance | undefined) => {
 				mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
 				mittBus.emit('clearCache', 'order');
 				router.push({
-					path: '/business/order',
+					path: '/business/order/index',
 				});
 			});
 		};
@@ -884,7 +884,7 @@ const handleSelectionChange = (row: any) => {
 	}
 };
 // 选中常用意见
-const chooseComment = (item: any) => {
+const chooseAdvice = (item: any) => {
 	state.ruleForm.content += item.content;
 };
 // 流程提交成功
@@ -893,7 +893,7 @@ const orderProcessSuccess = () => {
 	mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
 	mittBus.emit('clearCache', 'order');
 	router.push({
-		path: '/business/order',
+		path: '/business/order/index',
 	});
 };
 /** 搜索按钮操作 */

+ 11 - 11
src/views/business/order/accept/orderEdit.vue

@@ -381,14 +381,14 @@
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 								<el-form-item label="诉求详情" prop="content" :rules="[{ required: true, message: '请填写诉求详情', trigger: 'blur' }]">
-									<Comment
-										@chooseComment="chooseComment"
-										v-model="state.ruleForm.content"
-										placeholder="请填写诉求详情"
-										:loading="state.formLoading"
-										:commonEnum="commonEnum.Seat"
-										modal
-									/>
+                  <common-advice
+                      @chooseAdvice="chooseAdvice"
+                      v-model="state.ruleForm.content"
+                      placeholder="请填写诉求详情"
+                      :loading="state.formLoading"
+                      :commonEnum="commonEnum.Seat"
+                      modal
+                  />
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
@@ -575,7 +575,7 @@ import mittBus from '/@/utils/mitt';
 const OrderProcess = defineAsyncComponent(() => import('/@/views/business/order/components/Order-process.vue'));  // 提交流程
 const OrderExpandForm = defineAsyncComponent(() => import('/@/views/business/order/components/Order-expand-form.vue')); // 拓展表单
 const OrderHistory = defineAsyncComponent(() => import('/@/views/business/order/components/Order-history.vue'));  // 历史工单
-const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Order-comment.vue')); // 常用意见
+const CommonAdvice = defineAsyncComponent(() => import('/@/components/CommonAdvice/index.vue')); // 常用意见
 const OrderSupply = defineAsyncComponent(() => import('/@/views/business/order/components/Order-supply.vue'));  // 补充信息
 const AnnexList = defineAsyncComponent(() => import('/@/components/AnnexList/index.vue'));  // 附件列表
 // 定义变量内容
@@ -880,7 +880,7 @@ const searchKnowledge = (value?: string) => {
 	state.historyOrderLoading = false;
 };
 // 选中常用意见
-const chooseComment = (item: any) => {
+const chooseAdvice = (item: any) => {
 	state.ruleForm.content += item.content;
 };
 // 流程提交成功
@@ -889,7 +889,7 @@ const orderProcessSuccess = () => {
 	mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
 	mittBus.emit('clearCache', 'order');
 	router.push({
-		path: '/business/order',
+		path: '/business/order/index',
 	});
 };
 /** 搜索按钮操作 */

+ 28 - 11
src/views/business/backlog/index.vue → src/views/business/order/backlog/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="business-backlog-container layout-pd">
+  <div class="business-order-backlog-container layout-pd">
     <!-- 搜索  -->
     <el-card shadow="never">
       <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
@@ -112,13 +112,16 @@
     <el-card shadow="never">
       <!-- 功能按钮 -->
       <div class="mb20">
-          <el-button type="primary" @click="onAddWorkOrder" v-auth="'business:backlog:add'">
-            <SvgIcon name="ele-Plus" class="mr5" />新建工单
-          </el-button>
-          <el-button type="primary" @click="onExport" v-auth="'business:backlog:export'" :disabled="!multipleSelection.length">
-            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
-          </el-button>
+        <el-button type="primary" @click="onAddWorkOrder" v-auth="'business:order:backlog:add'">
+          <SvgIcon name="ele-Plus" class="mr5" />新建工单
+        </el-button>
+        <el-button type="primary" @click="onExport" v-auth="'business:order:backlog:export'" :disabled="!multipleSelection.length">
+          <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+        </el-button>
       </div>
+      <el-tabs v-model="state.queryParams.status" class="demo-tabs" @tab-change="handleClick">
+        <el-tab-pane :name="item.value" v-for="item in state.tabPaneList" :key="item.value" :label="item.label"></el-tab-pane>
+      </el-tabs>
       <!-- 表格 -->
       <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
         <el-table-column type="selection" width="55" />
@@ -161,7 +164,7 @@
         </el-table-column>
         <el-table-column label="操作" width="150" fixed="right" align="center">
           <template #default="{ row }">
-            <el-button link type="primary" @click="onOrderDetail(row)" title="查看工单详情" v-auth="'business:backlog:detail'"> 详情 </el-button>
+            <el-button link type="primary" @click="onOrderDetail(row)" title="查看工单详情" v-auth="'business:order:backlog:detail'"> 详情 </el-button>
           </template>
         </el-table-column>
         <template #empty>
@@ -217,6 +220,7 @@ const state = reactive(<any>{
     Status: [], // 状态
     pushTypeOptions: '', //
     PushTypeCode: '', //推送类型
+    status: '0', //工单状态
   },
   tableList: [], //表单
   loading: false, // 加载
@@ -228,6 +232,16 @@ const state = reactive(<any>{
   orgsOptions: [], // 部门
   pushTypeOptions: [], //推送分类
   orgData: [], // 机构数据
+  tabPaneList: [
+    {
+      label:'待办未办',
+      value:'0',
+    },
+    {
+      label:'待办已办',
+      value:'1',
+    },
+  ], // tab列表
 });
 const ruleFormRef = ref<RefType>(); // 表单ref
 const searchCol = ref(true); // 展开/收起
@@ -278,11 +292,14 @@ const getBaseData = async () => {
 };
 /** 获取列表 */
 const queryList = throttle(() => {
-  if (!auth('business:backlog:query')) ElMessage.error('抱歉,您没有权限查看工单待办!');
+  if (!auth('business:order:backlog:query')) ElMessage.error('抱歉,您没有权限查看工单待办!');
   else {
   }
 }, 500);
-
+// 切换tab 查询列表
+const handleClick = () => {
+  queryList();
+};
 /** 重置按钮操作 */
 const resetQuery = throttle((formEl: FormInstance | undefined) => {
   if (!formEl) return;
@@ -320,7 +337,7 @@ onMounted(async () => {
 </script>
 
 <style scoped lang="scss">
-.business-backlog-container {
+.business-order-backlog-container {
   .arrow {
     transition: transform var(--el-transition-duration);
     cursor: pointer;

+ 0 - 300
src/views/business/order/components/Order-comment.vue

@@ -1,300 +0,0 @@
-<template>
-	<div class="textarea w100">
-		<el-input v-model="value" type="textarea" :autosize="{ minRows: 10, maxRows: 20 }" :placeholder="placeholder" maxlength="2000"> </el-input>
-		<span class="buttons">
-			<el-button @click="showComments" class="default-button" :loading="loading">常用意见</el-button>
-			<el-button type="primary" @click="onAddComments" :loading="loading">添加到常用意见</el-button>
-		</span>
-
-		<el-drawer v-model="state.showDrawer" size="35%" title="" :show-close="false" :modal="modal">
-			<template #header="{ close }">
-				<div class="comments-header">
-					<div>
-						<el-button link @click="state.active = 'default'" :class="{ active: state.active === 'default' }"> 常用意见 </el-button>
-						<el-button link @click="state.active = 'add'" :class="{ active: state.active === 'add' }"> 新增意见 </el-button>
-						<span></span>
-					</div>
-				</div>
-				<div class="flex-center-align">
-					<el-button link @click="state.manage = true" v-if="!state.manage && state.active === 'default' && state.commentsList.length"
-						>管理</el-button
-					>
-					<el-button link @click="state.manage = false" type="primary" v-if="state.manage && state.active === 'default'">返回</el-button>
-					<el-button link @click="close">
-						<SvgIcon name="ele-Close" class="mr5" @click="close" size="16px" />
-					</el-button>
-				</div>
-			</template>
-			<div class="comments-container" v-loading="state.loading">
-				<template v-if="state.commentsList.length">
-					<!-- 默认状态 -->
-					<template v-if="state.active === 'default' && !state.manage">
-						<ul class="comments-box">
-							<li class="comments-item" v-for="(item, index) in state.commentsList" :key="index" @click="chooseComment(item)">
-								<p class="text-ellipsis2" :title="item.content">{{ item.content }}</p>
-							</li>
-						</ul>
-					</template>
-					<!-- 管理 -->
-					<template v-if="state.active === 'default' && state.manage">
-						<ul class="comments-box">
-							<li
-								class="comments-item"
-								v-for="(item, index) in state.commentsList"
-								:class="[item.ischeck === true ? 'chose' : '']"
-								:key="index"
-								@click="handelComment(item, <number>index)"
-							>
-								<p class="text-ellipsis2" :title="item.content">{{ item.content }}</p>
-								<el-checkbox v-model="item.ischeck" class="check-icon" label="" v-if="item.ischeck" size="large" />
-							</li>
-						</ul>
-					</template>
-				</template>
-				<template v-if="!state.commentsList.length && state.active !== 'add'">
-					<Empty description="暂无常用语" />
-				</template>
-				<!-- 新增意见 -->
-				<template v-if="state.active === 'add'">
-					<div>
-						<el-form :model="state.commentsForm" ref="commentsFormRef">
-							<el-form-item label="" prop="content" :rules="[{ required: true, message: '请填写新增常用意见', trigger: 'blur' }]">
-								<el-input
-									v-model="state.commentsForm.content"
-									type="textarea"
-									:autosize="{ minRows: 10, maxRows: 10 }"
-									placeholder="请填写新增常用意见"
-									clearable
-								>
-								</el-input>
-							</el-form-item>
-						</el-form>
-					</div>
-				</template>
-			</div>
-			<template #footer v-if="state.active === 'add' || state.manage">
-				<div style="flex: auto">
-					<el-button @click="deleteComment" class="default-button" :disabled="!state.chooseCommentList.length" v-if="state.active === 'default' && state.manage">删 除</el-button>
-					<el-button type="primary" @click="commentSave(commentsFormRef)" v-if="state.active === 'add'">保 存</el-button>
-				</div>
-			</template>
-		</el-drawer>
-	</div>
-</template>
-
-<script setup lang="ts" name="commentManage">
-import { reactive, ref, computed } from 'vue';
-import {ElMessage, ElMessageBox, FormInstance} from 'element-plus';
-import { commonList, addCommon, deleteCommon } from '/@/api/business/commonP';
-import { commonEnum } from '/@/utils/constants';
-const emit = defineEmits(['chooseComment', 'update:modelValue']);
-const props = defineProps({
-	modal: {
-		type: Boolean,
-		default: false,
-	},
-	modelValue: {
-		type: String,
-		default: '',
-	},
-	placeholder: {
-		type: String,
-		default: '请填写内容',
-	},
-	loading: {
-		type: Boolean,
-		default: false,
-	},
-	commonEnum: {
-		type: String,
-		default: commonEnum.Seat,
-	},
-});
-const value = computed({
-	get() {
-		return props.modelValue;
-	},
-	set(value) {
-		emit('update:modelValue', value);
-	},
-});
-// 定义变量内容
-const state = reactive<any>({
-	showDrawer: false,  // 是否显示弹窗
-	commentsList: [], // 常用意见列表
-	commentsForm: { // 新增常用意见
-		content: '',
-	},
-	chooseCommentList: [],  // 选中的常用意见
-	active: 'default',  // 当前状态
-	manage: false,  // 是否是管理状态
-	loading: false, // 是否显示loading
-	typecode: '', // 类型
-});
-
-// 打开常用意见管理
-const showComments = () => {
-	openDialog();
-};
-// 添加到常用意见
-const onAddComments = async () => {
-	if (!props.modelValue) {
-		ElMessage.warning(props.placeholder);
-		return;
-	}
-	await addCommon({
-		typeCode: props.commonEnum,
-		content: props.modelValue,
-	});
-	ElMessage.success('操作成功');
-	closeDialog();
-};
-// 打开弹窗
-const commentsFormRef = ref<RefType>();
-const openDialog = async () => {
-	state.typecode = props.commonEnum;
-	state.active = 'default';
-	commentsFormRef.value?.resetFields();
-	state.manage = false;
-	await getList();
-	state.showDrawer = true;
-};
-const getList = async () => {
-	try {
-		state.loading = true;
-		const res: any = await commonList({ typecode: props.commonEnum });
-		state.commentsList = res.result;
-		state.loading = false;
-	} catch (error) {
-		state.loading = false;
-	}
-};
-// 选中常用意见(管理)
-const handelComment= (item: any, index: number) => {
-	const repeatData = [...state.commentsList];
-	const repeatSolar = [...state.chooseCommentList];
-	if (!repeatData[index].ischeck) {
-		repeatData[index].ischeck = true;
-    repeatSolar.push(item);
-	} else {
-		repeatData[index].ischeck = false;
-		if (!repeatSolar || repeatSolar.length == 0) {
-			return '';
-		}
-    repeatSolar.splice(index, 1);
-	}
-	state.chooseCommentList = repeatSolar.filter((item: any) => item.ischeck);
-};
-// 重置状态
-const resetState = () => {
-	state.active = 'default';
-	state.manage = false;
-	state.chooseCommentList = [];
-	state.commentsForm.content = '';
-	getList();
-};
-// 删除常用意见
-const deleteComment = () => {
-	if (!state.chooseCommentList.length) {
-		ElMessage.warning('请选择要删除的常用意见');
-		return;
-	}
-	ElMessageBox.confirm(`确定要删除选中的常用意见,是否继续?`, '提示', {
-		confirmButtonText: '确认',
-		cancelButtonText: '取消',
-		draggable: true,
-		cancelButtonClass: 'default-button',
-		type: 'warning',
-	})
-		.then(() => {
-			const chooseCommentList = state.chooseCommentList.map((item: any) => {
-				return item.id;
-			});
-			deleteCommon({ ids: chooseCommentList }).then(() => {
-				ElMessage.success('操作成功');
-				resetState();
-				state.loading = false;
-			});
-		})
-		.catch(() => {});
-};
-// 添加常用意见 保存
-const commentSave = (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  formEl.validate((valid: boolean) => {
-    if (!valid) return;
-    state.loading = true;
-    addCommon({
-      typeCode: state.typecode,
-      content: state.commentsForm.content,
-    }).then(() => {
-      ElMessage.success('操作成功');
-      resetState();
-      state.loading = false;
-    });
-  })
-};
-// 选择常用意见 填入填写框
-const chooseComment = (item: any) => {
-	emit('chooseComment', item);
-	closeDialog();
-};
-// 关闭弹窗
-const closeDialog = () => {
-	state.showDrawer = false;
-};
-// 暴露变量
-defineExpose({
-	openDialog,
-	closeDialog,
-});
-</script>
-<style lang="scss" scoped>
-.textarea {
-	position: relative;
-	.buttons {
-		position: absolute;
-		right: 10px;
-		bottom: 10px;
-	}
-	:deep(.el-textarea__inner) {
-		padding-bottom: 40px;
-	}
-}
-.comments-container {
-	.comments-box {
-		.comments-item {
-			border: var(--el-border);
-			border-radius: var(--el-border-radius-base);
-			margin-bottom: 10px;
-			padding: 8px 15px;
-			cursor: pointer;
-			position: relative;
-			line-height: 18px;
-			&:hover {
-				box-shadow: 0 0 0 1px var(--el-color-primary) inset;
-				background-color: var(--hotline-bg-main-color);
-			}
-			.check-icon {
-				position: absolute;
-				right: 0;
-				top: -13px;
-			}
-		}
-		.chose {
-			box-shadow: 0 0 0 1px var(--el-color-primary) inset;
-		}
-	}
-}
-.comments-header {
-	.active {
-		color: var(--el-color-primary);
-		font-size: var(--el-font-size-medium);
-	}
-}
-:deep(.el-drawer__footer) {
-	box-shadow: 0px -4px 10px 0px rgb(0 0 0 / 10%);
-	border-radius: 0 0 8px 0;
-	padding: 10px 20px;
-}
-</style>

+ 9 - 9
src/views/business/order/components/Order-process.vue

@@ -72,13 +72,13 @@
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 						<el-form-item :label="state.title + '意见'" prop="opinion" :rules="[{ required: true, message: '请填写常用意见', trigger: 'blur' }]">
-							<Comment
-								@chooseComment="chooseComment"
-								v-model="state.ruleForm.opinion"
-								placeholder="请填写常用意见"
-								:loading="state.loading"
-								:commonEnum="state.commonEnum"
-							/>
+              <common-advice
+                  @chooseAdvice="chooseAdvice"
+                  v-model="state.ruleForm.opinion"
+                  placeholder="请填写常用意见"
+                  :loading="state.loading"
+                  :commonEnum="state.commonEnum"
+              />
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
@@ -106,7 +106,7 @@ import { OrderFlowParams, orderStartFlow } from '/@/api/business/order';
 import { workflowNextSteps, workflowNext, workflowRecall, workflowPrevious, workflowRecallParams, workflowStepOptions } from '/@/api/system/workflow';
 
 // 引入组件
-const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Order-comment.vue')); // 常用意见
+const CommonAdvice = defineAsyncComponent(() => import('/@/components/CommonAdvice/index.vue')); // 常用意见
 const AnnexList = defineAsyncComponent(() => import('/@/components/AnnexList/index.vue'));  // 附件列表
 // 定义子组件向父组件传值/事件
 const emit = defineEmits(['orderProcessSuccess', 'orderProcessFailed']);
@@ -254,7 +254,7 @@ const onCancel = () => {
 	closeDialog();
 };
 // 选择常用意见 填入填写框
-const chooseComment = (item: any) => {
+const chooseAdvice = (item: any) => {
 	state.ruleForm.opinion += item.content;
 };
 // 提交

+ 319 - 0
src/views/business/overdue/index.vue

@@ -0,0 +1,319 @@
+<template>
+  <div class="business-overdue-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:overdue:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="当前节点" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="工单期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="办结时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="一级部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单超期部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="中心会签" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="hotspotName" label="受理人" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" width="160" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" @click="onDetail(row)" title="查看工单详情" v-auth="'business:order:overdue:detail'"> 工单详情 </el-button>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="orderOverdue">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:order:overdue:query')) ElMessage.error('抱歉,您没有权限查看工单超期列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+// 查看工单详情
+const OrderDetailRef = ref<RefType>(); // 工单详情ref
+const onDetail = (row: any) => {
+  OrderDetailRef.value.openDialog()
+};
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-overdue-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

+ 323 - 0
src/views/business/overdue/node/index.vue

@@ -0,0 +1,323 @@
+<template>
+  <div class="business-nodeOverdue-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:node:overdue:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="当前节点" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="节点期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="工单期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="节点办理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="节点办理部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="节点办理人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="中心会签" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理人" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" width="160" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" @click="onDetail(row)" title="查看工单详情" v-auth="'business:node:overdue:detail'"> 工单详情 </el-button>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="nodeOverdue">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:node:overdue:query')) ElMessage.error('抱歉,您没有权限查看节点超期列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+// 查看工单详情
+const OrderDetailRef = ref<RefType>(); // 工单详情ref
+const onDetail = (row: any) => {
+  OrderDetailRef.value.openDialog()
+};
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-nodeOverdue-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

+ 319 - 0
src/views/business/overdueSoon/index.vue

@@ -0,0 +1,319 @@
+<template>
+  <div class="business-overdueSoon-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:overdueSoon:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单超期间隔" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="当前节点" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="工单期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="中心会签" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="一级部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="hotspotName" label="受理人" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" width="160" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" @click="onDetail(row)" title="查看工单详情" v-auth="'business:order:overdueSoon:detail'"> 工单详情 </el-button>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="orderOverdueSoon">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:order:overdueSoon:query')) ElMessage.error('抱歉,您没有权限查看工单即将超期列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+// 查看工单详情
+const OrderDetailRef = ref<RefType>(); // 工单详情ref
+const onDetail = (row: any) => {
+  OrderDetailRef.value.openDialog()
+};
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-overdueSoon-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

+ 329 - 0
src/views/business/overdueSoon/node/index.vue

@@ -0,0 +1,329 @@
+<template>
+  <div class="business-nodeOverdueSoon-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:node:overdueSoon:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单超期间隔" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="当前节点" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="节点期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="工单期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="交办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="接办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="hotspotName" label="一级部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="中心会签" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理人" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" width="160" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" @click="onDetail(row)" title="查看工单详情" v-auth="'business:node:overdueSoon:detail'"> 工单详情 </el-button>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="nodeOverdueSoon">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:node:overdueSoon:query')) ElMessage.error('抱歉,您没有权限查看工单会签列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+// 查看工单详情
+const OrderDetailRef = ref<RefType>(); // 工单详情ref
+const onDetail = (row: any) => {
+  OrderDetailRef.value.openDialog()
+};
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-nodeOverdueSoon-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

+ 334 - 0
src/views/business/redo/index.vue

@@ -0,0 +1,334 @@
+<template>
+  <div class="business-redo-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:supervise:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="重办类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="当前节点" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="接办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="要求重办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="要求重办人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="重办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="重办人" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="重办人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="重办意见" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="重办原因内容" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" width="150" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" @click="onDetail(row)" title="查看工单详情" v-auth="'business:redo:detail'"> 工单详情 </el-button>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+    <!-- 督办内容 -->
+    <order-supervise ref="OrderSuperviseRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="orderRedo">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+const OrderSupervise = defineAsyncComponent(() => import('/@/views/business/supervise/components/Order-supervise.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:redo:query')) ElMessage.error('抱歉,您没有权限查看工单重办列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+// 查看工单详情
+const OrderDetailRef = ref<RefType>(); // 工单详情ref
+const onDetail = (row: any) => {
+  OrderDetailRef.value.openDialog()
+};
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-redo-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

+ 2 - 3
src/views/business/release/index.vue

@@ -160,7 +160,7 @@
 						<el-button link type="primary" @click="release(row)" title="发布工单" v-auth="'business:release:release'"> 发布 </el-button>
 						<el-button link type="danger" @click="cancelRelease(row)" title="取消发布" v-auth="'business:release:cancel'"> 取消发布 </el-button>
 						<el-button link type="success" @click="releaseContent(row)" title="发布内容" v-auth="'business:release:content'"> 发布内容 </el-button>
-						<el-button link type="danger" @click="orderRedo(row)" title="重办工单" v-auth="'business:release:reDo'"> 重办 </el-button>
+						<el-button link type="danger" @click="OnOrderRedo(row)" title="重办工单" v-auth="'business:release:reDo'"> 重办 </el-button>
 						<el-button link type="primary" @click="releaseDetail(row)" title="发布详情" v-auth="'business:release:detail'"> 发布详情 </el-button>
 					</template>
 				</el-table-column>
@@ -190,7 +190,6 @@ import { auth } from '/@/utils/authFunction';
 import { throttle } from '/@/utils/tools';
 import { shortcuts } from '/@/utils/constants';
 import { formatDate } from '/@/utils/formatTime';
-import OrderReDo from "/@/views/business/release/component/Order-reDo.vue";
 // 引入组件
 const OrderRelease = defineAsyncComponent(() => import('/@/views/business/release/component/Order-release.vue'));
 const OrderReDo = defineAsyncComponent(() => import('/@/views/business/release/component/Order-reDo.vue'));
@@ -319,7 +318,7 @@ const releaseContent = (row: any) => {
 };
 // 工单重办
 const orderRedoRef = ref<RefType>();  // 工单重办ref
-const orderRedo = (row: any) => {
+const OnOrderRedo = (row: any) => {
   console.log('重办');
   orderRedoRef.value.openDialog();
 };

+ 335 - 0
src/views/business/return/backlog/index.vue

@@ -0,0 +1,335 @@
+<template>
+	<div class="business-return-backlog-container layout-pd">
+		<!-- 搜索  -->
+		<el-card shadow="never">
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+				<el-row :gutter="10">
+					<el-col :span="8">
+						<el-form-item label="发布状态" prop="AcceptType">
+							<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+								<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="8">
+						<el-form-item label="工单标题" prop="Keyword">
+							<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+						</el-form-item>
+					</el-col>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布人" prop="Content">
+								<el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布范围" prop="AcceptType">
+								<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+									<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理类型" prop="Channel">
+								<el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+									<el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="热点分类" prop="HotspotId">
+								<el-tree-select
+									class="w100"
+									v-model="state.queryParams.HotspotId"
+									filterable
+									clearable
+									multiple
+									:render-after-expand="false"
+									show-checkbox
+									placeholder="请选择热点分类"
+									:props="HotspotProps"
+									lazy
+									:load="load"
+									node-key="id"
+									check-strictly
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理时间" prop="crTime">
+								<el-date-picker
+									v-model="state.queryParams.crTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeCr"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="归档时间" prop="exTime">
+								<el-date-picker
+									v-model="state.queryParams.exTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeEx"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<el-col :span="8">
+						<div class="flex-end w100">
+							<el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+							<el-button link type="primary" @click="closeSearch">
+								{{ searchCol ? '展开' : '收起' }}
+								<SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+							</el-button>
+						</div>
+					</el-col>
+				</el-row>
+			</el-form>
+		</el-card>
+		<el-card shadow="never">
+			<!-- 功能按钮 -->
+      <el-tabs v-model="state.queryParams.status" class="demo-tabs" @tab-change="handleClick">
+        <el-tab-pane :name="item.value" v-for="item in state.tabPaneList" :key="item.value" :label="item.label"></el-tab-pane>
+      </el-tabs>
+			<!-- 表格 -->
+			<el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="退回状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="employeeName" label="受理人" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ row.employeeName + '[' + row.employeeStaffNo + ']' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="一级部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="交办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="退回申请时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="退回申请部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="退回申请人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="退回申请理由" show-overflow-tooltip></el-table-column>
+				<el-table-column label="操作" width="100" fixed="right" align="center">
+					<template #default="{ row }">
+						<el-button link type="primary" @click="approve(row)" title="退回审批" v-auth="'business:return:backlog:approve'"> 退回审批 </el-button>
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+			<!-- 分页 -->
+			<pagination
+				:total="state.total"
+				v-model:page="state.queryParams.PageIndex"
+				v-model:limit="state.queryParams.PageSize"
+				@pagination="queryList"
+			/>
+		</el-card>
+	</div>
+</template>
+<script setup lang="ts" name="orderReturnBacklog">
+import { onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import { ElButton, ElMessage, FormInstance } from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import { useRouter } from 'vue-router';
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+	queryParams: {
+		// 查询条件
+		PageIndex: 1,
+		PageSize: 10,
+		Keyword: '', // 关键字
+		Content: '', // 工单内容
+		AcceptType: '', // 受理类型
+		Channel: '', // 渠道
+		HotspotId: [], // 热点
+		OrgCode: [], // 机构
+		NameOrNo: '', // 受理坐席
+		crTime: [], // 创建时间
+		CreationTimeStart: '', // 创建时间 开始
+		CreationTimeEnd: '', // 创建时间 结束
+		TransferPhone: '', // 转派人
+		EmergencyLevel: [], // 紧急程度
+		exTime: [], // 办理期限
+		ExpiredTimeStart: '', //办理期限 开始
+		ExpiredTimeEnd: '', //办理期限 结束
+		PhoneNo: '', // 手机号
+		Status: [], // 状态
+		pushTypeOptions: '', //
+		PushTypeCode: '', //推送类型
+    status:'0'
+	},
+	tableList: [{}], //表单
+	loading: false, // 加载
+	total: 0, // 总数
+	acceptTypeOptions: [], //受理类型
+	channelOptions: [], // 来源频道
+	emergencyLevelOptions: [], // 紧急程度
+	orderStatusOptions: [], // 工单状态
+	orgsOptions: [], // 部门
+	pushTypeOptions: [], //推送分类
+	orgData: [], // 机构数据
+  tabPaneList: [
+    {
+      label:'甄别待办',
+      value:'0',
+    },
+    {
+      label:'甄别已办',
+      value:'1',
+    },
+  ], // tab列表
+});
+// 热点分类远程搜索
+const HotspotProps = {
+	label: 'hotSpotName',
+	children: 'children',
+	isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+	if (node.isLeaf) return resolve([]);
+	let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+	resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+	searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+	if (val) {
+		state.queryParams[startKey] = val[0];
+		state.queryParams[endKey] = val[1];
+	} else {
+		state.queryParams[startKey] = '';
+		state.queryParams[endKey] = '';
+	}
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+	handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+	handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+	const res: any = await listBaseData();
+	state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+	state.channelOptions = res.result?.channelOptions ?? [];
+	state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+	state.orgsOptions = res.result?.orgsOptions ?? [];
+	state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+	state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+	if (!auth('business:return:backlog:query')) ElMessage.error('抱歉,您没有权限查看退回待办!');
+	else {
+	}
+}, 500);
+// 切换tab 查询列表
+const handleClick = () => {
+  queryList();
+};
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	state.queryParams.CreationTimeStart = '';
+	state.queryParams.CreationTimeEnd = '';
+	state.queryParams.ExpiredTimeStart = '';
+	state.queryParams.ExpiredTimeStart = '';
+	queryList();
+}, 500);
+// 新增工单
+const onAddWorkOrder = () => {
+	// 跳转到录入工单页面
+	router.push('/business/order/accept');
+};
+// 表格多选
+const multipleTableRef = ref<RefType>();
+const multipleSelection = ref<any>([]);
+const handleSelectionChange = (val: any[]) => {
+	multipleSelection.value = val;
+};
+// 导出
+const onExport = () => {
+	console.log('导出');
+};
+// 甄别审批
+const approve = (row: any) => {
+	console.log('甄别审批');
+};
+onMounted(async () => {
+	await getBaseData();
+	queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-return-backlog-container {
+	.arrow {
+		transition: transform var(--el-transition-duration);
+		cursor: pointer;
+	}
+	.arrow.is-reverse {
+		transform: rotateZ(-180deg);
+	}
+}
+</style>

+ 334 - 0
src/views/business/return/index.vue

@@ -0,0 +1,334 @@
+<template>
+  <div class="business-return-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:supervise:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="退回状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="employeeName" label="受理人" show-overflow-tooltip width="170">
+          <template #default="{row}">
+            <span>{{ row.employeeName + '[' + row.employeeStaffNo + ']' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+
+        <el-table-column prop="acceptTypeText" label="一级部门" show-overflow-tooltip></el-table-column>
+
+        <el-table-column prop="expiredTime" label="交办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="退回申请时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="退回申请部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="退回申请人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="退回申请理由" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="审批时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="审批人" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" width="160" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" @click="onDetail(row)" title="查看工单详情" v-auth="'business:return:detail'"> 工单详情 </el-button>
+            <el-button link type="primary" @click="approve(row)" title="退回审批" v-auth="'business:return:backlog:approve'"> 退回审批 </el-button>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="orderReturn">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:return:query')) ElMessage.error('抱歉,您没有权限查看退回列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+// 查看督办详情
+const OrderDetailRef = ref<RefType>();
+const onDetail = (row: any) => {
+  OrderDetailRef.value.openDialog()
+};
+// 退回审批
+const approve = ()=>{
+
+}
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-return-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

+ 323 - 0
src/views/business/revocation/index.vue

@@ -0,0 +1,323 @@
+<template>
+  <div class="business-revocation-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:revocation:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="当前节点" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="接办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="撤销部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="撤销人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="撤销时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="撤销原因" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" width="80" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" @click="onDetail(row)" title="查看工单详情" v-auth="'business:revocation:detail'"> 工单详情 </el-button>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="orderRevocation">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:revocation:query')) ElMessage.error('抱歉,您没有权限查看工单重办列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+// 查看工单详情
+const OrderDetailRef = ref<RefType>(); // 工单详情ref
+const onDetail = (row: any) => {
+  OrderDetailRef.value.openDialog()
+};
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-revocation-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

+ 346 - 0
src/views/business/supervise/backlog/index.vue

@@ -0,0 +1,346 @@
+<template>
+	<div class="business-supervise-backlog-container layout-pd">
+		<!-- 搜索  -->
+		<el-card shadow="never">
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+				<el-row :gutter="10">
+					<el-col :span="8">
+						<el-form-item label="发布状态" prop="AcceptType">
+							<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+								<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="8">
+						<el-form-item label="工单标题" prop="Keyword">
+							<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+						</el-form-item>
+					</el-col>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布人" prop="Content">
+								<el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="发布范围" prop="AcceptType">
+								<el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+									<el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理类型" prop="Channel">
+								<el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+									<el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="热点分类" prop="HotspotId">
+								<el-tree-select
+									class="w100"
+									v-model="state.queryParams.HotspotId"
+									filterable
+									clearable
+									multiple
+									:render-after-expand="false"
+									show-checkbox
+									placeholder="请选择热点分类"
+									:props="HotspotProps"
+									lazy
+									:load="load"
+									node-key="id"
+									check-strictly
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="受理时间" prop="crTime">
+								<el-date-picker
+									v-model="state.queryParams.crTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeCr"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :span="8" v-show="!searchCol">
+							<el-form-item label="归档时间" prop="exTime">
+								<el-date-picker
+									v-model="state.queryParams.exTime"
+									type="datetimerange"
+									unlink-panels
+									range-separator="至"
+									start-placeholder="开始时间"
+									end-placeholder="结束时间"
+									:shortcuts="shortcuts"
+									@change="timeStartChangeEx"
+									value-format="YYYY-MM-DD[T]HH:mm:ss"
+								/>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<el-col :span="8">
+						<div class="flex-end w100">
+							<el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+							<el-button link type="primary" @click="closeSearch">
+								{{ searchCol ? '展开' : '收起' }}
+								<SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+							</el-button>
+						</div>
+					</el-col>
+				</el-row>
+			</el-form>
+		</el-card>
+		<el-card shadow="never">
+			<!-- 功能按钮 -->
+      <el-tabs v-model="state.queryParams.status" class="demo-tabs" @tab-change="handleClick">
+        <el-tab-pane :name="item.value" v-for="item in state.tabPaneList" :key="item.value" :label="item.label"></el-tab-pane>
+      </el-tabs>
+			<!-- 表格 -->
+			<el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="employeeName" label="受理人" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ row.employeeName + '[' + row.employeeStaffNo + ']' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="工单期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="督办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="督办回复时限" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="督办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="督办人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="被督办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="督办意见" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="督办回复时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="督办回复内容" show-overflow-tooltip></el-table-column>
+				<el-table-column label="操作" width="150" fixed="right" align="center">
+					<template #default="{ row }">
+						<el-button link type="primary" @click="approve(row)" title="查看督办详情" v-auth="'business:supervise:backlog:detail'"> 督办详情 </el-button>
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+			<!-- 分页 -->
+			<pagination
+				:total="state.total"
+				v-model:page="state.queryParams.PageIndex"
+				v-model:limit="state.queryParams.PageSize"
+				@pagination="queryList"
+			/>
+		</el-card>
+	</div>
+</template>
+<script setup lang="ts" name="orderSuperviseBacklog">
+import { onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import { ElButton, ElMessage, FormInstance } from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import { useRouter } from 'vue-router';
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+	queryParams: {
+		// 查询条件
+		PageIndex: 1,
+		PageSize: 10,
+		Keyword: '', // 关键字
+		Content: '', // 工单内容
+		AcceptType: '', // 受理类型
+		Channel: '', // 渠道
+		HotspotId: [], // 热点
+		OrgCode: [], // 机构
+		NameOrNo: '', // 受理坐席
+		crTime: [], // 创建时间
+		CreationTimeStart: '', // 创建时间 开始
+		CreationTimeEnd: '', // 创建时间 结束
+		TransferPhone: '', // 转派人
+		EmergencyLevel: [], // 紧急程度
+		exTime: [], // 办理期限
+		ExpiredTimeStart: '', //办理期限 开始
+		ExpiredTimeEnd: '', //办理期限 结束
+		PhoneNo: '', // 手机号
+		Status: [], // 状态
+		pushTypeOptions: '', //
+		PushTypeCode: '', //推送类型
+    status:'0'
+	},
+	tableList: [{}], //表单
+	loading: false, // 加载
+	total: 0, // 总数
+	acceptTypeOptions: [], //受理类型
+	channelOptions: [], // 来源频道
+	emergencyLevelOptions: [], // 紧急程度
+	orderStatusOptions: [], // 工单状态
+	orgsOptions: [], // 部门
+	pushTypeOptions: [], //推送分类
+	orgData: [], // 机构数据
+  tabPaneList: [
+    {
+      label:'甄别待办',
+      value:'0',
+    },
+    {
+      label:'甄别已办',
+      value:'1',
+    },
+  ], // tab列表
+});
+// 热点分类远程搜索
+const HotspotProps = {
+	label: 'hotSpotName',
+	children: 'children',
+	isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+	if (node.isLeaf) return resolve([]);
+	let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+	resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+	searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+	if (val) {
+		state.queryParams[startKey] = val[0];
+		state.queryParams[endKey] = val[1];
+	} else {
+		state.queryParams[startKey] = '';
+		state.queryParams[endKey] = '';
+	}
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+	handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+	handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+	const res: any = await listBaseData();
+	state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+	state.channelOptions = res.result?.channelOptions ?? [];
+	state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+	state.orgsOptions = res.result?.orgsOptions ?? [];
+	state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+	state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+	if (!auth('business:supervise:backlog:query')) ElMessage.error('抱歉,您没有权限查看督办待办!');
+	else {
+	}
+}, 500);
+// 切换tab 查询列表
+const handleClick = () => {
+  queryList();
+};
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	state.queryParams.CreationTimeStart = '';
+	state.queryParams.CreationTimeEnd = '';
+	state.queryParams.ExpiredTimeStart = '';
+	state.queryParams.ExpiredTimeStart = '';
+	queryList();
+}, 500);
+// 新增工单
+const onAddWorkOrder = () => {
+	// 跳转到录入工单页面
+	router.push('/business/order/accept');
+};
+// 表格多选
+const multipleTableRef = ref<RefType>();
+const multipleSelection = ref<any>([]);
+const handleSelectionChange = (val: any[]) => {
+	multipleSelection.value = val;
+};
+// 导出
+const onExport = () => {
+	console.log('导出');
+};
+// 甄别审批
+const approve = (row: any) => {
+	console.log('甄别审批');
+};
+onMounted(async () => {
+	await getBaseData();
+	queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-supervise-backlog-container {
+	.arrow {
+		transition: transform var(--el-transition-duration);
+		cursor: pointer;
+	}
+	.arrow.is-reverse {
+		transform: rotateZ(-180deg);
+	}
+}
+</style>

+ 2 - 2
src/views/business/supervise/index.vue

@@ -165,7 +165,7 @@
         </el-table-column>
         <el-table-column label="操作" width="150" fixed="right" align="center">
           <template #default="{ row }">
-            <el-button link type="primary" @click="onDetail(row)" title="查看督办详情" v-auth="'business:supervise:detail'"> 详情 </el-button>
+            <el-button link type="primary" @click="onDetail(row)" title="查看督办详情" v-auth="'business:supervise:detail'"> 查看详情 </el-button>
           </template>
         </el-table-column>
         <template #empty>
@@ -186,7 +186,7 @@
     <order-supervise ref="OrderSuperviseRef" @updateList="queryList" />
   </div>
 </template>
-<script setup lang="ts" name="businessSupervise">
+<script setup lang="ts" name="orderSupervise">
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import { hotSpotType, listBaseData } from '/@/api/business/order';
 import {ElButton, ElMessage, FormInstance} from 'element-plus';

+ 327 - 0
src/views/business/urge/index.vue

@@ -0,0 +1,327 @@
+<template>
+  <div class="business-urge-container layout-pd">
+    <!-- 搜索  -->
+    <el-card shadow="never">
+      <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="100px">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="发布状态" prop="AcceptType">
+              <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布状态" multiple clearable class="w100">
+                <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="工单标题" prop="Keyword">
+              <el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="queryList" />
+            </el-form-item>
+          </el-col>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布人" prop="Content">
+                <el-input v-model="state.queryParams.Content" placeholder="姓名/工号" clearable @keyup.enter="queryList" />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="发布范围" prop="AcceptType">
+                <el-select v-model="state.queryParams.AcceptType" placeholder="请选择发布范围" multiple clearable class="w100">
+                  <el-option v-for="item in state.acceptTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理类型" prop="Channel">
+                <el-select v-model="state.queryParams.Channel" placeholder="请选择受理类型" multiple clearable class="w100">
+                  <el-option v-for="item in state.channelOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="热点分类" prop="HotspotId">
+                <el-tree-select
+                    class="w100"
+                    v-model="state.queryParams.HotspotId"
+                    filterable
+                    clearable
+                    multiple
+                    :render-after-expand="false"
+                    show-checkbox
+                    placeholder="请选择热点分类"
+                    :props="HotspotProps"
+                    lazy
+                    :load="load"
+                    node-key="id"
+                    check-strictly
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="受理时间" prop="crTime">
+                <el-date-picker
+                    v-model="state.queryParams.crTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeCr"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <transition name="el-zoom-in-top">
+            <el-col :span="8" v-show="!searchCol">
+              <el-form-item label="归档时间" prop="exTime">
+                <el-date-picker
+                    v-model="state.queryParams.exTime"
+                    type="datetimerange"
+                    unlink-panels
+                    range-separator="至"
+                    start-placeholder="开始时间"
+                    end-placeholder="结束时间"
+                    :shortcuts="shortcuts"
+                    @change="timeStartChangeEx"
+                    value-format="YYYY-MM-DD[T]HH:mm:ss"
+                />
+              </el-form-item>
+            </el-col>
+          </transition>
+          <el-col :span="8">
+            <div class="flex-end w100">
+              <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+              <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+              <el-button link type="primary" @click="closeSearch">
+                {{ searchCol ? '展开' : '收起' }}
+                <SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+              </el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+    <el-card shadow="never">
+      <!-- 功能按钮 -->
+      <div class="mb20">
+          <el-button type="primary" @click="onExport" v-auth="'business:supervise:export'" :disabled="!multipleSelection.length">
+            <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+          </el-button>
+      </div>
+      <!-- 表格 -->
+      <el-table :data="state.tableList" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="no" label="工单编号" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="来源方式" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="no" label="当前节点" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="省/市工单" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="期满时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="expiredTime" label="受理时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="工单状态" show-overflow-tooltip></el-table-column>
+        <el-table-column label="工单标题" show-overflow-tooltip width="400">
+          <template #default="{ row }">
+            <el-button link type="primary">{{ row.title }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="接办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="接办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="hotspotName" label="热点分类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="催办部门" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="催办人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="expiredTime" label="催办时间" show-overflow-tooltip width="170">
+          <template #default="{ row }">
+            <span>{{ formatDate(row.expiredTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="acceptTypeText" label="被催办人" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="acceptTypeText" label="催办内容" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" width="150" fixed="right" align="center">
+          <template #default="{ row }">
+            <el-button link type="primary" @click="onDetail(row)" title="查看工单详情" v-auth="'business:urge:detail'"> 工单详情 </el-button>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <Empty />
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <pagination
+          :total="state.total"
+          v-model:page="state.queryParams.PageIndex"
+          v-model:limit="state.queryParams.PageSize"
+          @pagination="queryList"
+      />
+    </el-card>
+    <!-- 工单详情 -->
+    <order-detail ref="OrderDetailRef" @updateList="queryList" />
+    <!-- 督办内容 -->
+    <order-supervise ref="OrderSuperviseRef" @updateList="queryList" />
+  </div>
+</template>
+<script setup lang="ts" name="orderUrge">
+import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { hotSpotType, listBaseData } from '/@/api/business/order';
+import {ElButton, ElMessage, FormInstance} from 'element-plus';
+import { auth } from '/@/utils/authFunction';
+import { throttle, } from '/@/utils/tools';
+import { shortcuts } from '/@/utils/constants';
+import { formatDate } from '/@/utils/formatTime';
+import {useRouter} from "vue-router";
+// 引入组件
+const OrderDetail = defineAsyncComponent(() => import('/@/views/business/order/components/Order-detail.vue'));
+const OrderSupervise = defineAsyncComponent(() => import('/@/views/business/supervise/components/Order-supervise.vue'));
+
+// 定义变量内容
+const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 是否显示搜索栏
+const router = useRouter(); // 路由
+const state = reactive(<any>{
+  queryParams: {
+    // 查询条件
+    PageIndex: 1,
+    PageSize: 10,
+    Keyword: '', // 关键字
+    Content: '', // 工单内容
+    AcceptType: '', // 受理类型
+    Channel: '', // 渠道
+    HotspotId: [], // 热点
+    OrgCode: [], // 机构
+    NameOrNo: '', // 受理坐席
+    crTime: [], // 创建时间
+    CreationTimeStart: '', // 创建时间 开始
+    CreationTimeEnd: '', // 创建时间 结束
+    TransferPhone: '', // 转派人
+    EmergencyLevel: [], // 紧急程度
+    exTime: [], // 办理期限
+    ExpiredTimeStart: '', //办理期限 开始
+    ExpiredTimeEnd: '', //办理期限 结束
+    PhoneNo: '', // 手机号
+    Status: [], // 状态
+    pushTypeOptions: '', //
+    PushTypeCode: '', //推送类型
+  },
+  tableList: [{}], //表单
+  loading: false, // 加载
+  total: 0, // 总数
+  acceptTypeOptions: [], //受理类型
+  channelOptions: [], // 来源频道
+  emergencyLevelOptions: [], // 紧急程度
+  orderStatusOptions: [], // 工单状态
+  orgsOptions: [], // 部门
+  pushTypeOptions: [], //推送分类
+  orgData: [], // 机构数据
+});
+// 热点分类远程搜索
+const HotspotProps = {
+  label: 'hotSpotName',
+  children: 'children',
+  isLeaf: 'isLeaf',
+};
+// 热点分类远程搜索
+const load = async (node: any, resolve: any) => {
+  if (node.isLeaf) return resolve([]);
+  let res: any = await hotSpotType({ id: node.data.id ? node.data.id : '' });
+  resolve(res.result);
+};
+
+// 展开/收起
+const closeSearch = () => {
+  searchCol.value = !searchCol.value;
+};
+const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
+  if (val) {
+    state.queryParams[startKey] = val[0];
+    state.queryParams[endKey] = val[1];
+  } else {
+    state.queryParams[startKey] = '';
+    state.queryParams[endKey] = '';
+  }
+};
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+  handleTimeChange(val, 'CreationTimeStart', 'CreationTimeEnd');
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+  handleTimeChange(val, 'ExpiredTimeStart', 'ExpiredTimeEnd');
+};
+// 获取查询条件基础信息
+const getBaseData = async () => {
+  const res: any = await listBaseData();
+  state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+  state.channelOptions = res.result?.channelOptions ?? [];
+  state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+  state.orgsOptions = res.result?.orgsOptions ?? [];
+  state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+  state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
+};
+/** 获取列表 */
+const queryList = throttle(() => {
+  if (!auth('business:urge:query')) ElMessage.error('抱歉,您没有权限查看工单催办列表!');
+  else {
+  }
+}, 500);
+
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  state.queryParams.CreationTimeStart = '';
+  state.queryParams.CreationTimeEnd = '';
+  state.queryParams.ExpiredTimeStart = '';
+  state.queryParams.ExpiredTimeStart = '';
+  queryList();
+}, 500);
+// 表格多选
+const multipleTableRef = ref<RefType>()
+const multipleSelection = ref<any>([])
+const handleSelectionChange = (val: any[]) => {
+  multipleSelection.value = val
+}
+// 导出
+const onExport = () => {
+  console.log('导出');
+};
+// 查看工单详情
+const OrderDetailRef = ref<RefType>(); // 工单详情ref
+const onDetail = (row: any) => {
+  OrderDetailRef.value.openDialog()
+};
+onMounted(async () => {
+  await getBaseData();
+  queryList();
+});
+</script>
+
+<style scoped lang="scss">
+.business-urge-container {
+  .arrow {
+    transition: transform var(--el-transition-duration);
+    cursor: pointer;
+  }
+  .arrow.is-reverse {
+    transform: rotateZ(-180deg);
+  }
+}
+</style>

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

@@ -457,7 +457,7 @@ const linkList = ()=>{
       router.push('/business/screen')
       break;
     case '3': // 退回待办
-      router.push('/business/order')
+      router.push('/business/order/index')
       break;
     case '4': // 发布待办
       router.push('/business/release')

+ 9 - 9
src/views/knowledge/component/Knowledge-process.vue

@@ -82,13 +82,13 @@
 							prop="opinion"
 							:rules="[{ required: true, message: '请填写常用意见', trigger: 'blur' }]"
 						>
-							<Comment
-								@chooseComment="chooseComment"
-								placeholder="请填写常用意见"
-								v-model="state.ruleForm.opinion"
-								:loading="state.loading"
-								:commonEnum="state.commonEnum"
-							/>
+              <common-advice
+                  @chooseAdvice="chooseAdvice"
+                  v-model="state.ruleForm.opinion"
+                  placeholder="请填写常用意见"
+                  :loading="state.loading"
+                  :commonEnum="state.commonEnum"
+              />
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
@@ -115,7 +115,7 @@ import { KnowledgeAddStartFlowParams, KnowledgeDeleteStartFlowParams, KnowledgeA
 import { workflowNextSteps, workflowNext, workflowRecall, workflowRecallParams, workflowStepOptions } from '/@/api/system/workflow';
 import other from '/@/utils/other';
 // 引入组件
-const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Order-comment.vue')); // 常用意见
+const CommonAdvice = defineAsyncComponent(() => import('/@/components/CommonAdvice/index.vue')); // 常用意见
 const AnnexList = defineAsyncComponent(() => import('/@/components/AnnexList/index.vue'));  // 附件列表
 
 // 定义子组件向父组件传值/事件
@@ -274,7 +274,7 @@ const onCancel = () => {
 	closeDialog();
 };
 // 选择常用意见 填入填写框
-const chooseComment = (item: any) => {
+const chooseAdvice = (item: any) => {
 	state.ruleForm.opinion += item.content;
 };
 // 提交