瀏覽代碼

工单管理对接,菜单路径简化

zhangchong 2 年之前
父節點
當前提交
dd9db2ab18
共有 87 個文件被更改,包括 5971 次插入3646 次删除
  1. 6 6
      package-lock.json
  2. 10 0
      src/api/business/commonP.ts
  3. 24 12
      src/api/business/order.ts
  4. 0 0
      src/api/device/ivr.ts
  5. 0 0
      src/api/device/tels.ts
  6. 0 0
      src/api/device/telsGroup.ts
  7. 0 0
      src/api/device/trunks.ts
  8. 8 8
      src/api/login/user.ts
  9. 0 0
      src/api/system/dataAuthority.ts
  10. 0 0
      src/api/system/dict.ts
  11. 59 1
      src/api/system/roles.ts
  12. 0 0
      src/api/system/workflow.ts
  13. 0 0
      src/api/tels/blacklist.ts
  14. 0 0
      src/api/tels/callRecord.ts
  15. 10 9
      src/components/AudioPlayer/index.vue
  16. 1 1
      src/components/LogicFlow/PropertySetting/index.vue
  17. 2 2
      src/components/LogicFlow/PropertySetting/summary.vue
  18. 2 2
      src/components/LogicFlow/PropertySetting/task.vue
  19. 492 478
      src/components/LogicFlow/index.vue
  20. 1 1
      src/components/svgIcon/index.vue
  21. 274 56
      src/layout/navBars/breadcrumb/telControl.vue
  22. 15 15
      src/router/route.ts
  23. 6 1
      src/theme/element.scss
  24. 1 1
      src/types/global.d.ts
  25. 1 0
      src/types/mitt.d.ts
  26. 1 1
      src/utils/other.ts
  27. 81 4
      src/utils/tools.ts
  28. 1 1
      src/views/business/extension/index.vue
  29. 3 16
      src/views/business/order/components/Comment.vue
  30. 1 1
      src/views/business/order/components/CrculationRecord.vue
  31. 53 43
      src/views/business/order/components/Detail.vue
  32. 1 1
      src/views/business/order/components/Expand.vue
  33. 773 0
      src/views/business/order/components/ExpandForm.vue
  34. 36 29
      src/views/business/order/components/History.vue
  35. 127 106
      src/views/business/order/components/Process.vue
  36. 119 59
      src/views/business/order/index.vue
  37. 356 208
      src/views/business/order/orderAccept/add.vue
  38. 1022 0
      src/views/business/order/orderAccept/edit.vue
  39. 1 1
      src/views/business/orderReturnVist/index.vue
  40. 1 1
      src/views/business/quality/index.vue
  41. 0 0
      src/views/business/screening/index.vue
  42. 0 719
      src/views/businessManage/workOrderManage/components/ExpandForm.vue
  43. 3 3
      src/views/device/iverConfig/index.vue
  44. 2 2
      src/views/device/ivrCategroy/component/addCategroy.vue
  45. 2 2
      src/views/device/ivrCategroy/component/editCatehroy.vue
  46. 141 0
      src/views/device/ivrCategroy/index.vue
  47. 5 9
      src/views/device/ivrList/index.vue
  48. 114 0
      src/views/device/tels/index.vue
  49. 330 0
      src/views/device/telsGroup/index.vue
  50. 1 1
      src/views/device/trunks/component/add.vue
  51. 1 1
      src/views/device/trunks/component/edit.vue
  52. 174 0
      src/views/device/trunks/index.vue
  53. 0 144
      src/views/deviceManagement/ivrCategroy/index.vue
  54. 0 115
      src/views/deviceManagement/tels/index.vue
  55. 0 324
      src/views/deviceManagement/telsGroup/index.vue
  56. 0 179
      src/views/deviceManagement/trunks/index.vue
  57. 206 196
      src/views/home/component/entrance.vue
  58. 80 70
      src/views/home/index.vue
  59. 0 0
      src/views/knowledge/knowledge/index.vue
  60. 3 3
      src/views/system/configure/dict/component/add.vue
  61. 3 4
      src/views/system/configure/dict/component/edit.vue
  62. 76 95
      src/views/system/configure/dict/index.vue
  63. 4 41
      src/views/system/configure/workflow/component/Jump.vue
  64. 47 0
      src/views/system/configure/workflow/component/add.vue
  65. 4 4
      src/views/system/configure/workflow/component/edit.vue
  66. 397 0
      src/views/system/configure/workflow/index.vue
  67. 0 12
      src/views/system/configureManage/dictionarie/component/data.d.ts
  68. 0 380
      src/views/system/configureManage/workflowManage/index.vue
  69. 125 0
      src/views/system/dataAuth/component/AddAuth.vue
  70. 124 0
      src/views/system/dataAuth/component/EditAuth.vue
  71. 180 0
      src/views/system/dataAuth/index.vue
  72. 1 1
      src/views/system/menu/component/addMenu.vue
  73. 1 1
      src/views/system/menu/component/editMenu.vue
  74. 201 46
      src/views/system/menu/index.vue
  75. 89 42
      src/views/system/organizational/index.vue
  76. 18 4
      src/views/system/roles/index.vue
  77. 2 4
      src/views/system/systemParameter/index.vue
  78. 1 1
      src/views/system/user/component/addUser.vue
  79. 1 1
      src/views/system/user/component/editUser.vue
  80. 2 4
      src/views/system/user/index.vue
  81. 1 1
      src/views/tels/blacklist/component/addBlacklist.vue
  82. 0 0
      src/views/tels/blacklist/component/operationRecord.vue
  83. 62 66
      src/views/tels/blacklist/index.vue
  84. 0 0
      src/views/tels/callRecord/component/PlayRecording.vue
  85. 62 83
      src/views/tels/callRecord/index.vue
  86. 0 0
      src/views/tels/telsLog/component/detail.vue
  87. 20 24
      src/views/tels/telsLog/index.vue

+ 6 - 6
package-lock.json

@@ -61,9 +61,9 @@
 			}
 		},
 		"node_modules/@babel/parser": {
-			"version": "7.20.5",
-			"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.5.tgz",
-			"integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==",
+			"version": "7.20.15",
+			"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.15.tgz",
+			"integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==",
 			"bin": {
 				"parser": "bin/babel-parser.js"
 			},
@@ -4457,9 +4457,9 @@
 	},
 	"dependencies": {
 		"@babel/parser": {
-			"version": "7.20.5",
-			"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.5.tgz",
-			"integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA=="
+			"version": "7.20.15",
+			"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.15.tgz",
+			"integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg=="
 		},
 		"@babel/runtime": {
 			"version": "7.20.6",

+ 10 - 0
src/api/businessManage/commonP.ts → src/api/business/commonP.ts

@@ -39,4 +39,14 @@ export function deleteCommon(data:object) {
         method: 'post',
         data
     });
+}
+/**
+ * 获取省市区
+ * @param 
+ */
+export function treeArea() {
+    return request({
+        url: `/api/v1/CommonP/tree-area`,
+        method: 'get',
+    });
 }

+ 24 - 12
src/api/businessManage/workOrderManage.ts → src/api/business/order.ts

@@ -7,6 +7,7 @@
  * @LastEditTime: 2022-11-16 14:49:01
  */
 import request from '/@/utils/request';
+import qs from 'qs';
 /**
  * 列表页面基础数据
  * @param {}
@@ -20,13 +21,12 @@ export function listBaseData() {
 }
 /**
  * 工单列表
- * @param {object} params
+ * @param {any} params
  */
-export function orderList(params:object) {
+export function orderList(params:any) {
     return request({
-        url: `/api/v1/Order`,
+        url: `/api/v1/Order?${qs.stringify(params)}`,
         method: 'get',
-        params
     });
 }
 /**
@@ -66,7 +66,7 @@ export function orderEdit(data:object) {
  * 工单详情
  * @param {string} id
  */
-export function orderDetail(id:string) {
+export function orderDetail(id:string | any[]) {
     return request({
         url: `/api/v1/Order/${id}`,
         method: 'get',
@@ -84,21 +84,23 @@ export function orderDelete(id:string) {
 }
 /**
  * 开始流程
- * @param {string} id
+ * @param {string} id 工单id
+ * @param {object} data 开启参数
  */
-export function orderStartflow(id:string) {
+export function orderStartflow(id:string,data:object) {
     return request({
         url: `/api/v1/Order/${id}/startflow`,
         method: 'post',
+        data
     });
 }
 /**
- * 查询工单办理流程编号
+ * 查询工单办理流程开启参数
  * @param {object}params
  */
-export function OrderFlowId(params?:object) {
+export function OrderFlowParams(params?:object) {
     return request({
-        url: `/api/v1/Order/flowId-manage`,
+        url: `/api/v1/Order/flow-start`,
         method: 'get',
         params
     });
@@ -126,13 +128,23 @@ export function orderBaseExt(params?:object) {
     });
 }
 /**
- * 获取热点
+ * 获取热点下一级
  * @param {object} params
  */
 export function hotspottype(params?:object) {
     return request({
-        url: `/api/v1/Order/hotspottype-list-parent`,
+        url: `/api/v1/HotSpot/children`,
         method: 'get',
         params
     });
+}
+/**
+ * 查询热点数据(包含所有根目录及所查热点的所有上级对象) 编辑页面使用
+ * @param {object} params
+ */
+export function hotspotWithParents(id:object) {
+    return request({
+        url: `/api/v1/HotSpot/${id}/with-parents`,
+        method: 'get'
+    });
 }

+ 0 - 0
src/api/deviceManagement/ivr.ts → src/api/device/ivr.ts


+ 0 - 0
src/api/deviceManagement/tels.ts → src/api/device/tels.ts


+ 0 - 0
src/api/deviceManagement/telsGroup.ts → src/api/device/telsGroup.ts


+ 0 - 0
src/api/deviceManagement/trunks.ts → src/api/device/trunks.ts


+ 8 - 8
src/api/login/user.ts

@@ -133,22 +133,22 @@ export function hangupApi(val: any) {
 /**
  * 分机休息
  */
-export function telRest() {
+export function telRest(data:object) {
     return request({
         url: `/api/v1/Pbx/rest`,
-        method: 'put',
+        method: 'post',
+        data
     });
 }
 /**
- * 申请小休
- * @param data  申请选择的原因
+ * 
+ * @param  查询小修流程开启参数
  * @returns 返回接口数据
  */
-export function applyForRest(data: object) {
+export function restFlowStart() {
     return request({
-        url: `/api/v1/Pbx/meeting`,
-        method: 'post',
-        data
+        url: `/api/v1/Pbx/flow-start`,
+        method: 'get'
     });
 }
 /**

+ 0 - 0
src/api/system/dataAuthority.ts


+ 0 - 0
src/api/system/dictionarie.ts → src/api/system/dict.ts


+ 59 - 1
src/api/system/roles.ts

@@ -83,9 +83,67 @@ export const delRole = (roleId: string) => {
  * @param {object} params  ids
  * @return {*}
  */
- export const getUserListByIds = (params: any) => {
+export const getUserListByIds = (params: any) => {
 	return request({
 		url: `/api/v1/User${params}`,
 		method: 'get',
 	});
 };
+/**
+ * @description: 获取数据表
+ * @param {object} 
+ * @return {*}
+ */
+ export const dataAuthList = () => {
+	return request({
+		url: `/api/v1/Role/datatable-list`,
+		method: 'get',
+	});
+};
+/**
+ * @description: 新增数据权限
+ * @param {object} data  
+ * @return {*}
+ */
+ export const addDataAuth = (data: object) => {
+	return request({
+		url: `/api/v1/Role/add-data-authority`,
+		method: 'post',
+		data
+	});
+};
+/**
+ * @description: 修改数据权限
+ * @param {object} data  
+ * @return {*}
+ */
+ export const editDataAuth = (data: object) => {
+	return request({
+		url: `/api/v1/Role/update-data-authority`,
+		method: 'post',
+		data
+	});
+};
+/**
+ * @description: 删除数据权限
+ * @param {string} id  
+ * @return {*}
+ */
+ export const deleteDataAuth = (id: string) => {
+	return request({
+		url: `/api/v1/Role/remove-data-authority/${id}`,
+		method: 'delete',
+	});
+};
+/**
+ * @description: 获取角色所有数据权限设置
+ * @param {object} params  
+ * @return {*}
+ */
+ export const getdataauthoritybyrole = (params: object) => {
+	return request({
+		url: `/api/v1/Role/getdataauthoritybyrole`,
+		method: 'get',
+		params
+	});
+};

+ 0 - 0
src/api/system/workflowManage.ts → src/api/system/workflow.ts


+ 0 - 0
src/api/telsManage/blacklist.ts → src/api/tels/blacklist.ts


+ 0 - 0
src/api/telsManage/callRecord.ts → src/api/tels/callRecord.ts


+ 10 - 9
src/components/AudioPlayer/index.vue

@@ -187,15 +187,16 @@ const downLoad = () => {
     // window.URL.revokeObjectURL(href) // 释放blob对象
 
 
-    const elink = document.createElement('a')
-    elink.href = props.url
-    elink.setAttribute('download', props?.fileName ?? '')
-    elink.style.display = 'none'
-    document.body.appendChild(elink)
-    setTimeout(() => {
-        elink.click()
-        document.body.removeChild(elink)
-    }, 66)
+    // const elink = document.createElement('a')
+    // elink.href = props.url
+    // elink.setAttribute('download', props?.fileName ?? '')
+    // elink.style.display = 'none'
+    // document.body.appendChild(elink)
+    // setTimeout(() => {
+    //     elink.click()
+    //     document.body.removeChild(elink)
+    // }, 66)
+    window.open(props.url)
 }
 </script>
 <style scoped lang="scss">

+ 1 - 1
src/components/LogicFlow/PropertySetting/index.vue

@@ -7,7 +7,7 @@
     </div>
 </template>
 <script lang="ts" setup name="flowMain">
-import { reactive, ref, defineProps, computed, defineEmits, defineAsyncComponent, unref } from 'vue'
+import { reactive, ref, computed, defineAsyncComponent, unref } from 'vue'
 import { NodeTypeEnum } from '../enums';
 const task = defineAsyncComponent(() => import('./task.vue'));
 const summary = defineAsyncComponent(() => import('./summary.vue'));

+ 2 - 2
src/components/LogicFlow/PropertySetting/summary.vue

@@ -45,8 +45,8 @@
 
 </template>
 <script lang="ts" setup name="flowNode">
-import { reactive, watch, defineProps, onMounted, defineEmits, ref } from 'vue';
-import { baseData, getSelectList } from '/@/api/system/workflowManage';
+import { reactive, watch, onMounted, ref } from 'vue';
+import { baseData, getSelectList } from '/@/api/system/workflow';
 import { queryUser } from '/@/api/login/user';
 // 注意:ref不能与model一样,相同的话表单双向绑定将会失效
 const form = reactive<any>({} as any)

+ 2 - 2
src/components/LogicFlow/PropertySetting/task.vue

@@ -45,8 +45,8 @@
 
 </template>
 <script lang="ts" setup name="flowNode">
-import { reactive, watch, defineProps, onMounted, defineEmits, ref } from 'vue';
-import { baseData, getSelectList } from '/@/api/system/workflowManage';
+import { reactive, watch, onMounted, ref } from 'vue';
+import { baseData, getSelectList } from '/@/api/system/workflow';
 import { queryUser } from '/@/api/login/user';
 // 注意:ref不能与model一样,相同的话表单双向绑定将会失效
 const form = reactive<any>({} as any)

文件差異過大導致無法顯示
+ 492 - 478
src/components/LogicFlow/index.vue


+ 1 - 1
src/components/svgIcon/index.vue

@@ -8,7 +8,7 @@
 	<i v-else :class="getIconName" :style="setIconSvgStyle" />
 </template>
 
-<script lang="ts" name="svgIcon" setup>
+<script lang="ts" name="SvgIcon" setup>
 import { computed } from 'vue';
 
 // 定义父组件传过来的值

+ 274 - 56
src/layout/navBars/breadcrumb/telControl.vue

@@ -342,21 +342,138 @@
 		</template>
 	</el-dialog>
 
-	<!-- 小休提交审核 -->
-	<el-dialog v-model="state.showRestDialog" draggable title="小休申请" width="400px">
-		<el-form :model="state.restForm" label-width="80px" ref="restFormRef">
-			<el-form-item label="小休" prop="reason" :rules="[{ required: true, message: '请选择小休原因', trigger: 'change' }]">
-				<el-select v-model="state.restForm.reason" placeholder="请选择小休原因" class="w100" clearable>
-					<el-option v-for="item in state.telsList" :key="item.id" :label="item.no" :value="item.no" />
-				</el-select>
-			</el-form-item>
-		</el-form>
+	<!-- 小休弹窗 -->
+	<el-dialog
+		v-model="state.showRestDialog"
+		ref="dialogRestRef"
+		draggable
+		title="小休申请"
+		:width="AppConfigInfo.isRestApproval ? '60%' : '400px'"
+		@mouseup="mouseup"
+		:style="'transform: ' + state.trasform + ';'"
+	>
+		<!-- 需要审核 -->
+		<template v-if="AppConfigInfo.isRestApproval">
+			<el-form :model="state.restForm" label-width="90px" ref="restFormRef">
+				<el-row :gutter="10">
+					<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
+						<el-form-item label="小休" prop="reason" :rules="[{ required: true, message: '请选择小休原因', trigger: 'change' }]">
+							<el-select v-model="state.restForm.reason" placeholder="请选择小休原因" class="w100" clearable>
+								<el-option v-for="item in state.restReasonOptions" :key="item.id" :label="item.content" :value="item.id" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
+						<el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
+							<el-select v-model="state.restForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
+								<el-option v-for="item in state.nextStepOptions" :key="item.code" :label="item.name" :value="item.code" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
+						<el-form-item label="处理人" prop="nextHandlers" :rules="[{ required: false, message: '请选择处理人', trigger: 'change' }]">
+							<el-select
+								v-model="state.restForm.nextHandlers"
+								multiple
+								filterable
+								placeholder="请选择处理人"
+								class="w100"
+								@change="selectHanders"
+								value-key="key"
+							>
+								<el-option v-for="item in state.handerOptions" :key="item.key" :label="item.value" :value="item" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
+						<el-form-item
+							label="主办"
+							prop="nextMainHandler"
+							multiple
+							filterable
+							:rules="[{ required: false, message: '请选择主办', trigger: 'change' }]"
+						>
+							<el-select v-model="state.restForm.nextMainHandler" placeholder="请选择主办" class="w100">
+								<el-option v-for="item in state.handerOptions" :key="item.key" :label="item.value" :value="item.key" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
+						<el-form-item label="" prop="acceptSms">
+							<el-checkbox v-model="state.restForm.acceptSms" label="短信通知" />
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+						<el-form-item
+							label="办理意见"
+							class="textarea"
+							prop="opinion"
+							:rules="[{ required: true, message: '请填写小休办理意见', trigger: 'blur' }]"
+						>
+							<el-input
+								v-model="state.restForm.opinion"
+								type="textarea"
+								:autosize="{ minRows: 10, maxRows: 10 }"
+								placeholder="请填写小休办理意见"
+								clearable
+							>
+							</el-input>
+							<span class="bttons">
+								<el-button @click="showComents" class="default-button" :loading="state.loading">常用意见</el-button>
+								<el-button type="primary" @click="onAddComments" :loading="state.loading">添加到常用意见</el-button>
+							</span>
+						</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' }]">
+							<el-upload
+								v-model:file-list="state.fileList"
+								class="upload-demo w100"
+								action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
+								multiple
+								:before-remove="beforeRemove"
+								:on-exceed="handleExceed"
+								ref="uploadListRef"
+							>
+								<el-button> <SvgIcon name="ele-Upload" /> 上传附件 </el-button>
+								<template #file="{ file }">
+									<div class="el-upload-list__item-info">
+										<a class="el-upload-list__item-name">
+											<SvgIcon class="mr5" :name="fileType(checkFile(file.name))" size="16px" />
+											<span class="el-upload-list__item-file-name">{{ file.name }}</span>
+										</a>
+									</div>
+									<SvgIcon name="ele-Close" class="el-icon--close" size="14px" title="删除文件" @click="handleRemove(file)" />
+								</template>
+							</el-upload>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+		</template>
+		<!-- 不需要审核 -->
+		<template v-else>
+			<el-form :model="state.restForm" label-width="90px" ref="restFormRef">
+				<el-row :gutter="10">
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+						<el-form-item label="小休" prop="reason" :rules="[{ required: true, message: '请选择小休原因', trigger: 'change' }]">
+							<el-select v-model="state.restForm.reason" placeholder="请选择小休原因" class="w100" clearable>
+								<el-option v-for="item in state.restReasonOptions" :key="item.id" :label="item.content" :value="item.content" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+		</template>
+
 		<template #footer>
 			<span class="dialog-footer">
 				<el-button @click="state.showRestDialog = false" class="default-button">取 消</el-button>
-				<el-button type="primary" @click="clickOnRest" :loading="state.loading">确 定</el-button>
+				<el-button type="primary" @click="clickOnRest" :loading="state.loading">提 交</el-button>
 			</span>
 		</template>
+		<!-- 常用意见管理 -->
+		<Comment ref="CommentRef" @chooseComment="chooseComment" />
 	</el-dialog>
 
 	<!-- 转接 -->
@@ -490,9 +607,10 @@
 </template>
 
 <script setup lang="ts" name="telControl">
-import { reactive, ref, computed, watch, onMounted, onUnmounted } from 'vue';
+import { reactive, ref, computed, watch, onMounted, onUnmounted, defineAsyncComponent } from 'vue';
 import { useRouter } from 'vue-router';
 import { ElMessageBox, ElNotification, ElMessage } from 'element-plus';
+import type { UploadProps } from 'element-plus';
 import { storeToRefs } from 'pinia';
 import { useUserInfo } from '/@/stores/userInfo';
 import { useTelStatus } from '/@/stores/telStatus';
@@ -501,11 +619,11 @@ import { getImageUrl } from '/@/utils/tools';
 import { getTelsList } from '/@/api/login/user';
 import signalR from '/@/utils/signalR';
 import { formatDuraton } from '/@/utils/formatTime';
+import { checkFile, fileType, commonEeum } from '/@/utils/tools';
 import {
 	onDuty,
 	offDuty,
 	telRest,
-	applyForRest,
 	telUnrest,
 	telHold,
 	telUnhold,
@@ -517,9 +635,14 @@ import {
 	visitorToOuter,
 	meeting,
 	hangupApi,
+	restFlowStart,
 } from '/@/api/login/user';
+import { addCommon, commonList } from '/@/api/business/commonP';
+
+// 引入组件
+const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Comment.vue'));
 
-const state = reactive({
+const state = reactive<any>({
 	active: <any>[], // 当前选中
 	currentStatus: '', //当前通话状态
 	showDutyDialog: false, //签入选分机弹窗
@@ -532,6 +655,11 @@ const state = reactive({
 	showRestDialog: false, //小休弹窗
 	restForm: {
 		//小休表单
+		opinion: '',
+		nextStepCode: '',
+		nextHandlers: [],
+		acceptSms: false,
+		nextMainHandler: '',
 		reason: '',
 	},
 	showTransferDialog: false, // 转接弹窗
@@ -575,6 +703,12 @@ const state = reactive({
 	},
 	time: 0, // 毫秒数
 	timer: null as any, // 计时器
+	restReasonOptions: [], // 小休原因
+	nextStepOptions: [], // 下一环节
+	handerOptions: [], // 处理人
+	genderList: [],
+	trasform: 'translate(0px, 0px)',
+	fileList: [],
 });
 const usetelStatusStore = useTelStatus();
 const { telStatusInfo } = storeToRefs(usetelStatusStore);
@@ -587,6 +721,9 @@ const restFormRef = ref(); //小休
 const transferFormRef = ref(); // 转接
 const outboundFormRef = ref(); //外呼
 const callForwardingFormRef = ref(); //呼叫转移
+const CommentRef = ref(); // 常用意见
+const uploadListRef = ref(); // 上传组件
+const dialogRestRef = ref(); // 小休申请弹窗
 const router = useRouter();
 //  signalR 初始化signalr
 signalR.init();
@@ -643,7 +780,7 @@ if (telStatusInfo.value.isDutyOn) {
 		usetelStatusStore.setPhonecontrolState('ring');
 		// 跳转到录入工单页面
 		router.push({
-			path: '/businessManage/workOrderManage/wokOrder',
+			path: '/business/order/orderAccept',
 			query: {
 				form: 'tel',
 			},
@@ -892,7 +1029,7 @@ const clickOnDuty = () => {
 						usetelStatusStore.setPhonecontrolState('ring');
 						// 跳转到录入工单页面
 						router.push({
-							path: '/businessManage/workOrderManage/wokOrder',
+							path: '/business/order/orderAccept',
 							query: {
 								form: 'tel',
 							},
@@ -944,7 +1081,8 @@ const clickOnDuty = () => {
 					state.showDutyDialog = false;
 					state.loading = false;
 				})
-				.catch(() => {
+				.catch((err:any) => {
+					console.log(err,'签入出现错误')
 					state.showDutyDialog = false;
 					state.loading = false;
 				});
@@ -1048,51 +1186,124 @@ const hanupItem = (value: any) => {
 		.catch(() => {});
 };
 // 小休
-const onRest = () => {
+const onRest = async () => {
 	if (AppConfigInfo.value.isRestApproval) {
 		// 如果小休需要审核
-		//  重置表单
-		restFormRef.value?.resetFields();
-		state.showRestDialog = true;
-		
-	} else {
-		//不需要审核直接开始小休
-		ElMessageBox.confirm(`确定要开始小休,是否继续?`, '提示', {
-			confirmButtonText: '确认',
-			cancelButtonText: '取消',
-			type: 'warning',
-			draggable: true,
-			cancelButtonClass: 'default-button',
-			autofocus: false,
-		})
-			.then(() => {
-				telRest().then(() => {
-					ElNotification({
-						title: '成功',
-						message: '小休开始',
-						type: 'success',
-					});
-					// 设置休息状态 小休中
-					usetelStatusStore.setRest('resting');
-					// 设置话机状态 开始休息设置为小休状态
-					usetelStatusStore.setPhonecontrolState('rest');
-				});
-			})
-			.catch(() => {});
+		// 查询流程节点参数
+		const res: any = await restFlowStart();
+		state.nextStepOptions = res.result;
 	}
+	//  重置表单
+	restFormRef.value?.resetFields();
+	// 查询小休原因
+	const response: any = await commonList({ typecode: commonEeum.RestReason });
+	state.restReasonOptions = response.result;
+	state.showRestDialog = true;
+};
+// 小休流程选择下一环节
+const selectNextStep = (val: any) => {
+	const next = state.nextStepOptions.find((item: any) => item.code === val);
+	state.handerOptions = next.nextSteps ?? [];
 };
-// 确定申请小休
+// 小休选择处理人
+const selectHanders = (val: any) => {
+	state.restForm.nextHandlers = val.map((item: any) => {
+		return {
+			id: item.key,
+			name: item.value,
+			label: item.value,
+			key: item.key
+		};
+	});
+};
+// 确定小休
 const clickOnRest = () => {
-	applyForRest(state.restForm).then(() => {
-		ElNotification({
-			title: '成功',
-			message: '申请小休成功',
-			type: 'success',
-		});
-		// 设置休息状态 审核中
-		usetelStatusStore.setRest('Inreview');
+	restFormRef.value.validate((valid: boolean) => {
+		if (valid) {
+			ElMessageBox.confirm(`确认提交?`, '提示', {
+				confirmButtonText: '确认',
+				cancelButtonText: '取消',
+				type: 'warning',
+				draggable: true,
+				cancelButtonClass: 'default-button',
+				autofocus: false,
+			})
+				.then(() => {
+					if (AppConfigInfo.value.isRestApproval) {
+						//如果需要审核
+						telRest(state.restForm).then(() => {
+							ElNotification({
+								title: '成功',
+								message: '申请小休成功',
+								type: 'success',
+							});
+							// 设置休息状态 审核中
+							usetelStatusStore.setRest('Inreview');
+							state.showRestDialog = false;
+						});
+					} else {
+						//不需要审核直接开始小休
+						telRest(state.restForm).then(() => {
+							ElNotification({
+								title: '成功',
+								message: '小休开始',
+								type: 'success',
+							});
+							state.showRestDialog = false;
+							// 设置休息状态 小休中
+							usetelStatusStore.setRest('resting');
+							// 设置话机状态 开始休息设置为小休状态
+							usetelStatusStore.setPhonecontrolState('rest');
+						});
+					}
+				})
+				.catch(() => {});
+		} else {
+			return false;
+		}
 	});
 };
+// 设置抽屉
+const mouseup = () => {
+	state.trasform = dialogRestRef.value.dialogContentRef.$el.style.transform;
+};
+// 删除确认
+const beforeRemove: UploadProps['beforeRemove'] = (uploadFile) => {
+	return ElMessageBox.confirm(`确定要删除 ${uploadFile.name} ?`).then(
+		() => true,
+		() => false
+	);
+};
+// 删除文件
+const handleRemove = (file: any) => {
+	uploadListRef.value.handleRemove(file);
+};
+const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
+	ElMessage.warning(`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + uploadFiles.length} totally`);
+};
+
+// 打开常用意见管理
+const showComents = () => {
+	CommentRef.value.openDialog(commonEeum.Rest);
+};
+// 添加到常用意见
+const onAddComments = async () => {
+	if (!state.restForm.opinion) {
+		ElMessage.warning(`请先填写小休常用意见`);
+		return;
+	}
+	await addCommon({
+		typeCode: commonEeum.Rest,
+		content: state.restForm.opinion,
+	});
+	ElMessage.success('操作成功');
+	CommentRef.value.closeDialog();
+};
+// 选择常用意见 填入填写框
+const chooseComment = (item: any) => {
+	state.restForm.opinion += item.content;
+	CommentRef.value.closeDialog();
+};
 // 小休结束
 const onRestEnd = () => {
 	ElMessageBox.confirm(`确定要结束小休,是否继续?`, '提示', {
@@ -1438,7 +1649,7 @@ watch(
 onUnmounted(() => {
 	removeTimer();
 });
-onMounted(() => {
+onMounted(async () => {
 	// 获取所有分机列表
 	getTelsLists();
 });
@@ -1448,7 +1659,14 @@ onMounted(() => {
 .seizeSeat-box {
 	display: none;
 }
-
+.textarea {
+	position: relative;
+	.bttons {
+		position: absolute;
+		right: 10px;
+		bottom: 10px;
+	}
+}
 .phoneControls {
 	display: flex;
 	flex: 1;

+ 15 - 15
src/router/route.ts

@@ -77,9 +77,9 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
 				},
 				children:[
 					{
-						path: '/telsManage/callRecord',
+						path: '/tels/callRecord',
 						name: 'callRecord',
-						component: () => import('/@/views/telsManage/callRecord/index.vue'),
+						component: () => import('/@/views/tels/callRecord/index.vue'),
 						meta: {
 							title: '通讯记录',
 							isLink: '',
@@ -91,9 +91,9 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
 						},
 					},
 					{
-						path: '/telsManage/blacklist',
+						path: '/tels/blacklist',
 						name: 'blacklist',
-						component: () => import('/@/views/telsManage/blacklist/index.vue'),
+						component: () => import('/@/views/tels/blacklist/index.vue'),
 						meta: {
 							title: '黑名单管理',
 							isLink: '',
@@ -107,10 +107,10 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
 				]
 			},
 			{
-				path: '/deviceManagement',
-				name: 'deviceManagement',
+				path: '/device',
+				name: 'device',
 				component: () => import('/@/layout/routerView/parent.vue'),
-				redirect: '/deviceManagement/tels',
+				redirect: '/device/tels',
 				meta: {
 					title: '设备管理',
 					isLink: '',
@@ -122,9 +122,9 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
 				},
 				children: [
 					{
-						path: '/deviceManagement/tels',
+						path: '/device/tels',
 						name: 'tels',
-						component: () => import('/@/views/deviceManagement/tels/index.vue'),
+						component: () => import('/@/views/device/tels/index.vue'),
 						meta: {
 							title: '话机管理',
 							isLink: '',
@@ -136,9 +136,9 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
 						},
 					},
 					{
-						path: '/deviceManagement/telsGroup',
+						path: '/device/telsGroup',
 						name: 'telsGroup',
-						component: () => import('/@/views/deviceManagement/telsGroup/index.vue'),
+						component: () => import('/@/views/device/telsGroup/index.vue'),
 						meta: {
 							title: '分机组管理',
 							isLink: '',
@@ -150,9 +150,9 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
 						},
 					},
 					{
-						path: '/deviceManagement/ivrCategroy',
+						path: '/device/ivrCategroy',
 						name: 'ivrCategroy',
-						component: () => import('/@/views/deviceManagement/ivrCategroy/index.vue'),
+						component: () => import('/@/views/device/ivrCategroy/index.vue'),
 						meta: {
 							title: 'IVR分类管理',
 							isLink: '',
@@ -164,9 +164,9 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
 						},
 					},
 					{
-						path: '/deviceManagement/ivrList',
+						path: '/device/ivrList',
 						name: 'ivrList',
-						component: () => import('/@/views/deviceManagement/ivrList/index.vue'),
+						component: () => import('/@/views/device/ivrList/index.vue'),
 						meta: {
 							title: 'IVR管理',
 							isLink: '',

+ 6 - 1
src/theme/element.scss

@@ -266,7 +266,12 @@
 		background-color: var(--hotline-bg-main-color) !important;
 	}
 }
-
+.el-table-v2__header-row{
+	background-color: var(--hotline-bg-main-color) !important;
+}
+.el-table-v2__header-cell{
+	background-color: var(--hotline-bg-main-color) !important;
+}
 /* scrollbar
 ------------------------------- */
 /*防止页面切换时,滚动条高度不变的问题(滚动条高度非滚动条滚动高度)*/

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

@@ -1,7 +1,7 @@
 // 申明外部 npm 插件模块
 declare module 'vue-grid-layout';
 declare module 'qrcodejs2-fixes';
-declare module 'splitpanes';
+declare module 'sortablejs';
 declare module 'js-cookie';
 declare module '@wangeditor/editor-for-vue';
 declare module 'js-table2excel';

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

@@ -11,6 +11,7 @@ export type MittType = {
 	onTagsViewRefreshRouterView?: any; // tagsview 刷新界面
 	onCurrentContextmenuClick?: any; // tagsview 右键菜单每项点击时
 	scrollTopEmit?:object; //点击分页跳转滚动到顶部
+	refreshList?:string; // 刷新当前页面
 };
 // mitt 参数类型定义
 declare type LayoutMobileResize = {

+ 1 - 1
src/utils/other.ts

@@ -6,7 +6,7 @@ import pinia from '/@/stores/index';
 import { storeToRefs } from 'pinia';
 import { useThemeConfig } from '/@/stores/themeConfig';
 import { Local } from '/@/utils/storage';
-import SvgIcon from '/@/components/svgIcon/index.vue';
+import SvgIcon from '/@/components/SvgIcon/index.vue';
 
 /**
  * 导出全局注册 element plus svg 图标

+ 81 - 4
src/utils/tools.ts

@@ -36,14 +36,14 @@ export function throttle(func: Function, delay: number, thisArg?: any) {
 /**
  * vite引入图片
  *
- * @param name   文件路径
+ * @param {string} name   文件路径
  */
 export function getImageUrl(name: string) {
     return new URL(`../assets/images/${name}`, import.meta.url).href;
 }
 /**
  * 手机号脱敏处理
- * @param phoneNumber  手机号码
+ * @param  { string} phoneNumber  手机号码
  * @returns 返回处理后的手机号码
  */
 export function desensitizationPhone(phoneNumber: string) {
@@ -52,7 +52,7 @@ export function desensitizationPhone(phoneNumber: string) {
 }
 /**
  * 姓名脱敏处理
- * @param name  姓名
+ * @param {string} name  姓名
  * @returns 返回处理后的姓名
  */
 export function desensitizationName(name: string) {
@@ -61,4 +61,81 @@ export function desensitizationName(name: string) {
     return len <= 3 ? "*" + name.substring(1, len) :
         len > 3 && len <= 6 ? "**" + name.substring(2, len) :
             len > 6 ? name.substring(0, 2) + "****" + name.substring(6, len) : "";
-}
+}
+/**
+ * 检查文件类型
+ * @param  {string} fileValue  姓名
+ * @returns 返回处理后的姓名
+ */
+export function checkFile(fileValue: string) {
+    let index = fileValue.lastIndexOf('.'); //(考虑严谨用lastIndexOf(".")得到)得到"."在第几位
+    let fileValueSuffix = fileValue.substring(index); //截断"."之前的,得到后缀
+    if (/(.*)\.(mp4|avi|wmv|MP4|AVI|WMV)$/.test(fileValueSuffix)) {
+        //根据后缀,判断是否符合视频格式
+        return 'video';
+    } else if (/(.*)\.(jpg|JPG|bmp|BMP|mpg|MPG|mpeg|MPEG|tis|TIS|svg)$/.test(fileValueSuffix)) {
+        //根据后缀,判断是否符合图片格式
+        return 'image';
+    } else if (/(.*)\.(xls|XLS|xlsx|XLSX)$/.test(fileValueSuffix)) {
+        //根据后缀,判断是否符合OFFICE格式
+        return 'xls';
+    } else if (/(.*)\.(doc|DOC|docx|DOCX)$/.test(fileValueSuffix)) {
+        // 文档类型
+        return 'doc';
+    } else if (/(.*)\.(pdf|PDF)$/.test(fileValueSuffix)) {
+        // PDF
+        return 'pdf';
+    } else if (/(.*)\.(PPT|PPTX|ppt|pptx)$/.test(fileValueSuffix)) {
+        // ppt
+        return 'ppt';
+    }
+    return '';
+}
+// 传入类型返回对应的文件类型图标
+export function fileType(file: string) {
+    switch (file) {
+        case 'video':
+            return 'ele-VideoCamera';
+        case 'image':
+            return 'ele-Picture';
+        case 'xls':
+            return 'iconfont icon-excel';
+        case 'doc':
+            return 'ele-Document';
+        case 'pdf':
+            return 'iconfont icon-pdf';
+        case 'ppt':
+            return 'iconfont icon-ppt';
+        default:
+            break;
+    }
+}
+/**
+ * 常用意见
+ * @param  {string} Discriminate  甄别惯用语
+ * @param  {string} Return  退回惯用语
+ * @param  {string} Archive  归档惯用语
+ * @param  {string} Teti  特提惯用语
+ * @param  {string} Seat  坐席惯用语
+ * @param  {string} Circulation  流转惯用语
+ * @param  {string} ReturnVisit  回访惯用语
+ * @param  {string} HandleAgain  办理惯用语
+ * @param  {string} Delay  延期惯用语
+ * @param  {string} Supervise  督办惯用语
+ * @param  {string} KnowledgeLocution  知识诉求惯用语
+ */
+export const commonEeum = {
+	Discriminate: 'Discriminate', //  甄别惯用语
+	Return: 'Return', // 退回惯用语
+	Archive: 'Archive', // 归档惯用语
+	Teti: 'Teti', // 特提惯用语
+	Seat: 'Seat', // 坐席惯用语
+	Circulation: 'Circulation', // 流转惯用语
+	ReturnVisit: 'ReturnVisit', // 回访惯用语
+	HandleAgain: 'HandleAgain', // 办理惯用语
+	Delay: 'Delay', // 延期惯用语
+	Supervise: 'Supervise', // 督办惯用语
+	KnowledgeLocution: 'KnowledgeLocution', // 知识诉求惯用语
+	RestReason : 'RestReason', // 小休原因
+	Rest: 'Rest', // 小休常用意见
+};

+ 1 - 1
src/views/businessManage/extensionRequest/index.vue → src/views/business/extension/index.vue

@@ -6,7 +6,7 @@
     </div>
 </template>
 
-<script setup lang="ts" name="extensionRequest">
+<script setup lang="ts" name="extension">
 
 </script>
 

+ 3 - 16
src/views/businessManage/workOrderManage/components/Comment.vue → src/views/business/order/components/Comment.vue

@@ -1,6 +1,6 @@
 <template>
 	<div>
-		<el-drawer v-model="state.showDrawer" title="" :show-close="false" :modal="props.modal">
+		<el-drawer v-model="state.showDrawer" size="35%" title="" :show-close="false" :modal="props.modal">
 			<template #header="{ close }">
 				<div class="comments-header">
 					<div>
@@ -76,23 +76,10 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="workOrderCrculationRecord">
+<script setup lang="ts" name="orderCrculationRecord">
 import { reactive, ref } from 'vue';
 import { ElMessage, ElMessageBox } from 'element-plus';
-import { commonList, addCommon, deleteCommon } from '/@/api/businessManage/commonP';
-const summary = {
-	Discriminate: 'Discriminate', //  甄别惯用语
-	Return: 'Return', // 退回惯用语
-	Archive: 'Archive', // 归档惯用语
-	Teti: 'Teti', // 特提惯用语
-	Seat: 'Seat', // 坐席惯用语
-	Circulation: 'Circulation', // 流转惯用语
-	ReturnVisit: 'ReturnVisit', // 回访惯用语
-	HandleAgain: 'HandleAgain', // 办理惯用语
-	Delay: 'Delay', // 延期惯用语
-	Supervise: 'Supervise', // 督办惯用语
-	KnowledgeLocution: 'KnowledgeLocution', // 知识诉求惯用语
-};
+import { commonList, addCommon, deleteCommon } from '/@/api/business/commonP';
 const emit = defineEmits(['chooseComment']);
 const props = defineProps({
 	modal: {

+ 1 - 1
src/views/businessManage/workOrderManage/components/CrculationRecord.vue → src/views/business/order/components/CrculationRecord.vue

@@ -11,7 +11,7 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="workOrderCrculationRecord">
+<script setup lang="ts" name="orderCrculationRecord">
 import { reactive, ref } from 'vue';
 // import { ElMessage } from 'element-plus';
 // 定义变量内容

+ 53 - 43
src/views/businessManage/workOrderManage/components/Detail.vue → src/views/business/order/components/Detail.vue

@@ -17,37 +17,43 @@
 						<el-form label-width="100px" ref="ruleFormRef">
 							<el-row :gutter="35">
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="来源渠道"> 微信公众号 </el-form-item>
+									<el-form-item label="来源渠道"> {{ state.ruleForm.channel }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="转接来源"> 12345 </el-form-item>
+									<el-form-item label="转接来源"> {{ state.ruleForm.transferPhone }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
 									<el-form-item label="来电号码">
-										134 3562 4569
-										<el-button link type="primary" class="ml5" title="播放录音"><SvgIcon name="ele-Headset" size="16px" /></el-button>
+										{{ state.ruleForm.fromPhone }}
+										<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="服务坐席"> 1号坐席[8001] </el-form-item>
+									<el-form-item label="服务坐席"> {{ state.ruleForm.employeeName }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="来电/信人"> 张女士 </el-form-item>
+									<el-form-item label="来电/信人"> {{ state.ruleForm.fromName }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="来电/信人身份"> 市民 </el-form-item>
+									<el-form-item label="来电/信人身份"> {{ state.ruleForm.identityType }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="证件类型"> 身份证 </el-form-item>
+									<el-form-item label="证件类型"> {{ state.ruleForm.licence }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="证件号码"> 51036548199601246589</el-form-item>
+									<el-form-item label="证件号码"> {{ state.ruleForm.licenceNo }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="年龄段"> 中青年(19岁~65岁) </el-form-item>
+									<el-form-item label="年龄段"> {{ state.ruleForm.licenceNo }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="联系电话"> 156 9878 9564 </el-form-item>
+									<el-form-item label="联系电话"> {{ state.ruleForm.licenceNo }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
 									<el-form-item label="受理短信">
@@ -58,10 +64,10 @@
 									</el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="受理时间"> 2022-12-28 10:26:32 </el-form-item>
+									<el-form-item label="受理时间"> {{ state.ruleForm.licenceNo }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
-									<el-form-item label="工作单位"> 成都蜂窝科技有限公司 </el-form-item>
+									<el-form-item label="工作单位"> {{ state.ruleForm.licenceNo }} </el-form-item>
 								</el-col>
 							</el-row>
 						</el-form>
@@ -78,44 +84,45 @@
 						<el-form label-width="100px" ref="ruleFormRef">
 							<el-row :gutter="35">
 								<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-									<el-form-item label="工单标题"> 投诉xxx超市乱定价问题 <el-tag class="ml10">办理完成</el-tag> </el-form-item>
+									<el-form-item label="工单标题"> {{ state.ruleForm.title }} <el-tag class="ml10">办理完成</el-tag> </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-									<el-form-item label="工单编码"> 2022101000001【1001】 </el-form-item>
+									<el-form-item label="工单编码"> {{ state.ruleForm.no }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-									<el-form-item label="紧急程度"> 一般 </el-form-item>
+									<el-form-item label="紧急程度"> {{ state.ruleForm.emergencyLevelText }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-									<el-form-item label="受理类型"> 投诉 </el-form-item>
+									<el-form-item label="受理类型"> {{ state.ruleForm.acceptTypeText }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
 									<el-form-item label="工单类型">
-										12315市场监督管理局受理单
+										{{ state.ruleForm.orderType }}
 										<el-button link type="primary" class="ml10" @click="showExpandInfo"
 											><SvgIcon name="ele-Document" class="mr2" /> 拓展信息</el-button
 										>
 									</el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="16" :md="16" :lg="16" :xl="16">
-									<el-form-item label="热点分类"> 市场管理-物价-价格波动-生活资料价格上涨或下降-生产原料价格 </el-form-item>
+									<el-form-item label="热点分类"> {{ state.ruleForm.hotspotSpliceName }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
-									<el-form-item label="事发时间"> 2022-12-28 10:26:32 </el-form-item>
+									<el-form-item label="事发时间"> {{ state.ruleForm.incidentTime }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="16" :md="16" :lg="16" :xl="16">
-									<el-form-item label="事发地址"> 武侯区-火车南站街道火车南站西路481号 </el-form-item>
+									<el-form-item label="事发地址"> {{ state.ruleForm.licenceNo }} </el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-									<el-form-item label="是否重复"> 是 <el-button link type="primary" class="ml10"> 投诉xxx超市乱定价问题</el-button> </el-form-item>
+									<el-form-item label="是否重复">
+										{{ state.ruleForm.licenceNo }} <el-button link type="primary" class="ml10"> {{ state.ruleForm.duplicateTitle }}</el-button>
+									</el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-									<el-form-item label="推送分类"> 110 </el-form-item>
+									<el-form-item label="推送分类"> {{ state.ruleForm.pushType }} </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">
@@ -249,7 +256,7 @@
 			</template>
 		</el-dialog>
 		<!-- 处理流程 -->
-		<Process ref="processRef" />
+		<Process ref="processRef" @onSubmit="onSubmitProcess" />
 		<!-- 扩展信息 -->
 		<ExpandForm ref="ExpandFormRef" />
 		<!-- 流转记录 -->
@@ -257,32 +264,24 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="workOrderDetail">
+<script setup lang="ts" name="orderDetail">
 import { defineAsyncComponent, reactive, ref } from 'vue';
 // import { ElMessage } from 'element-plus';
 import { throttle } from '/@/utils/tools';
+import { orderDetail } from '/@/api/business/order';
 
 // 引入组件
-const ExpandForm = defineAsyncComponent(() => import('/@/views/businessManage/workOrderManage/components/Expand.vue'));
-const CrculationRecord = defineAsyncComponent(() => import('/@/views/businessManage/workOrderManage/components/CrculationRecord.vue'));
-const Process = defineAsyncComponent(() => import('/@/views/businessManage/workOrderManage/components/Process.vue'));
+const ExpandForm = defineAsyncComponent(() => import('/@/views/business/order/components/Expand.vue'));
+const CrculationRecord = defineAsyncComponent(() => import('/@/views/business/order/components/CrculationRecord.vue'));
+const Process = defineAsyncComponent(() => import('/@/views/business/order/components/Process.vue'));
+const AudioPlayer = defineAsyncComponent(() => import('/@/components/AudioPlayer/index.vue'));
 
 // 定义子组件向父组件传值/事件
 const emit = defineEmits(['updateList', 'handle']);
 // 定义变量内容
 const state = reactive<any>({
 	isShowDialog: false,
-	ruleForm: {
-		phoneNo: '', // 手机号
-		gender: 0, //性别
-		name: '', // 姓名
-		userName: '', // 用户昵称
-		orgId: '', // 组织id
-		orgCode: '', //组织code
-		staffNo: '', //工号
-		defaultTelNo: '', //默认分机
-		email: '', //邮箱
-	},
+	ruleForm: { url: '' } as any,
 	activeName: 'default',
 	tabPaneList: [
 		{
@@ -315,10 +314,17 @@ const ruleFormRef = ref();
 const processRef = ref();
 const ExpandFormRef = ref();
 const CrculationRecordRef = ref();
+const AudioPlayerRef = ref();
 // 打开弹窗
-const openDialog = () => {
+const openDialog = (val: any) => {
+	getDeail(val.id);
 	state.isShowDialog = true;
 };
+// 查看详情
+const getDeail = async (id: string) => {
+	const res: any = await orderDetail(id);
+	state.ruleForm = res.result ?? {};
+};
 // 展示扩展表单
 const showExpandInfo = () => {
 	ExpandFormRef.value.openDialog();
@@ -338,8 +344,12 @@ const onRecord = () => {
 // 新增
 const onSubmit = throttle((val: string) => {
 	// emit('handle','id')
-	processRef.value.openDialog({ id: 'id', title: val });
+	processRef.value.openDialog({id:state.ruleForm.id,title:val,start:true});
 }, 1000);
+// 流程保存
+const onSubmitProcess = () => {
+	emit('updateList');
+};
 // 暴露变量
 defineExpose({
 	openDialog,

+ 1 - 1
src/views/businessManage/workOrderManage/components/Expand.vue → src/views/business/order/components/Expand.vue

@@ -403,7 +403,7 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="workOrderDetailExpand">
+<script setup lang="ts" name="orderDetailExpand">
 import { reactive, ref } from 'vue';
 // import { ElMessage } from 'element-plus';
 

+ 773 - 0
src/views/business/order/components/ExpandForm.vue

@@ -0,0 +1,773 @@
+<template>
+	<div>
+		<el-dialog v-model="state.isShowDialog" width="80%" draggable title="拓展信息" append-to-body @closed="closed" @opened="opened">
+			<el-form :model="state.expandForm" scroll-to-error ref="expandFormRef" label-width="120px" v-loading="state.loading">
+				<el-row :gutter="20">
+					<el-col :xs="24" :sm="24" :md="8" :lg="6" :xl="6">
+						<el-form-item label="工单类型"> 12315市场监管局受理单 </el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
+						<el-form-item label="受理类型">
+							<template v-if="state.type === 5"> 举报 </template>
+							<template v-if="state.type === 6"> 投诉 </template>
+						</el-form-item>
+					</el-col>
+					<el-divider content-position="left" v-if="state.type === 5"><b class="formTitle">举报人信息</b></el-divider>
+					<el-divider content-position="left" v-if="state.type === 6"><b class="formTitle">投诉人信息</b></el-divider>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="证件类型" prop="licenceObj" :rules="[{ required: false, message: '请选择证件类型', trigger: 'change' }]">
+							<el-select
+								v-model="state.expandForm.licenceObj"
+								clearable
+								filterable
+								value-key="dicDataValue"
+								placeholder="请选择证件类型"
+								class="w100"
+								@change="(val:any)=>{state.expandForm.licenceType = val.dicDataName;
+									state.expandForm.licenceTypeCode = val.dicDataValue}"
+							>
+								<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="8" :lg="8" :xl="6">
+						<el-form-item
+							label="证件号码"
+							prop="licenceNo"
+							:rules="[
+								{ required: state.expandForm.licenceTypeCode || state.expandForm.licenceTypeCode == 0, message: '请填写证件号码', trigger: 'blur' },
+							]"
+						>
+							<el-input v-model="state.expandForm.licenceNo" placeholder="请填写证件号码" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="提供方类型" prop="identityTypeObj" :rules="[{ required: false, message: '请选择提供方类型', trigger: 'change' }]">
+							<el-select
+								v-model="state.expandForm.identityTypeObj"
+								value-key="dicDataValue"
+								clearable
+								filterable
+								placeholder="请选择提供方类型"
+								class="w100"
+								@change="(val:any)=>{state.expandForm.identityType = val.dicDataName;
+									state.expandForm.identityTypeCode = val.dicDataValue}"
+							>
+								<el-option v-for="item in state.identityTypeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="提供方身份" prop="identityObj" :rules="[{ required: false, message: '请选择提供方身份', trigger: 'change' }]">
+							<el-select
+								v-model="state.expandForm.identityObj"
+								value-key="dicDataValue"
+								filterable
+								clearable
+								placeholder="请选择提供方身份"
+								class="w100"
+								@change="(val:any)=>{state.expandForm.identity = val.dicDataName;
+									state.expandForm.identityCode = val.dicDataValue}"
+							>
+								<el-option v-for="item in state.identityOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="国籍/地区" prop="nationalityObj" :rules="[{ required: false, message: '请选择国籍/地区', trigger: 'change' }]">
+							<el-select
+								v-model="state.expandForm.nationalityObj"
+								filterable
+								clearable
+								placeholder="请选择国籍/地区"
+								class="w100"
+								value-key="dicDataValue"
+								@change="(val:any)=>{state.expandForm.nationality = val.dicDataName;
+									state.expandForm.nationalityCode = val.dicDataValue}"
+							>
+								<el-option v-for="item in state.nationalityOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="民族" prop="nationObj" :rules="[{ required: false, message: '请选择民族', trigger: 'change' }]">
+							<el-select
+								v-model="state.expandForm.nationObj"
+								value-key="dicDataValue"
+								clearable
+								filterable
+								placeholder="请选择民族"
+								class="w100"
+								@change="(val:any)=>{state.expandForm.nation = val.dicDataName;
+									state.expandForm.nationCode = val.dicDataValue}"
+							>
+								<el-option v-for="item in state.nationOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="邮政编码" prop="postalCode" :rules="[{ required: false, message: '请填写邮政编码', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.postalCode" placeholder="请填写邮政编码" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="邮箱" prop="email" :rules="[{ required: false, message: '请填写邮箱', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.email" placeholder="请填写邮箱" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="其他联系方式" prop="otherContact" :rules="[{ required: false, message: '请填写其他联系方式', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.otherContact" placeholder="请填写其他联系方式" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-divider content-position="left" v-if="state.type === 5"><b class="formTitle">举报对象信息</b></el-divider>
+					<el-divider content-position="left" v-if="state.type === 6"><b class="formTitle">投诉对象信息</b></el-divider>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="企业名称" prop="enterpriseName" :rules="[{ required: true, message: '请填写企业名称', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.enterpriseName" placeholder="请填写企业名称" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item
+							label="统一社会信用代码"
+							prop="unifiedSocialCreditCode"
+							:rules="[{ required: false, message: '请填写统一社会信用代码', trigger: 'blur' }]"
+						>
+							<el-input v-model="state.expandForm.unifiedSocialCreditCode" placeholder="请填写统一社会信用代码" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="注册地址" prop="registerAddress" :rules="[{ required: true, message: '请填写注册地址', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.registerAddress" placeholder="请填写注册地址" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="注册号" prop="registerNumber" :rules="[{ required: false, message: '请填写注册号', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.registerNumber" placeholder="请填写注册号" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="企业联系人" prop="enterpriseContact" :rules="[{ required: false, message: '请填写企业联系人', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.enterpriseContact" placeholder="请填写企业联系人" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="市场主体类型" prop="marketTypeCode" :rules="[{ required: false, message: '请选择市场主体类型', trigger: 'change' }]">
+							<el-cascader
+								:options="state.marketTypeOptions"
+								filterable
+								:props="{ value: 'dicDataValue', label: 'dicDataName', emitPath: false }"
+								placeholder="请选择市场主体类型"
+								clearable
+								class="w100"
+								v-model="state.expandForm.marketTypeCode"
+								ref="marketTypeRef"
+								@change="changeMarketType"
+							>
+								<template #default="{ node, data }">
+									<span>{{ data.dicDataName }}</span>
+									<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+								</template>
+							</el-cascader>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="行业分类" prop="industryClassifyCode" :rules="[{ required: false, message: '请选择行业分类', trigger: 'blur' }]">
+							<el-cascader
+								:options="state.industryClassifyOptions"
+								filterable
+								:props="{ value: 'dicDataValue', label: 'dicDataName', emitPath: false }"
+								placeholder="请选择行业分类"
+								clearable
+								class="w100"
+								v-model="state.expandForm.industryClassifyCode"
+								ref="industryClassifyRef"
+								@change="changeIndustryClassify"
+							>
+								<template #default="{ node, data }">
+									<span>{{ data.dicDataName }}</span>
+									<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+								</template>
+							</el-cascader>
+						</el-form-item>
+					</el-col>
+					<el-divider content-position="left" v-if="state.type === 5"><b class="formTitle">举报详情</b></el-divider>
+					<el-divider content-position="left" v-if="state.type === 6"><b class="formTitle">投诉详情</b></el-divider>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="商品分类/品牌" prop="brandCode" :rules="[{ required: true, message: '请选择商品分类/品牌', trigger: 'change' }]">
+							<el-cascader
+								:options="state.brandOptions"
+								filterable
+								:props="{ value: 'dicDataValue', label: 'dicDataName', emitPath: false }"
+								placeholder="请选择商品分类/品牌"
+								clearable
+								class="w100"
+								v-model="state.expandForm.brandCode"
+								ref="brandRef"
+								@change="changeBrand"
+							>
+								<template #default="{ node, data }">
+									<span>{{ data.dicDataName }}</span>
+									<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+								</template>
+							</el-cascader>
+						</el-form-item>
+					</el-col>
+					<!-- 只能填写数字,且只能填写非负数 -->
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="消费金额" prop="amount" :rules="[{ required: true, message: '请填写消费金额', trigger: 'blur' }]">
+							<!-- <el-input v-model="state.expandForm.amount" placeholder="请填写消费金额" clearable> </el-input> -->
+							<el-input-number v-model="state.expandForm.amount" :min="0" placeholder="请填写消费金额" class="w100" />
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="客体类别" prop="objectClassifyCode" :rules="[{ required: true, message: '请选择客体类别', trigger: 'change' }]">
+							<el-cascader
+								:options="state.objectClassifyOptions"
+								filterable
+								:props="{ value: 'dicDataValue', label: 'dicDataName', emitPath: false }"
+								placeholder="请选择客体类别"
+								clearable
+								class="w100"
+								v-model="state.expandForm.objectClassifyCode"
+								ref="objectClassifyRef"
+								@change="changeObjectClassify"
+							>
+								<template #default="{ node, data }">
+									<span>{{ data.dicDataName }}</span>
+									<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+								</template>
+							</el-cascader>
+						</el-form-item>
+					</el-col>
+					<!-- 举报才展示 -->
+					<template v-if="state.type === 5">
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+							<el-form-item
+								label="举报问题类别"
+								prop="reportClassifyCode"
+								:rules="[{ required: true, message: '请选择举报问题类别', trigger: 'change' }]"
+							>
+								<el-cascader
+									:options="state.reportClassifyOptions"
+									filterable
+									:props="{ value: 'dicDataValue', label: 'dicDataName', emitPath: false }"
+									placeholder="请选择举报问题类别"
+									clearable
+									class="w100"
+									v-model="state.expandForm.reportClassifyCode"
+									ref="problemCascaderRef"
+									@change="changeProblems"
+								>
+									<template #default="{ node, data }">
+										<span>{{ data.dicDataName }}</span>
+										<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+									</template>
+								</el-cascader>
+							</el-form-item>
+						</el-col>
+					</template>
+					<!-- 投诉才展示 -->
+					<template v-if="state.type === 6">
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+							<el-form-item
+								label="投诉问题类别"
+								prop="complainClassifyCode"
+								:rules="[{ required: true, message: '请选择投诉问题类别', trigger: 'change' }]"
+							>
+								<el-cascader
+									:options="state.complainClassifyOptions"
+									filterable
+									:props="{ value: 'dicDataValue', label: 'dicDataName', emitPath: false }"
+									placeholder="请选择投诉问题类别"
+									clearable
+									class="w100"
+									v-model="state.expandForm.complainClassifyCode"
+									ref="problemCascaderRef"
+									@change="changeProblems"
+								>
+									<template #default="{ node, data }">
+										<span>{{ data.dicDataName }}</span>
+										<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+									</template>
+								</el-cascader>
+							</el-form-item>
+						</el-col>
+					</template>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6" v-if="state.type === 6">
+						<el-form-item label="争议发生时间" prop="occurrenceTime" :rules="[{ required: true, message: '请选择争议发生时间', trigger: 'change' }]">
+							<el-date-picker
+								v-model="state.expandForm.occurrenceTime"
+								type="datetime"
+								placeholder="请选择争议发生时间"
+								format="YYYY-MM-DD HH:mm:ss"
+								class="w100"
+								clearable
+							/>
+							<!-- value-format="YYYY-MM-DD HH:mm:ss" -->
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="销售方式" prop="salesModeObj" :rules="[{ required: true, message: '请选择销售方式', trigger: 'change' }]">
+							<el-select
+								v-model="state.expandForm.salesModeObj"
+								value-key="dicDataValue"
+								placeholder="请选择销售方式"
+								clearable
+								class="w100"
+								@change="(val:any)=>{state.expandForm.salesMode = val.dicDataName;
+									state.expandForm.salesModeCode = val.dicDataValue}"
+							>
+								<el-option v-for="item in state.salesModeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<!-- 售方式为“网购”时展示该字段且必填 -->
+					<template v-if="state.type === 5 && state.expandForm.salesModeCode === '114'">
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+							<el-form-item label="举报目标" prop="reportTargetObj" :rules="[{ required: true, message: '请选择举报目标', trigger: 'blur' }]">
+								<el-select
+									v-model="state.expandForm.reportTargetObj"
+									placeholder="请选择举报目标"
+									class="w100"
+									clearable
+									value-key="dicDataValue"
+									@change="(val:any)=>{state.expandForm.reportTarget = val.dicDataName;
+									state.expandForm.reportTargetCode = val.dicDataValue}"
+								>
+									<el-option v-for="item in state.affairTargetOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</template>
+					<!-- 销售方式为“网购”时展示该字段且必填 -->
+					<template v-if="state.type === 6 && state.expandForm.salesModeCode === '114'">
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+							<el-form-item label="投诉目标" prop="complainTargetObj" :rules="[{ required: true, message: '请选择投诉目标', trigger: 'blur' }]">
+								<el-select
+									v-model="state.expandForm.complainTargetObj"
+									placeholder="请选择投诉目标"
+									class="w100"
+									clearable
+									value-key="dicDataValue"
+									@change="(val:any)=>{state.expandForm.complainTarget = val.dicDataName;
+									state.expandForm.complainTargetCode = val.dicDataValue}"
+								>
+									<el-option v-for="item in state.affairTargetOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</template>
+
+					<!-- 销售方式为“网购”时展示该字段且必填,支持模糊搜索,支持分级模式选择 -->
+					<template v-if="state.expandForm.salesModeCode === '114'">
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+							<el-form-item label="电商平台" prop="eCommercePlatform" :rules="[{ required: true, message: '请选择电商平台', trigger: 'blur' }]">
+								<el-cascader
+									:options="state.eCommercePlatformOptions"
+									filterable
+									:props="{ value: 'dicDataValue', label: 'dicDataName', emitPath: false }"
+									placeholder="请选择电商平台"
+									clearable
+									class="w100"
+									v-model="state.expandForm.eCommercePlatform"
+									ref="eCommercePlatformRef"
+									@change="changeECommercePlatform"
+								>
+									<template #default="{ node, data }">
+										<span>{{ data.dicDataName }}</span>
+										<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+									</template>
+								</el-cascader>
+							</el-form-item>
+						</el-col>
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6" v-if="state.expandForm.salesModeCode === '114'">
+							<el-form-item label="订单号" prop="externalOrderNo" :rules="[{ required: true, message: '请填写订单号', trigger: 'blur' }]">
+								<el-input v-model="state.expandForm.externalOrderNo" placeholder="请填写订单号" clearable> </el-input>
+							</el-form-item>
+						</el-col>
+					</template>
+
+					<!-- 销售方式为“现场”时必填,先选择经营地址所属行政区划,后填写详细地址,行政区划展示本市所有区县名称即可 举报并且销售方式为现场才会有经营地址 -->
+					<template v-if="state.type === 6 && state.expandForm.salesModeCode === '19'">
+						<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
+							<el-cascader
+								:options="state.areaOptions"
+								filterable
+								:props="{ value: 'id', label: 'areaName', emitPath: false }"
+								placeholder="请选择经营地址"
+								clearable
+								class="w100"
+								v-model="state.ruleForm.bussinessArea"
+								ref="areaRef"
+								@change="changeArea"
+							>
+								<template #default="{ node, data }">
+									<span>{{ data.areaName }}</span>
+									<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+								</template>
+							</el-cascader>
+						</el-col>
+						<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
+							<el-form-item
+								label="经营详细地址"
+								prop="bussinessAddress"
+								:rules="[{ required: true, message: '请填写经营详细地址', trigger: 'blur' }]"
+							>
+								<el-input v-model="state.expandForm.bussinessAddress" placeholder="请填写经营详细地址" clearable> </el-input>
+							</el-form-item>
+						</el-col>
+					</template>
+
+					<!-- 销售方式为“电视购物”“电话购物”“邮购”时展示该字段,且必填
+						电视购物:请填写购物的电视频道,电话购物:请填写商品销售者的热线号码,邮购:请填写宣传商品的邮政公司或来件地址 -->
+					<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6" v-if="state.expandForm.salesModeCode === '19'">
+						<el-form-item
+							label="具体渠道"
+							prop="channel"
+							:rules="[{ required: true, message: '电视频道/热线号码/商品邮政公司或来件地址', trigger: 'blur' }]"
+						>
+							<el-input v-model="state.expandForm.channel" placeholder="电视频道/热线号码/商品邮政公司或来件地址" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<!-- 投诉问题类别”为“专利”时展示该字段 -->
+					<template v-if="state.isPatent">
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+							<el-form-item label="专利权人" prop="patentee" :rules="[{ required: false, message: '请填写专利权人', trigger: 'blur' }]">
+								<el-input v-model="state.expandForm.patentee" placeholder="请填写专利权人" clearable> </el-input>
+							</el-form-item>
+						</el-col>
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+							<el-form-item label="发明名称" prop="patentName" :rules="[{ required: false, message: '请填写发明名称', trigger: 'blur' }]">
+								<el-input v-model="state.expandForm.patentName" placeholder="请填发明名称" clearable> </el-input>
+							</el-form-item>
+						</el-col>
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+							<el-form-item label="专利类型" prop="patentTypeObj" :rules="[{ required: false, message: '请选择专利类型', trigger: 'blur' }]">
+								<el-select
+									v-model="state.expandForm.patentTypeObj"
+									value-key="dicDataValue"
+									clearable
+									filterable
+									placeholder="请选择专利类型"
+									class="w100"
+									@change="(val:any)=>{state.expandForm.patentType = val.dicDataName;
+									state.expandForm.patentTypeCode = val.dicDataValue}"
+								>
+									<el-option v-for="item in state.patentTypeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+							<el-form-item label="专利号" prop="patentNo" :rules="[{ required: false, message: '请填写专利号', trigger: 'blur' }]">
+								<el-input v-model="state.expandForm.patentNo" placeholder="请填写专利号" clearable> </el-input>
+							</el-form-item>
+						</el-col>
+					</template>
+
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="产品名称" prop="productName" :rules="[{ required: false, message: '请填写产品名称', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.productName" placeholder="请填写产品名称" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="批准文号" prop="approvalNumber" :rules="[{ required: false, message: '请填写批准文号', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.approvalNumber" placeholder="请填写批准文号" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="产品批号" prop="productBatchNo" :rules="[{ required: false, message: '请填写产品批号', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.productBatchNo" placeholder="请填写产品批号" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="产品规格" prop="productStandard" :rules="[{ required: false, message: '请填写产品规格', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.productStandard" placeholder="请填写产品规格" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="产品有效期" prop="productExpiredTime" :rules="[{ required: false, message: '请选择产品有效期', trigger: 'change' }]">
+							<el-date-picker
+								v-model="state.expandForm.productExpiredTime"
+								type="datetime"
+								placeholder="请选择产品有效期"
+								format="YYYY-MM-DD HH:mm:ss"
+								class="w100"
+							/>
+							<!-- value-format="YYYY-MM-DD HH:mm:ss" -->
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="生产厂家" prop="manufacturer" :rules="[{ required: false, message: '请填写生产厂家', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.manufacturer" placeholder="请填写生产厂家" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="销售企业" prop="salesEnterprise" :rules="[{ required: false, message: '请填写销售企业', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.salesEnterprise" placeholder="请填写销售企业" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
+						<el-form-item label="消费者地址" prop="consumerAddress" :rules="[{ required: false, message: '请填写消费者地址', trigger: 'blur' }]">
+							<el-input v-model="state.expandForm.consumerAddress" placeholder="请填写消费者地址" clearable> </el-input>
+						</el-form-item>
+					</el-col>
+					<!-- 投诉才展示 -->
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" v-if="state.type === 6">
+						<el-form-item label="诉求" prop="complainTypes" :rules="[{ required: false, message: '请选择诉求', trigger: 'change' }]">
+							<el-checkbox-group v-model="state.expandForm.complainTypes">
+								<el-checkbox v-for="item in state.complainTypeOptions" :key="item.key" :label="item.key">{{ item.value }}</el-checkbox>
+							</el-checkbox-group>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="state.isShowDialog = false" class="default-button">取 消</el-button>
+					<el-button type="primary" @click="saveExpandForm">保 存</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script setup lang="ts" name="oderExpandForm">
+import { reactive, ref, onMounted, nextTick } from 'vue';
+import { useRoute } from 'vue-router';
+import { orderBaseExt, orderDetail } from '/@/api/business/order';
+import { treeArea } from '/@/api/business/commonP';
+import { ElMessage } from 'element-plus';
+// import { ElMessage } from 'element-plus';
+const emit = defineEmits(['saveExpandForm']);
+// 定义变量内容
+const state = reactive<any>({
+	isShowDialog: false,
+	type: 5, // 5: 举报 6: 投诉
+	expandForm: {},
+	licenceTypeOptions: [], //证件类型
+	identityTypeOptions: [], //提供方类型
+	identityOptions: [], //提供方身份
+	nationalityOptions: [], //国籍/地区
+	nationOptions: [], //民族
+	marketTypeOptions: [], //市场主体类型
+	industryClassifyOptions: [], //行业分类
+	brandOptions: [], //商品分类/品牌
+	objectClassifyOptions: [], //客体类别
+	complainClassifyOptions: [], //投诉问题类别
+	reportClassifyOptions: [], //举报问题类别
+	salesModeOptions: [], //销售方式
+	affairTargetOptions: [], //举报 / 投诉目标
+	eCommercePlatformOptions: [], //电商平台
+	patentTypeOptions: [], //专利类型
+	complainTypeOptions: [], // 诉求列表
+	areaOptions: [], //省市区
+	isPatent: false, // 举报或者投诉问题类别为专利
+	validated: false, // 是否验证通过
+	isvalidate: false,
+});
+const expandFormRef = ref();
+const route = useRoute();
+/**
+ * @description: 打开弹窗
+ * @param {number} type  5: 举报 6: 投诉
+ * @return {*}
+ */
+const openDialog = async (type: any, isvalidate?: boolean) => {
+	state.type = type;
+	state.isvalidate = isvalidate;
+	state.isShowDialog = true;
+};
+// 打开表单如果需要立即校验
+const opened = () => {
+	if (state.isvalidate) {
+		// 如果需要验证
+		ElMessage.warning('请确认扩展表单信息')
+		closed();
+	} else {
+		expandFormRef.value.clearValidate();
+	}
+};
+// 弹窗关闭时校验一次表单
+const closed = () => {
+	expandFormRef.value.validate((valid: boolean) => {
+		state.validated = valid;
+	});
+};
+// 选择举报或者投诉问题目
+const problemCascaderRef = ref();
+const changeProblems = () => {
+	let currentNode = problemCascaderRef.value.getCheckedNodes();
+	if (currentNode[0].parent?.value === '26') {
+		// 专利code为26
+		state.isPatent = true;
+	} else {
+		state.isPatent = false;
+	}
+	if (state.type == 5) {
+		//举报
+		state.expandForm.reportClassify = currentNode[0].label;
+	} else if (state.type == 6) {
+		// 投诉
+		state.expandForm.complainClassify = currentNode[0].label;
+	}
+};
+// 选择市场主体类型
+const marketTypeRef = ref();
+const changeMarketType = () => {
+	let currentNode = marketTypeRef.value.getCheckedNodes();
+	state.expandForm.marketType = currentNode[0].label;
+};
+// 选择行业分类
+const industryClassifyRef = ref();
+const changeIndustryClassify = () => {
+	let currentNode = industryClassifyRef.value.getCheckedNodes();
+	state.expandForm.industryClassify = currentNode[0].label;
+};
+// 选择商品分类/品牌
+const brandRef = ref();
+const changeBrand = () => {
+	let currentNode = brandRef.value.getCheckedNodes();
+	state.expandForm.brand = currentNode[0].label;
+};
+// 选择客体类别
+const objectClassifyRef = ref();
+const changeObjectClassify = () => {
+	let currentNode = objectClassifyRef.value.getCheckedNodes();
+	state.expandForm.objectClassify = currentNode[0].label;
+};
+// 电商平台
+const eCommercePlatformRef = ref();
+const changeECommercePlatform = () => {
+	let currentNode = eCommercePlatformRef.value.getCheckedNodes();
+	state.expandForm.objectClassify = currentNode[0].label;
+};
+// 省市区选择
+const areaRef = ref();
+const changeArea = () => {
+	const currentNode = areaRef.value.getCheckedNodes();
+	state.expandForm.province = currentNode[0].pathLabels[0];
+	state.expandForm.city = currentNode[0].pathLabels[1];
+	state.expandForm.county = currentNode[0].pathLabels[2];
+};
+// 保存拓展表单
+const saveExpandForm = () => {
+	expandFormRef.value.validate((valid: boolean) => {
+		state.validated = valid;
+		if (valid) {
+			let submitObj = JSON.parse(JSON.stringify(state.expandForm));
+			Reflect.deleteProperty(submitObj, 'licenceObj'); // 删除无用的参数
+			Reflect.deleteProperty(submitObj, 'identityTypeObj'); // 删除无用的参数
+			Reflect.deleteProperty(submitObj, 'identityObj'); // 删除无用的参数
+			Reflect.deleteProperty(submitObj, 'nationalityObj'); // 删除无用的参数
+			Reflect.deleteProperty(submitObj, 'nationObj'); // 删除无用的参数
+			Reflect.deleteProperty(submitObj, 'salesModeObj'); // 删除无用的参数
+			Reflect.deleteProperty(submitObj, 'patentTypeObj'); // 删除无用的参数
+			Reflect.deleteProperty(submitObj, 'complainTargetObj'); // 删除无用的参数
+			Reflect.deleteProperty(submitObj, 'reportTargetObj'); // 删除无用的参数
+			emit('saveExpandForm', submitObj);
+			closeDialog();
+		} else {
+			return false;
+		}
+	});
+};
+
+onMounted(async () => {
+	state.loading = true;
+	const res: any = await orderBaseExt(); //基础数据
+	const area: any = await treeArea();
+	state.licenceTypeOptions = res.result.licenceTypeOptions ?? []; // 证件类型
+	state.identityTypeOptions = res.result.identityTypeOptions ?? []; // 提供方类型
+	state.identityOptions = res.result.identityOptions ?? []; // 提供方身份
+	state.nationalityOptions = res.result.nationalityOptions ?? []; // 国籍/地区
+	state.nationOptions = res.result.nationOptions ?? []; // 民族
+	state.marketTypeOptions = res.result.marketTypeOptions ?? []; // 市场主体类型
+	state.eCommercePlatformOptions = res.result.eCommercePlatformOptions ?? []; // 电商平台
+	state.industryClassifyOptions = res.result.industryClassifyOptions ?? []; // 行业分类
+	state.brandOptions = res.result.brandOptions ?? []; // 商品分类/品牌
+	state.objectClassifyOptions = res.result.objectClassifyOptions ?? []; // 客体类别
+	state.complainClassifyOptions = res.result.complainClassifyOptions ?? []; // 投诉问题类别
+	state.salesModeOptions = res.result.salesModeOptions ?? []; // 销售方式
+	state.affairTargetOptions = res.result.affairTargetOptions ?? []; // /举报 / 投诉目标
+	state.reportClassifyOptions = res.result.reportClassifyOptions ?? []; // 举报问题类别
+	state.complainTypeOptions = res.result.complainTypeOptions ?? []; // 诉求列表
+	state.patentTypeOptions = res.result.patentTypeOptions ?? []; // 专利类型
+	state.loading = false;
+	state.areaOptions = area.result ?? []; //省市区数据
+	nextTick(async () => {
+		if (route.params.id) {
+			// 修改 将数据填入表单组件
+			const response: any = await orderDetail(route.params.id);
+			if (response.result.acceptType === 5) {
+				// 举报
+				state.expandForm = response.result.orderReport;
+			} else if (response.result.acceptType === 6) {
+				// 投诉
+				state.expandForm = response.result.orderComplain;
+			}
+			state.expandForm.licenceObj = {
+				//证件类型
+				dicDataValue: state.expandForm.licenceTypeCode,
+				dicDataName: state.expandForm.licenceType,
+			};
+			state.expandForm.identityTypeObj = {
+				//提供方类型
+				dicDataValue: state.expandForm.identityTypeCode,
+				dicDataName: state.expandForm.identityType,
+			};
+			state.expandForm.identityObj = {
+				//提供方身份
+				dicDataValue: state.expandForm.identityCode,
+				dicDataName: state.expandForm.identity,
+			};
+			state.expandForm.nationalityObj = {
+				//国籍/地区
+				dicDataValue: state.expandForm.nationalityCode,
+				dicDataName: state.expandForm.nationality,
+			};
+			state.expandForm.nationObj = {
+				//民族
+				dicDataValue: state.expandForm.nationCode,
+				dicDataName: state.expandForm.nation,
+			};
+			state.expandForm.salesModeObj = {
+				//销售方式
+				dicDataValue: state.expandForm.salesModeCode,
+				dicDataName: state.expandForm.salesMode,
+			};
+			state.expandForm.complainTargetObj = {
+				//投诉目标
+				dicDataValue: state.expandForm.complainTargetCode,
+				dicDataName: state.expandForm.complainTarget,
+			};
+			state.expandForm.reportTargetObj = {
+				//举报目标
+				dicDataValue: state.expandForm.reportTargetCode,
+				dicDataName: state.expandForm.reportTarget,
+			};
+			if (state.expandForm.patentTypeCode) {
+				//专利类型
+				state.expandForm.patentTypeObj = {
+					dicDataValue: state.expandForm.patentTypeCode,
+					dicDataName: state.expandForm.patentType,
+				};
+			}
+		}
+	});
+});
+
+// 关闭弹窗
+const closeDialog = () => {
+	state.isShowDialog = false;
+};
+// 暴露变量
+defineExpose({
+	openDialog,
+	closeDialog,
+	closed,
+	state,
+});
+</script>
+<style lang="scss" scoped></style>

+ 36 - 29
src/views/businessManage/workOrderManage/components/History.vue → src/views/business/order/components/History.vue

@@ -13,21 +13,24 @@
 						<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
 					</el-form-item>
 				</el-form>
-				<el-table :data="state.tableData">
+				<el-table :data="state.tableData" @current-change="handleSelectionChange">
 					<el-table-column prop="phoneNo" label="重复件" width="70">
 						<template #default="scope">
-							<el-radio v-model="state.tableRadio" @change="handleSelectionChange(scope.row)"></el-radio>
+							<el-radio v-model="state.tableRadio" :label="scope.row.id" @change="handleRowChange(scope.row)">&nbsp;</el-radio>
 						</template>
 					</el-table-column>
-					<el-table-column type="index" width="60" label="序号" />
-					<el-table-column prop="phoneNo" label="工单标题" show-overflow-tooltip> </el-table-column>
-					<el-table-column prop="phoneNo" label="热点分类" show-overflow-tooltip> </el-table-column>
-					<el-table-column prop="phoneNo" label="工单编码" show-overflow-tooltip> </el-table-column>
-					<el-table-column prop="phoneNo" label="当前环节" show-overflow-tooltip></el-table-column>
-					<el-table-column prop="phoneNo" label="状态" width="70" fixed="right" align="center">
+					<el-table-column prop="phoneNo" label="工单标题" show-overflow-tooltip>
+						<template #default="scope">
+							<span style="color: var(--el-color-primary)">{{ scope.row.title }}</span>
+						</template>
+					</el-table-column>
+					<el-table-column prop="hotspot" label="热点分类" show-overflow-tooltip> </el-table-column>
+					<el-table-column prop="no" label="工单编码" show-overflow-tooltip> </el-table-column>
+					<el-table-column prop="currentStepName" label="当前环节" show-overflow-tooltip></el-table-column>
+					<el-table-column prop="statusText" label="状态" width="70" fixed="right" align="center">
 						<template #default="scope">
 							<el-button text type="primary">
-								{{ scope.row.phoneNo }}
+								{{ scope.row.statusText }}
 							</el-button>
 						</template>
 					</el-table-column>
@@ -53,10 +56,10 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="workOrderHistory">
+<script setup lang="ts" name="orderHistory">
 import { reactive, ref } from 'vue';
 import type { FormInstance } from 'element-plus';
-import { historyOrder } from '/@/api/businessManage/workOrderManage';
+import { historyOrder } from '/@/api/business/order';
 // import { ElMessage } from 'element-plus';
 const emit = defineEmits(['saveSlect']);
 // 定义变量内容
@@ -70,12 +73,18 @@ const state = reactive<any>({
 	tableData: [],
 	total: 0,
 	loading: false,
-	tableRadio:null as any
+	tableRadio: null as any,
+	selectRow: null as any,
 });
 const ruleFormRef = ref();
 // 打开弹窗
-const openDialog = () => {
+const openDialog = (row: any) => {
 	getList();
+	if (row) {
+		state.tableRadio = row;
+	}else{
+		state.tableRadio = '';
+	}
 	state.isShowDialog = true;
 };
 const dialogRef = ref();
@@ -99,27 +108,27 @@ const getList = () => {
 	state.loading = true;
 	historyOrder(state.queryParams)
 		.then((response: any) => {
-			// state.tableData = response?.result.items ?? [];
-			state.tableData = [
-				{
-					phoneNo: 12321,
-				}
-			];
+			state.tableData = response?.result.items ?? [];
 			state.total = response?.result.total;
-			setTimeout(() => {
-				state.loading = false;
-			}, 300);
+			state.loading = false;
 		})
 		.catch(() => {
 			state.loading = false;
 		});
 };
-const handleSelectionChange = (row:any)=>{
-	console.log(row,'handleSelectionChange')
-}
+const handleSelectionChange = (row: any) => {
+	if (row) {
+		state.tableRadio = row.id;
+		state.selectRow = row;
+	}
+};
+const handleRowChange = (row: any) => {
+	state.tableRadio = row.id;
+	state.selectRow = row;
+};
 // 确定选择历史工单
 const selecConfrim = () => {
-	emit('saveSlect');
+	emit('saveSlect', state.selectRow);
 };
 // 暴露变量
 defineExpose({
@@ -127,6 +136,4 @@ defineExpose({
 	closeDialog,
 });
 </script>
-<style lang="scss" scoped>
-
-</style>
+<style lang="scss" scoped></style>

+ 127 - 106
src/views/businessManage/workOrderManage/components/Process.vue → src/views/business/order/components/Process.vue

@@ -7,39 +7,61 @@
 			ref="dialogRef"
 			@mouseup="mouseup"
 			:style="'transform: ' + state.trasform + ';'"
-			width="60%"
 			append-to-body
 		>
 			<el-form :model="state.ruleForm" label-width="90px" ref="ruleFormRef">
 				<el-row :gutter="35">
-					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-						<el-form-item label="下一环节" prop="name" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
-							<el-select v-model="state.ruleForm.gender" placeholder="请选择下一环节" class="w100">
-								<el-option v-for="item in state.genderList" :key="item.key" :label="item.value" :value="item.key" />
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
+							<el-select v-model="state.ruleForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
+								<el-option v-for="item in state.nextStepOptions" :key="item.code" :label="item.name" :value="item.code" />
 							</el-select>
 						</el-form-item>
 					</el-col>
-					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-						<el-form-item label="处理人" prop="userName" :rules="[{ required: true, message: '请选择处理人', trigger: 'change' }]">
-							<el-select v-model="state.ruleForm.gender" placeholder="请选择处理人" class="w100">
-								<el-option v-for="item in state.genderList" :key="item.key" :label="item.value" :value="item.key" />
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="处理人" prop="nextHandlers" :rules="[{ required: false, message: '请选择处理人', trigger: 'change' }]">
+							<el-select
+								v-model="state.ruleForm.nextHandlers"
+								multiple
+								filterable
+								placeholder="请选择处理人"
+								class="w100"
+								@change="selectHanders"
+								value-key="key"
+								clearable
+							>
+								<el-option v-for="item in state.handerOptions" :key="item.key" :label="item.value" :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="nextMainHandler"
+							multiple
+							filterable
+							clearable
+							:rules="[{ required: false, message: '请选择主办', trigger: 'change' }]"
+						>
+							<el-select v-model="state.ruleForm.nextMainHandler" placeholder="请选择主办" class="w100">
+								<el-option v-for="item in state.handerOptions" :key="item.key" :label="item.value" :value="item.key" />
 							</el-select>
 						</el-form-item>
 					</el-col>
-					<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
-						<el-form-item label="" prop="phoneNo">
-							<el-checkbox v-model="state.ruleForm.phoneNo" label="短信通知" />
+					<el-col :xs="24" :sm="12" :md="8" :lg="12" :xl="12">
+						<el-form-item label="" prop="acceptSms">
+							<el-checkbox v-model="state.ruleForm.acceptSms" label="短信通知" />
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 						<el-form-item
 							:label="state.title + '意见'"
 							class="textarea"
-							prop="content"
+							prop="opinion"
 							:rules="[{ required: true, message: '请填写常用意见', trigger: 'blur' }]"
 						>
 							<el-input
-								v-model="state.ruleForm.content"
+								v-model="state.ruleForm.opinion"
 								type="textarea"
 								:autosize="{ minRows: 10, maxRows: 10 }"
 								placeholder="请填写常用意见"
@@ -47,13 +69,13 @@
 							>
 							</el-input>
 							<span class="bttons">
-								<el-button @click="showComents" class="default-button" :loading="loading">常用意见</el-button>
-								<el-button type="primary" @click="onAddComments" :loading="loading">添加到常用意见</el-button>
+								<el-button @click="showComents" class="default-button" :loading="state.loading">常用意见</el-button>
+								<el-button type="primary" @click="onAddComments" :loading="state.loading">添加到常用意见</el-button>
 							</span>
 						</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' }]">
+						<el-form-item label="附件" prop="additions" :rules="[{ required: false, message: '请填写诉求内容', trigger: 'change' }]">
 							<el-upload
 								v-model:file-list="state.fileList"
 								class="upload-demo w100"
@@ -81,8 +103,8 @@
 			<template #footer>
 				<span class="dialog-footer">
 					<el-button @click="onCancel" class="default-button">取 消</el-button>
-					<el-button type="primary" @click="onSave" :loading="loading">保 存</el-button>
-					<el-button type="primary" @click="onSubmit" :loading="loading">提 交</el-button>
+					<!-- <el-button type="primary" @click="onSave" :loading="loading">保 存</el-button> -->
+					<el-button type="primary" @click="onSubmit" :loading="state.loading">提 交</el-button>
 				</span>
 			</template>
 			<!-- 常用意见管理 -->
@@ -91,45 +113,76 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="workOrderProcess">
+<script setup lang="ts" name="orderProcess">
 import { defineAsyncComponent, reactive, ref } from 'vue';
 import { ElMessage, ElMessageBox } from 'element-plus';
 import type { UploadProps } from 'element-plus';
-import { throttle } from '/@/utils/tools';
-import { addCommon } from '/@/api/businessManage/commonP';
+import { useRouter,useRoute } from 'vue-router';
+import mittBus from '/@/utils/mitt';
+import Cookies from 'js-cookie';
+import { throttle, checkFile, fileType, commonEeum } from '/@/utils/tools';
+import { addCommon } from '/@/api/business/commonP';
+import { OrderFlowParams, orderStartflow } from '/@/api/business/order';
 
 // 引入组件
-const Comment = defineAsyncComponent(() => import('/@/views/businessManage/workOrderManage/components/Comment.vue'));
+const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Comment.vue'));
 // 定义子组件向父组件传值/事件
-const emit = defineEmits(['updateList']);
+const emit = defineEmits(['onSubmit']);
 // 定义变量内容
 const state = reactive<any>({
 	isShowDialog: false,
 	title: '提交',
 	ruleForm: {
-		phoneNo: '', // 手机号
-		gender: '', //性别
-		remark: '',
-		content: '',
+		nextStepCode: '',
+		nextHandlers: [],
+		nextMainHandler: '',
+		acceptSms: false,
 	},
-	orgData: [], //可用组织
-	telsList: [], // 所有分机
-	genderList: [], // 性别列表
+	nextStepOptions: [], // 下一节点
+	handerOptions: [], // 处理人
 	trasform: 'translate(0px, 0px)',
 	fileList: [],
+	loading: false,
+	isStartFlow: false, //是否开启流程
+	orderId: '', //工单id
 });
-let loading = ref<boolean>(false);
 const ruleFormRef = ref();
 const CommentRef = ref();
+const dialogRef = ref();
+const uploadListRef = ref();
+const router = useRouter();
+const route = useRoute();
 // 打开弹窗
-const openDialog = (val: any) => {
+const openDialog = async (val: any) => {
+	console.log(val);
+	state.isStartFlow = val.start ? val.start : false;
+	state.orderId = val.id ?? '';
+	if (state.isStartFlow) {
+		// 如果是开启流程
+		const res: any = await OrderFlowParams(); //获取开启流程参数
+		state.nextStepOptions = res.result;
+	}
 	state.title = val.title ?? '提交流程';
 	ruleFormRef.value?.clearValidate();
 	ruleFormRef.value?.resetFields();
 	state.isShowDialog = true;
 };
-const dialogRef = ref();
-const uploadListRef = ref();
+// 流程选择下一环节
+const selectNextStep = (val: any) => {
+	const next = state.nextStepOptions.find((item: any) => item.code === val);
+	state.handerOptions = next.nextSteps ?? [];
+};
+// 选择处理人
+const selectHanders = (val: any) => {
+	state.ruleForm.nextHandlers = val.map((item: any) => {
+		return {
+			id: item.key,
+			name: item.value,
+			label: item.value,
+			key: item.key
+		};
+	});
+};
 // 设置抽屉
 const mouseup = () => {
 	state.trasform = dialogRef.value.dialogContentRef.$el.style.transform;
@@ -156,66 +209,9 @@ const handleRemove = (file: any) => {
 const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
 	ElMessage.warning(`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + uploadFiles.length} totally`);
 };
-// 检查文件类型
-const checkFile = (fileValue: string) => {
-	let index = fileValue.lastIndexOf('.'); //(考虑严谨用lastIndexOf(".")得到)得到"."在第几位
-	let fileValueSuffix = fileValue.substring(index); //截断"."之前的,得到后缀
-	if (/(.*)\.(mp4|avi|wmv|MP4|AVI|WMV)$/.test(fileValueSuffix)) {
-		//根据后缀,判断是否符合视频格式
-		return 'video';
-	} else if (/(.*)\.(jpg|JPG|bmp|BMP|mpg|MPG|mpeg|MPEG|tis|TIS|svg)$/.test(fileValueSuffix)) {
-		//根据后缀,判断是否符合图片格式
-		return 'image';
-	} else if (/(.*)\.(xls|XLS|xlsx|XLSX)$/.test(fileValueSuffix)) {
-		//根据后缀,判断是否符合OFFICE格式
-		return 'xls';
-	} else if (/(.*)\.(doc|DOC|docx|DOCX)$/.test(fileValueSuffix)) {
-		// 文档类型
-		return 'doc';
-	} else if (/(.*)\.(pdf|PDF)$/.test(fileValueSuffix)) {
-		// PDF
-		return 'pdf';
-	} else if (/(.*)\.(PPT|PPTX|ppt|pptx)$/.test(fileValueSuffix)) {
-		// ppt
-		return 'ppt';
-	}
-	return '';
-};
-// 返回相对应的字段
-const fileType = (file: string) => {
-	switch (file) {
-		case 'video':
-			return 'ele-VideoCamera';
-		case 'image':
-			return 'ele-Picture';
-		case 'xls':
-			return 'iconfont icon-excel';
-		case 'doc':
-			return 'ele-Document';
-		case 'pdf':
-			return 'iconfont icon-pdf';
-		case 'ppt':
-			return 'iconfont icon-ppt';
-		default:
-			break;
-	}
-};
-const summary = {
-	Discriminate: 'Discriminate', //  甄别惯用语
-	Return: 'Return', // 退回惯用语
-	Archive: 'Archive', // 归档惯用语
-	Teti: 'Teti', // 特提惯用语
-	Seat: 'Seat', // 坐席惯用语
-	Circulation: 'Circulation', // 流转惯用语
-	ReturnVisit: 'ReturnVisit', // 回访惯用语
-	HandleAgain: 'HandleAgain', // 办理惯用语
-	Delay: 'Delay', // 延期惯用语
-	Supervise: 'Supervise', // 督办惯用语
-	KnowledgeLocution: 'KnowledgeLocution', // 知识诉求惯用语
-};
 // 打开常用意见管理
 const showComents = () => {
-	CommentRef.value.openDialog(summary.Circulation);
+	CommentRef.value.openDialog(commonEeum.Circulation);
 };
 // 添加到常用意见
 const onAddComments = async () => {
@@ -224,7 +220,7 @@ const onAddComments = async () => {
 		return;
 	}
 	await addCommon({
-		typeCode: summary.Seat,
+		typeCode: commonEeum.Seat,
 		content: state.ruleForm.content,
 	});
 	ElMessage.success('操作成功');
@@ -236,22 +232,47 @@ const chooseComment = (item: any) => {
 	CommentRef.value.closeDialog();
 };
 // 保存
-const onSave = () => {
-	ruleFormRef.value.validate((valid: boolean) => {
-		if (valid) {
-			loading.value = true;
-			emit('updateList');
-		} else {
-			return false;
-		}
-	});
-};
+// const onSave = () => {
+// 	ruleFormRef.value.validate((valid: boolean) => {
+// 		if (valid) {
+// 			loading.value = true;
+// 			emit('onSubmit');
+// 		} else {
+// 			return false;
+// 		}
+// 	});
+// };
 // 提交
 const onSubmit = throttle(() => {
 	ruleFormRef.value.validate((valid: boolean) => {
 		if (valid) {
-			loading.value = true;
-			emit('updateList');
+			ElMessageBox.confirm(`确认提交?`, '提示', {
+				confirmButtonText: '确认',
+				cancelButtonText: '取消',
+				type: 'warning',
+				draggable: true,
+				cancelButtonClass: 'default-button',
+				autofocus: false,
+			})
+				.then(() => {
+					if (state.isStartFlow) {
+						// 如果是开启流程
+						orderStartflow(state.orderId,state.ruleForm).then(() => {
+							ElMessage.success('操作成功');
+							router.push({
+								path: '/business/order',
+							});
+							Cookies.set('refresh',1)
+							// 关闭当前 tagsView
+							mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
+							mittBus.emit('refreshList');
+							state.loading = false;
+							state.isShowDialog = false;
+							emit('onSubmit');
+						});
+					}
+				})
+				.catch(() => {});
 		} else {
 			return false;
 		}

+ 119 - 59
src/views/businessManage/workOrderManage/index.vue → src/views/business/order/index.vue

@@ -1,5 +1,5 @@
 <template>
-	<div class="businessManage-workOrderManage-container layout-pd">
+	<div class="business-oreder-container layout-pd">
 		<el-card shadow="never">
 			<el-tabs v-model="state.activeName" 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>
@@ -76,9 +76,9 @@
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-								<el-form-item label="受理时间" prop="CreationTimeStart">
+								<el-form-item label="受理时间" prop="crTime">
 									<el-date-picker
-										v-model="state.queryParams.CreationTimeStart"
+										v-model="state.queryParams.crTime"
 										type="daterange"
 										unlink-panels
 										range-separator="至"
@@ -86,14 +86,19 @@
 										end-placeholder="结束日期"
 										:shortcuts="shortcuts"
 										format="YYYY-MM-DD"
-										value-format="YYYY-MM-DD"
-										@change="timeStartChange"
+										@change="timeStartChangeCr"
 									/>
+									<!-- value-format="YYYY-MM-DD" -->
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
 								<el-form-item label="转接来源" prop="TransferPhone">
-									<el-input v-model="state.queryParams.TransferPhone" placeholder="诉求详情" clearable @keyup.enter="getList(state.activeName)" />
+									<el-input
+										v-model="state.queryParams.TransferPhone"
+										placeholder="请填写转接来源"
+										clearable
+										@keyup.enter="getList(state.activeName)"
+									/>
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
@@ -104,9 +109,9 @@
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-								<el-form-item label="办理期限" prop="Keyword">
+								<el-form-item label="办理期限" prop="exTime">
 									<el-date-picker
-										v-model="state.queryParams.Keyword"
+										v-model="state.queryParams.exTime"
 										type="daterange"
 										unlink-panels
 										range-separator="至"
@@ -114,8 +119,9 @@
 										end-placeholder="结束日期"
 										:shortcuts="shortcuts"
 										format="YYYY-MM-DD"
-										value-format="YYYY-MM-DD"
+										@change="timeStartChangeEx"
 									/>
+									<!-- value-format="YYYY-MM-DD" -->
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
@@ -124,9 +130,9 @@
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-								<el-form-item label="推送分类" prop="PushType">
-									<el-select v-model="state.queryParams.PushType" placeholder="请选择推送分类" multiple clearable class="w100">
-										<el-option v-for="item in state.pushTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
+								<el-form-item label="推送分类" prop="PushTypeCode">
+									<el-select v-model="state.queryParams.PushTypeCode" placeholder="请选择推送分类" clearable class="w100">
+										<el-option v-for="item in state.pushTypeOptions" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
 									</el-select>
 								</el-form-item>
 							</el-col>
@@ -156,7 +162,6 @@
 					<!-- <p class="table-title">信息列表</p> -->
 					<div>
 						<el-button type="primary" @click="onAddWorkOrder" v-waves> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
-						<el-button type="primary" @click="onDetail" v-waves> <SvgIcon name="ele-Plus" class="mr5" />详情 </el-button>
 						<el-button type="primary" :disabled="!state.multipleSelection.length" v-waves @click="onImportTable">
 							<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
 						</el-button>
@@ -166,38 +171,42 @@
 				<el-table :data="state.tableList" v-loading="state.loading" row-key="id" @selection-change="handleSelectionChange" @sort-change="sortChange">
 					<el-table-column type="selection" width="55" :reserve-selection="true" />
 					<el-table-column type="index" width="60" label="序号" />
-					<el-table-column label="工单编码" prop="moduleName" show-overflow-tooltip sortable="custom">
+					<el-table-column label="工单编码" prop="no" show-overflow-tooltip sortable="custom" width="150">
 						<template #default="scope">
-							<span>{{ scope.row.moduleName }}</span>
+							<span>{{ scope.row.no }}</span>
 						</template>
 					</el-table-column>
-					<el-table-column label="标题" show-overflow-tooltip>
+					<el-table-column label="标题" show-overflow-tooltip width="400">
 						<template #default="scope">
-							<el-button link type="primary">{{ scope.row.moduleName }}</el-button>
+							<span style="color: var(--el-color-primary)">{{ scope.row.title }}</span>
 						</template>
 					</el-table-column>
 					<el-table-column label="工单状态" show-overflow-tooltip>
 						<template #default="scope">
-							<el-button link type="primary">{{ scope.row.moduleName }}</el-button>
+							<el-button link type="primary">{{ scope.row.statusText }}</el-button>
 						</template>
 					</el-table-column>
-					<el-table-column prop="name" label="当前环节" show-overflow-tooltip></el-table-column>
-					<el-table-column prop="name" label="受理类型" show-overflow-tooltip></el-table-column>
-					<el-table-column prop="name" label="热点分类" show-overflow-tooltip></el-table-column>
-					<el-table-column label="紧急程度" show-overflow-tooltip prop="moduleName" sortable="custom">
+					<el-table-column prop="currentStepName" label="当前环节" show-overflow-tooltip width="150"></el-table-column>
+					<el-table-column prop="acceptTypeText" label="受理类型" show-overflow-tooltip></el-table-column>
+					<el-table-column prop="hotspot" label="热点分类" show-overflow-tooltip width="200"></el-table-column>
+					<el-table-column label="紧急程度" show-overflow-tooltip prop="emergencyLevelText" sortable="custom" width="150">
 						<template #default="scope">
-							<el-button link type="primary">{{ scope.row.moduleName }}</el-button>
+							<span v-if="scope.row.emergencyLevel === 2 || scope.row.emergencyLevel === 3" style="color: var(--el-color-danger)">{{ scope.row.emergencyLevelText }}</span>
+							<span v-else style="color: var(--el-color-primary)">{{ scope.row.emergencyLevelText }}</span>
 						</template>
 					</el-table-column>
-					<el-table-column prop="name" label="办理期限" show-overflow-tooltip sortable="custom"></el-table-column>
-					<el-table-column prop="name" label="受理坐席" show-overflow-tooltip></el-table-column>
-					<el-table-column prop="creationTime" label="更新时间" show-overflow-tooltip>
+					<el-table-column prop="expiredTime" label="办理期限" show-overflow-tooltip sortable="custom" width="170">
 						<template #default="scope">
-							<span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+							<span>{{ formatDate(scope.row.expiredTime, 'YYYY-MM-dd') }}</span>
+						</template>
+					</el-table-column>
+					<el-table-column prop="employeeName" label="受理坐席" show-overflow-tooltip width="170">
+						<template #default="scope">
+							<span>{{ scope.row.employeeName+'['+scope.row.employeeStaffNo+']' }}</span>
 						</template>
 					</el-table-column>
 					<el-table-column label="操作" width="150" fixed="right" align="center">
-						<!-- 草稿0 启用1 禁用2 -->
+						<!-- 草稿0 status 可以删除 -->
 						<template #default="scope">
 							<!-- <el-button text type="primary" @click="onEditTemp(scope.row)" title="修改">
 								修改
@@ -207,13 +216,9 @@
 							</el-button>
 							<el-button text type="warning" v-if="scope.row.status === 2" @click="tempEnable(scope.row)" title="启用">
 								启用
-							</el-button>
-							<el-button text type="danger" v-if="scope.row.status === 1" @click="tempDisable(scope.row)" title="禁用">
-								禁用
-							</el-button>
-							<el-button text v-if="scope.row.status === 0" type="danger" @click="onDeleteTemp(scope.row)" title="删除">
-								删除
-							</el-button> -->
+							</el-button>-->
+							<el-button text type="primary" @click="onOrderDetail(scope.row)" title="详情"> 详情 </el-button>
+							<el-button text v-if="scope.row.status === 0" type="danger" @click="onDeleteOrder(scope.row)" title="删除"> 删除 </el-button>
 						</template>
 					</el-table-column>
 					<template #empty>
@@ -240,20 +245,21 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="workOrderManage">
-import { defineAsyncComponent, ref, reactive, onMounted, onBeforeUnmount } from 'vue';
+<script setup lang="ts" name="order">
+import { defineAsyncComponent, ref, reactive, onMounted,onActivated,onUnmounted } from 'vue';
+import { ElMessageBox, ElMessage } from 'element-plus';
 import type { FormInstance } from 'element-plus';
 import { useRouter } from 'vue-router';
 import { formatDate } from '/@/utils/formatTime';
-import Cookies from 'js-cookie';
 import table2excel from 'js-table2excel';
-import { listBaseData, orderList, hotspottype } from '/@/api/businessManage/workOrderManage';
+import { listBaseData, orderList, hotspottype, orderDelete } from '/@/api/business/order';
+import mittBus from '/@/utils/mitt';
 // const ExpandText = defineAsyncComponent(() => import('/@/components/ExpandText/index.vue'));
 // const content = ref(
 // 	'Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。提供驱动。提供驱动。提供驱动。'
 // );
 // 引入组件
-const Detail = defineAsyncComponent(() => import('/@/views/businessManage/workOrderManage/components/Detail.vue'));
+const Detail = defineAsyncComponent(() => import('/@/views/business/order/components/Detail.vue'));
 const shortcuts = [
 	{
 		text: '近一周',
@@ -296,7 +302,22 @@ const state = reactive(<any>{
 		PageSize: 10,
 		Keyword: '',
 		Content: '',
-		AcceptType: [],
+		AcceptType: '',
+		Channel: '',
+		HotspotId: [],
+		OrgCode: [],
+		NameOrNo: '',
+		crTime: [],
+		CreationTimeStart: '',
+		CreationTimeEnd: '',
+		TransferPhone: '',
+		EmergencyLevel: [],
+		exTime: [],
+		ExpiredTimeStart: '',
+		ExpiredTimeEnd: '',
+		PhoneNo: '',
+		Status: [],
+		pushTypeOptions: '',
 	},
 	tableList: [], //表单
 	loading: false,
@@ -343,11 +364,12 @@ const HotspotProps = {
 	children: 'children',
 	isLeaf: 'isLeaf',
 };
-const load = async (node:any, resolve:any) => {
-  if (node.isLeaf) return resolve([])
-  let res:any = await hotspottype({parentId:node.data.id ? node.data.id : ''});
-   resolve(res.result)
-}
+// 热点分类远程搜索
+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);
+};
 // 获取选择组织name值
 const getselKnowledgeList = () => {
 	let currentNode = cascaderRef.value.getCheckedNodes();
@@ -357,13 +379,23 @@ const getselKnowledgeList = () => {
 const closeSearch = () => {
 	searchCol.value = !searchCol.value;
 };
+// 受理时间
+const timeStartChangeCr = (val: string[]) => {
+	state.queryParams.CreationTimeStart = val[0];
+	state.queryParams.CreationTimeEnd = val[0];
+};
+// 过期时间
+const timeStartChangeEx = (val: string[]) => {
+	state.queryParams.ExpiredTimeStart = val[0];
+	state.queryParams.ExpiredTimeStart = val[0];
+};
 // 获取查询条件基础信息
 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.result ?? [];
+	state.orgsOptions = res.result?.orgsOptions ?? [];
 	state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
 	state.orderStatusOptions = res.result?.orderStatusOptions ?? [];
 };
@@ -377,9 +409,7 @@ const getList = (val: string) => {
 				.then((response: any) => {
 					state.tableList = response?.result.items ?? [];
 					state.total = response?.result.total;
-					setTimeout(() => {
-						state.loading = false;
-					}, 300);
+					state.loading = false;
 				})
 				.catch(() => {
 					state.loading = false;
@@ -472,7 +502,6 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 // 切换tab 查询列表
 const handleClick = (val: string) => {
 	getList(val);
-	Cookies.set('activeName', val);
 };
 // 多选表格
 const handleSelectionChange = (val: any) => {
@@ -481,14 +510,41 @@ const handleSelectionChange = (val: any) => {
 // 新增工单
 const onAddWorkOrder = () => {
 	// 跳转到录入工单页面
-	router.push('/businessManage/workOrderManage/wokOrder');
+	router.push('/business/order/orderAccept');
 };
 // 查看详情
-const onDetail = () => {
-	detailRef.value.openDialog('121');
+const onOrderDetail = (row: any) => {
+	if (row.status === 0) {
+		// 草稿状态跳转到编辑页面
+		router.push({
+			name:"orderAcceptEdit",
+			params: {
+				id: row.id,
+				tagsViewName: '工单受理 ' + row.no,
+			}
+		});
+	} else {
+		// 已经发布的直接查看详情
+		detailRef.value.openDialog(row);
+	}
 };
-const timeStartChange = (val: string[]) => {
-	console.log(val);
+// 删除工单
+const onDeleteOrder = (row: any) => {
+	ElMessageBox.confirm(`确认删除?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			orderDelete(row.id).then(() => {
+				ElMessage.success('操作成功');
+				getList(state.activeName);
+			});
+		})
+		.catch(() => {});
 };
 // 导出列表
 const onImportTable = () => {
@@ -500,12 +556,16 @@ const onImportTable = () => {
 	table2excel(tabeHeader, state.multipleSelection, `${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
 };
 onMounted(async () => {
-	state.activeName = Cookies.get('activeName') ?? 'all';
 	getBaseData();
 	getList(state.activeName);
 });
-onBeforeUnmount(() => {
-	Cookies.remove('activeName');
+onActivated(()=>{
+	mittBus.on('refreshList',()=>{ // 从详情页刷新列表
+		getList(state.activeName);
+	});
+})
+onUnmounted(() => {
+	mittBus.off('refreshList', () => {});
 });
 </script>
 <style scoped lang="scss">

+ 356 - 208
src/views/businessManage/workOrderManage/wokOrder/index.vue → src/views/business/order/orderAccept/add.vue

@@ -4,17 +4,18 @@
 			<!-- 左边工单信息 -->
 			<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="left-content mb20 h100">
 				<el-scrollbar class="box pd20">
-					<div class="flex-center-between mb20">
+					<!-- <div class="flex-center-between mb20">
 						<p class="table-title">工单信息</p>
-					</div>
-					<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="110px" label-position="right" scroll-to-error>
+					</div> -->
+					<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="110px" label-position="right" scroll-to-error v-loading="state.loading">
 						<p class="border-title mb10">来电信息</p>
 						<el-row :gutter="0">
+							<!-- 来源渠道 -->
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
 								<!-- 手动创建 -->
 								<template v-if="state.createFrom == 'manual'">
-									<el-form-item label="来源渠道" prop="transferPhone" :rules="[{ required: true, message: '请选择来源渠道', trigger: 'change' }]">
-										<el-select v-model="state.ruleForm.transferPhone" placeholder="请选择来源渠道" class="w100">
+									<el-form-item label="来源渠道" prop="channel" :rules="[{ required: true, message: '请选择来源渠道', trigger: 'change' }]">
+										<el-select v-model="state.ruleForm.channel" placeholder="请选择来源渠道" class="w100">
 											<el-option v-for="item in state.channelOptions" :key="item.key" :label="item.value" :value="item.key" />
 										</el-select>
 									</el-form-item>
@@ -32,10 +33,11 @@
 									</el-form-item>
 								</template>
 							</el-col>
+							<!-- 转接来源 -->
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
 								<!-- 手动创建 -->
 								<template v-if="state.createFrom == 'manual'">
-									<el-form-item label="转接来源"> 暂无 </el-form-item>
+									<el-form-item label="转接来源" prop="transferPhone"> 暂无 </el-form-item>
 								</template>
 								<!-- 来电弹单 -->
 								<template v-else-if="state.createFrom == 'tel'">
@@ -50,11 +52,23 @@
 									</el-form-item>
 								</template>
 							</el-col>
-							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+							<!-- 来电号码 -->
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="state.ruleForm.channel == 0">
 								<!-- 手动创建 -->
 								<template v-if="state.createFrom == 'manual'">
-									<el-form-item label="来电号码" prop="fromPhone" :rules="[{ required: true, message: '请填写来电号码', trigger: 'blur' }]">
-										<el-input v-model="state.ruleForm.fromPhone" placeholder="请填写来电号码" clearable> </el-input>
+									<el-form-item
+										label="来电号码"
+										prop="fromPhone"
+										:rules="[
+											{ required: true, message: '请填写来电号码', trigger: 'blur' },
+											// {
+											// 	pattern: /^(13[0-9]|14[01456879]|15[0-3,5-9]|16[2567]|17[0-8]|18[0-9]|19[0-3,5-9])d{8}$/,
+											// 	message: '手机号格式错误',
+											// 	trigger: 'blur'
+											// },
+										]"
+									>
+										<el-input v-model="state.ruleForm.fromPhone" placeholder="请填写来电号码" clearable @blur="searchHistory"> </el-input>
 									</el-form-item>
 								</template>
 								<!-- 来电弹单 -->
@@ -66,15 +80,16 @@
 								<!-- 互联网来信 -->
 								<template v-else-if="state.createFrom == 'letter'">
 									<el-form-item label="来电号码">
-										<span>[{{ telStatusInfo.telsNo }}]</span>
+										<span>[{{ phoneNumber }}]</span>
 									</el-form-item>
 								</template>
 							</el-col>
+							<!-- 服务坐席 -->
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
 								<el-form-item label="服务坐席">
 									<!-- 手动创建 -->
 									<template v-if="state.createFrom == 'manual'">
-										<span>{{ state.ruleForm.seats }}</span>
+										<span>{{ state.ruleForm.employeeName + ' [ ' + state.ruleForm.employeeStaffNo + ' ]' }}</span>
 									</template>
 									<!-- 来电弹单 -->
 									<template v-else-if="state.createFrom == 'tel'">
@@ -92,7 +107,11 @@
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
-								<el-form-item label="" label-width="40px"  prop="fromGender" :rules="[{ required: true, message: '请选择来电/信人性别', trigger: 'change' }]">
+								<el-form-item
+									label="来电/信人性别"
+									prop="fromGender"
+									:rules="[{ required: true, message: '请选择来电/信人性别', trigger: 'change' }]"
+								>
 									<el-radio-group v-model="state.ruleForm.fromGender">
 										<el-radio :label="item.key" v-for="item in state.genderOptions" :key="item.key">{{ item.value }}</el-radio>
 									</el-radio-group>
@@ -102,7 +121,7 @@
 								<el-form-item
 									label="来电/信人身份"
 									prop="identityType"
-									:rules="[{ required: true, message: '请选择来电/信人身份', trigger: 'blur' }]"
+									:rules="[{ required: true, message: '请选择来电/信人身份', trigger: 'change' }]"
 								>
 									<el-radio-group v-model="state.ruleForm.identityType">
 										<el-radio :label="item.key" v-for="item in state.identityTypeOptions" :key="item.key">{{ item.value }}</el-radio>
@@ -110,9 +129,16 @@
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
-								<el-form-item label="证件类型" prop="licence" :rules="[{ required: false, message: '请选择证件类型', trigger: 'change' }]">
-									<el-select v-model="state.ruleForm.licence" placeholder="请选择证件类型" class="w100">
-										<el-option v-for="item in state.licenceTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+								<el-form-item label="证件类型" prop="licenceTypeObj" :rules="[{ required: false, message: '请选择证件类型', trigger: 'change' }]">
+									<el-select
+										v-model="state.ruleForm.licenceTypeObj"
+										placeholder="请选择证件类型"
+										class="w100"
+										value-key="dicDataValue"
+										@change="(val:any)=>{state.ruleForm.licenceType = val.dicDataName;
+									state.ruleForm.licenceTypeCode = val.dicDataValue}"
+									>
+										<el-option v-for="item in state.licenceTypeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
 									</el-select>
 								</el-form-item>
 							</el-col>
@@ -121,27 +147,44 @@
 								<el-form-item
 									label="证件号码"
 									prop="licenceNo"
-									:rules="[{ required: state.ruleForm.licence, message: '请填写证件号码', trigger: 'blur' }]"
+									:rules="[{ required: state.ruleForm.licence || state.ruleForm.licence === 0, message: '请填写证件号码', trigger: 'blur' }]"
 								>
 									<el-input v-model="state.ruleForm.licenceNo" placeholder="请填写证件号码" clearable> </el-input>
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
-								<el-form-item label="年龄段" prop="ageRange" :rules="[{ required: false, message: '请选择年龄段', trigger: 'change' }]">
-									<el-select v-model="state.ruleForm.ageRange" placeholder="请选择年龄段" class="w100">
-										<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
+								<el-form-item label="年龄段" prop="ageRangeObj" :rules="[{ required: false, message: '请选择年龄段', trigger: 'change' }]">
+									<el-select
+										v-model="state.ruleForm.ageRangeObj"
+										placeholder="请选择年龄段"
+										class="w100"
+										value-key="dicDataValue"
+										@change="(val:any)=>{state.ruleForm.ageRange = val.dicDataName;
+									state.ruleForm.ageRangeCode = val.dicDataValue}"
+									>
+										<el-option v-for="item in state.ageRangeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
 									</el-select>
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
-								<el-form-item label="联系电话" prop="contact" :rules="[{ required: true, message: '请填写联系电话', trigger: 'blur' }]">
-									<el-input v-model="state.ruleForm.contact" placeholder="请填写联系电话" clearable> </el-input>
+								<el-form-item
+									label="联系电话"
+									prop="contact"
+									:rules="[{ required: !state.ruleForm.needContact, message: '请填写联系电话', trigger: 'blur' }]"
+								>
+									<el-input
+										v-model="state.ruleForm.contact"
+										:disabled="state.ruleForm.needContact"
+										:placeholder="state.ruleForm.needContact ? '无需联系' : '请填写联系电话'"
+										clearable
+									>
+									</el-input>
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
 								<el-form-item label="" prop="acceptSms" :rules="[{ required: false, message: '请选择', trigger: 'blur' }]">
 									<el-checkbox v-model="state.ruleForm.acceptSms" label="受理短信" />
-									<el-checkbox v-model="state.ruleForm.needContact" label="无需联系" />
+									<el-checkbox v-model="state.ruleForm.needContact" label="无需联系" @change="(val:boolean)=> ruleFormRef.resetFields('contact')" />
 								</el-form-item>
 							</el-col>
 							<!-- 当“来电/信人身份”为“企业”时必填 -->
@@ -158,7 +201,7 @@
 						<p class="border-title mb10">诉求信息</p>
 						<el-row>
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
-								<el-form-item label="工单编码"> </el-form-item>
+								<el-form-item label="工单编码"> {{ state.ruleForm.no }} </el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 								<el-form-item label="工单标题" prop="title" :rules="[{ required: true, message: '请填写工单标题', trigger: 'blur' }]">
@@ -169,13 +212,13 @@
 								<el-row :gutter="0">
 									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
 										<el-form-item label="工单类型" prop="orderType" :rules="[{ required: true, message: '请填写工单类型', trigger: 'blur' }]">
-											<el-select v-model="state.ruleForm.orderType" placeholder="请选择工单类型" class="w100">
+											<el-select v-model="state.ruleForm.orderType" placeholder="请选择工单类型" class="w100" @change="selectOrderType">
 												<el-option v-for="item in state.orderTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
 											</el-select>
 										</el-form-item>
 									</el-col>
 									<!-- 当“工单类型”为非通用工单时,展示【拓展信息】按钮 -->
-									<el-col :xs="6" :sm="6" :md="6" :lg="6" :xl="6" :offset="1">
+									<el-col :xs="6" :sm="6" :md="6" :lg="6" :xl="6" :offset="1" v-if="state.ruleForm.orderType === 1 && state.ruleForm.acceptType">
 										<el-form-item label="" label-width="0px">
 											<el-button @click="showExpandForm"><SvgIcon name="ele-CirclePlus" class="mr3" size="16px" /> 拓展信息</el-button>
 										</el-form-item>
@@ -185,7 +228,13 @@
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
 								<el-form-item label="受理类型" prop="acceptType" :rules="[{ required: true, message: '请选择受理类型', trigger: 'change' }]">
 									<el-select v-model="state.ruleForm.acceptType" placeholder="请选择受理类型" class="w100">
-										<el-option v-for="item in state.acceptTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+										<el-option
+											v-for="item in state.acceptTypeOptions"
+											:key="item.key"
+											:disabled="item.disabled"
+											:label="item.value"
+											:value="item.key"
+										/>
 									</el-select>
 								</el-form-item>
 							</el-col>
@@ -203,43 +252,50 @@
 										v-model="state.ruleForm.hotspotId"
 										filterable
 										clearable
-										:render-after-expand="false"
 										placeholder="请选择热点分类"
 										:props="HotspotProps"
 										lazy
 										:load="load"
 										node-key="id"
-										@change="hotsoptChange"
+										check-strictly
+										:render-after-expand="false"
+										@node-click="hotsoptChange"
+										ref="hotspotRef"
+										:default-expanded-keys="state.hotspotExternal"
 									/>
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
 								<el-form-item label="事发时间" prop="incidentTime" :rules="[{ required: false, message: '请选择事发时间', trigger: 'change' }]">
-									<el-date-picker
-										v-model="state.ruleForm.incidentTime"
-										type="date"
-										placeholder="请选择事发时间"
-										value-format="YYYY-MM-DD"
-										format="YYYY-MM-DD"
-										class="w100"
-									/>
+									<el-date-picker v-model="state.ruleForm.incidentTime" type="date" placeholder="请选择事发时间" format="YYYY-MM-DD" class="w100" />
+									<!-- value-format="YYYY-MM-DD" -->
 								</el-form-item>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 								<el-row :gutter="0">
 									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
-										<el-form-item label="事发地址" prop="phoneNo" :rules="[{ required: true, message: '请选择事发地址', trigger: 'change' }]">
-											<el-cascader v-model="state.ruleForm.phoneNo" class="w100" :options="state.orgData" placeholder="请选择事发地址" />
+										<el-form-item label="事发地址" prop="areaCode" :rules="[{ required: true, message: '请选择事发地址', trigger: 'change' }]">
+											<el-cascader
+												:options="state.areaOptions"
+												filterable
+												:props="{ value: 'id', label: 'areaName', emitPath: false }"
+												placeholder="请选择事发地址"
+												clearable
+												class="w100"
+												v-model="state.ruleForm.areaCode"
+												ref="areaRef"
+												@change="changeArea"
+											>
+												<template #default="{ node, data }">
+													<span>{{ data.areaName }}</span>
+													<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+												</template>
+											</el-cascader>
 										</el-form-item>
 									</el-col>
 									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
-										<el-form-item
-											label=""
-											prop="phoneNo"
-											:rules="[{ required: true, message: '请填写详细地址', trigger: 'blur' }]"
-											label-width="10px"
-										>
-											<el-input v-model="state.ruleForm.phoneNo" placeholder="请填写详细地址" clearable> </el-input>
+										<el-form-item label="" prop="street" :rules="[{ required: true, message: '请填写详细地址', trigger: 'blur' }]" label-width="10px">
+											<el-input v-model="state.ruleForm.street" placeholder="请填写详细地址" clearable> </el-input>
 										</el-form-item>
 									</el-col>
 								</el-row>
@@ -248,23 +304,23 @@
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 								<el-row :gutter="0">
 									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
-										<el-form-item label="是否重复" prop="phoneNo" :rules="[{ required: true, message: '请选择是否重复', trigger: 'change' }]">
-											<el-select v-model="state.ruleForm.phoneNo" placeholder="请选择是否重复" class="w100">
-												<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
+										<el-form-item label="是否重复" prop="isRepeat" :rules="[{ required: true, message: '请选择是否重复', trigger: 'change' }]">
+											<el-select v-model="state.ruleForm.isRepeat" placeholder="请选择是否重复" class="w100">
+												<el-option v-for="item in state.repeatOptions" :key="item.key" :label="item.value" :value="item.key" />
 											</el-select>
 										</el-form-item>
 									</el-col>
 									<!-- 必填,若“是否重复”为“是”,则展示重复件选择框 -->
-									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="state.ruleForm.isRepeat === 'true'">
 										<el-form-item
 											label=""
-											prop="duplicateName"
+											prop="duplicateTitle"
 											label-width="10px"
 											:rules="[{ required: true, message: '请选择重复件', trigger: 'change' }]"
 										>
-											<el-input v-model="state.ruleForm.duplicateName" placeholder="请选择重复件" readonly>
+											<el-input v-model="state.ruleForm.duplicateTitle" placeholder="请选择重复件" readonly>
 												<template #suffix>
-													<el-button link type="danger" v-if="state.ruleForm.duplicateName" @click="clearRepeat">
+													<el-button link type="danger" v-if="state.ruleForm.duplicateTitle" @click="clearRepeat">
 														<SvgIcon name="ele-Delete" size="16px" />
 													</el-button>
 													<el-button link type="primary" class="ml1" @click="selectRepat">
@@ -277,9 +333,17 @@
 								</el-row>
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
-								<el-form-item label="推送分类" prop="pushType" :rules="[{ required: false, message: '请选择推送分类', trigger: 'change' }]">
-									<el-select v-model="state.ruleForm.pushType" placeholder="请选择推送分类" class="w100">
-										<el-option v-for="item in state.orderTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+								<el-form-item label="推送分类" prop="pushTypeObj" :rules="[{ required: false, message: '请选择推送分类', trigger: 'change' }]">
+									<el-select
+										v-model="state.ruleForm.pushTypeObj"
+										placeholder="请选择推送分类"
+										class="w100"
+										clearable
+										value-key="dicDataValue"
+										@change="(val:any)=>{state.ruleForm.pushType = val.dicDataName;
+									state.ruleForm.pushTypeCode = val.dicDataValue}"
+									>
+										<el-option v-for="item in state.pushTypeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
 									</el-select>
 								</el-form-item>
 							</el-col>
@@ -288,7 +352,7 @@
 									label="诉求详情"
 									prop="content"
 									class="textarea"
-									:rules="[{ required: false, message: '请填写诉求详情', trigger: 'blur' }]"
+									:rules="[{ required: true, message: '请填写诉求详情', trigger: 'blur' }]"
 								>
 									<el-input
 										v-model="state.ruleForm.content"
@@ -360,21 +424,25 @@
 								</el-button>
 							</el-form-item>
 						</el-form>
-						<el-table :data="state.tableData" v-loading="state.loading">
-							<el-table-column prop="phoneNo" label="重复件" width="70">
+						<el-table :data="state.tableData" v-loading="state.loading" @current-change="handleSelectionChange">
+							<el-table-column prop="phoneNo" label="重复件" width="70" v-if="state.ruleForm.isRepeat === 'true'">
 								<template #default="scope">
-									<el-radio v-model="state.tableRadio" @change="handleSelectionChange(scope.row)"></el-radio>
+									<el-radio v-model="state.tableRadio" :label="scope.row.id" @change="handleRowChange(scope.row)">&nbsp;</el-radio>
 								</template>
 							</el-table-column>
 							<el-table-column type="index" width="60" label="序号" />
-							<el-table-column prop="phoneNo" label="工单标题" show-overflow-tooltip> </el-table-column>
-							<el-table-column prop="phoneNo" label="热点分类" show-overflow-tooltip> </el-table-column>
-							<el-table-column prop="phoneNo" label="工单编码" show-overflow-tooltip> </el-table-column>
-							<el-table-column prop="phoneNo" label="当前环节" show-overflow-tooltip></el-table-column>
-							<el-table-column prop="phoneNo" label="状态" width="70" fixed="right" align="center">
+							<el-table-column prop="phoneNo" label="工单标题" show-overflow-tooltip>
+								<template #default="scope">
+									<span style="color: var(--el-color-primary)">{{ scope.row.title }}</span>
+								</template>
+							</el-table-column>
+							<el-table-column prop="hotspot" label="热点分类" show-overflow-tooltip> </el-table-column>
+							<el-table-column prop="no" label="工单编码" show-overflow-tooltip> </el-table-column>
+							<el-table-column prop="currentStepName" label="当前环节" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="statusText" label="状态" width="70" fixed="right" align="center">
 								<template #default="scope">
 									<el-button text type="primary">
-										{{ scope.row.phoneNo }}
+										{{ scope.row.statusText }}
 									</el-button>
 								</template>
 							</el-table-column>
@@ -384,7 +452,7 @@
 							:total="state.total"
 							v-model:page="state.queryParams.PageIndex"
 							v-model:limit="state.queryParams.PageSize"
-							@pagination="getList"
+							@pagination="searchHistory"
 						/>
 					</div>
 					<div class="right-content-knowledge mt20 box pd20">
@@ -441,7 +509,7 @@
 			</el-col>
 		</el-row>
 		<!-- 拓展表单 -->
-		<ExpandForm ref="ExpandFormRef" />
+		<ExpandForm ref="ExpandFormRef" @saveExpandForm="saveExpandForm" />
 		<!-- 常用意见管理 -->
 		<Comment ref="CommentRef" @chooseComment="chooseComment" modal />
 		<!-- 历史工单 -->
@@ -451,35 +519,36 @@
 	</div>
 </template>
 
-<script setup lang="ts" name="WokOrder">
+<script setup lang="ts" name="orderAcceptAdd">
 import { defineAsyncComponent, ref, reactive, computed, onMounted } from 'vue';
 import { ElMessage, ElMessageBox } from 'element-plus';
 import type { UploadProps, UploadUserFile, FormInstance } from 'element-plus';
 import { storeToRefs } from 'pinia';
-import { useRoute } from 'vue-router';
+import { useRoute, useRouter } from 'vue-router';
 import { useTelStatus } from '/@/stores/telStatus';
-import { formatDate } from '/@/utils/formatTime';
-import { desensitizationPhone } from '/@/utils/tools';
-import { orderBasedataAdd, orderAdd, hotspottype, historyOrder } from '/@/api/businessManage/workOrderManage';
+import { desensitizationPhone, checkFile, fileType, commonEeum } from '/@/utils/tools';
+import { orderBasedataAdd, orderAdd, hotspottype, historyOrder } from '/@/api/business/order';
 import { useUserInfo } from '/@/stores/userInfo';
-import { addCommon } from '/@/api/businessManage/commonP';
+import { addCommon, treeArea } from '/@/api/business/commonP';
+import mittBus from '/@/utils/mitt';
 
 // 引入组件
-const Process = defineAsyncComponent(() => import('/@/views/businessManage/workOrderManage/components/Process.vue'));
-const ExpandForm = defineAsyncComponent(() => import('/@/views/businessManage/workOrderManage/components/ExpandForm.vue'));
-const History = defineAsyncComponent(() => import('/@/views/businessManage/workOrderManage/components/History.vue'));
-const Comment = defineAsyncComponent(() => import('/@/views/businessManage/workOrderManage/components/Comment.vue'));
+const Process = defineAsyncComponent(() => import('/@/views/business/order/components/Process.vue'));
+const ExpandForm = defineAsyncComponent(() => import('/@/views/business/order/components/ExpandForm.vue'));
+const History = defineAsyncComponent(() => import('/@/views/business/order/components/History.vue'));
+const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Comment.vue'));
 // 定义变量内容
 const state = reactive<any>({
 	createFrom: 'manual', // 工单创建方式 默认手动创建  tel:来电弹单  letter:互联网来信 默认表示手动创建
 	activeName: 'first', // tabs
 	ruleForm: {
 		// 表单
-		phoneNo: '',
-		time: '',
-		content: '',
-		type: 2,
-		repeat: '',
+		street: '',
+		transferPhone: '',
+		employeeName: '',
+		employeeStaffNo: '',
+		duplicateTitle: '',
+		duplicateId: '',
 	},
 	acceptTypeOptions: [], // 受理类型
 	channelOptions: [], // 来源频道
@@ -487,26 +556,24 @@ const state = reactive<any>({
 	genderOptions: [], // 性别
 	identityTypeOptions: [], //来电人身份
 	licenceTypeOptions: [], // 证件类型
+	ageRangeOptions: [], // 年龄段
 	orderTypeOptions: [], // 工单类型
 	pushTypeOptions: [], //推送分类
-	levelList: [
+	areaOptions: [], //省市区
+	repeatOptions: [
+		//是否重复
 		{
-			value: '呼入限制',
-			key: 0,
+			value: '',
+			key: 'true',
 		},
 		{
-			value: '坐席限制',
-			key: 1,
-		},
-		{
-			value: '友情提示',
-			key: 2,
+			value: '否',
+			key: 'false',
 		},
 	],
 	tableRadio: null as any, // 重复件选择
 	orgData: [],
-	isShowDialog: false,
-	tableData: [],
+	tableData: [], // 历史工单
 	total: 0,
 	loading: false,
 	queryParams: {
@@ -514,8 +581,9 @@ const state = reactive<any>({
 		PageSize: 10,
 		Keyword: '',
 	},
-	KnowledgeKeyword: '',
+	KnowledgeKeyword: '', //知识检索内容
 	items: [
+		// 知识检索热点
 		{ type: '', label: 'Tag 1' },
 		{ type: 'success', label: 'Tag 2' },
 		{ type: 'info', label: 'Tag 3' },
@@ -543,6 +611,7 @@ const state = reactive<any>({
 		{ type: 'warning', label: 'Tag 5' },
 	],
 	knowledgeList: [
+		//知识检索列表
 		{
 			title: '领取失业保险金会影响退休金吗?',
 			content:
@@ -554,6 +623,8 @@ const state = reactive<any>({
 				'不能。退休金的高低跟参保人的平均缴费指数有关,而平均缴费指数是根据每个月的缴费指数累加再除以总缴费月数计算出来的,也就是说最后几年的缴费指数高,如果前面的缴费指数低,也会被平均拉低,当然最后几年交高一点,退休金也会高一点,但不会同比率的提高。',
 		},
 	],
+	external: [],
+	hotspotExternal: [], // 热点分类展开
 });
 const ruleFormRef = ref();
 const queryParamsRef = ref();
@@ -563,20 +634,41 @@ const uploadListRef = ref();
 const processRef = ref();
 const storesUserInfo = useUserInfo();
 const { userInfos } = storeToRefs(storesUserInfo);
+state.ruleForm.employeeName = userInfos.value.name;
+state.ruleForm.employeeStaffNo = userInfos.value.staffNo;
 const route = useRoute();
+const router = useRouter();
 const HistoryOrderRef = ref();
 const CommentRef = ref();
+const hotspotRef = ref();
 // 热点分类远程搜索
 const HotspotProps = {
-	label: 'hotSpotName',
+	label: 'hotSpotFullName',
 	children: 'children',
 	isLeaf: 'isLeaf',
 };
+// 热点分类懒加载
 const load = async (node: any, resolve: any) => {
 	if (node.isLeaf) return resolve([]);
-	let res: any = await hotspottype({ parentId: node.data.id ? node.data.id : '' });
+	const res: any = await hotspottype({ id: node.data.id ? node.data.id : '' });
 	resolve(res.result);
 };
+// 选择热点分类
+const hotsoptChange = (val: any, e: any) => {
+	state.hotspotExternal = [];
+	state.external = [];
+	state.hotspotExternal = getParentId(e, state.external);
+	state.ruleForm.hotspotSpliceName = val.hotSpotFullName;
+	state.ruleForm.hotspot = val.hotSpotName;
+};
+// 递归查找父级Id
+const getParentId = (val: any, arr: string[]) => {
+	if (val.data.parentId) {
+		arr.push(val.data.parentId);
+		getParentId(val.parent, arr);
+	}
+	return arr;
+};
 // 手机号码脱敏处理
 const phoneNumber = computed(() => {
 	return desensitizationPhone(telStatusInfo.value.onCallArr[0]?.from);
@@ -597,44 +689,104 @@ const handleRemove = (file: any) => {
 const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
 	ElMessage.warning(`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + uploadFiles.length} totally`);
 };
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-	state.queryParams.PageIndex = 1;
-	getList();
-};
-/** 重置按钮操作 */
-const resetQuery = (formEl: FormInstance | undefined) => {
-	if (!formEl) return;
-	formEl.resetFields();
-	handleQuery();
-};
-/** 获取历史工单 */
-const getList = () => {
-	state.loading = true;
-	historyOrder(state.queryParams)
-		.then((response: any) => {
-			state.tableData = response?.result.items ?? [];
-			state.total = response?.result.total;
-			setTimeout(() => {
-				state.loading = false;
-			}, 300);
-		})
-		.catch(() => {
-			state.loading = false;
+// 选择工单类型 处理受理类型选择数据
+const selectOrderType = (val: any) => {
+	ruleFormRef.value.resetFields('acceptType');
+	if (val === 1) {
+		// 选择了12315市场监管受理单
+		state.acceptTypeOptions = state.acceptTypeOptions.map((item: any) => {
+			if (item.key === 5 || item.key === 6) {
+				//直接投诉或者建议
+				return {
+					key: item.key,
+					value: item.value,
+					disabled: false,
+				};
+			} else {
+				return {
+					key: item.key,
+					value: item.value,
+					disabled: true,
+				};
+			}
 		});
+	} else {
+		state.acceptTypeOptions = state.acceptTypeOptions.map((item: any) => {
+			return {
+				key: item.key,
+				value: item.value,
+				disabled: false,
+			};
+		});
+	}
+};
+const areaRef = ref();
+// 选择省市区
+const changeArea = () => {
+	const currentNode = areaRef.value.getCheckedNodes();
+	state.ruleForm.province = currentNode[0].pathLabels[0];
+	state.ruleForm.city = currentNode[0].pathLabels[1];
+	state.ruleForm.county = currentNode[0].pathLabels[2];
 };
 const ExpandFormRef = ref();
 // 打开拓展表单
-const showExpandForm = (id: any) => {
-	ExpandFormRef.value.openDialog(id);
+const showExpandForm = () => {
+	ExpandFormRef.value.openDialog(state.ruleForm.acceptType);
+};
+// 拓展表单保存
+const saveExpandForm = (val: any) => {
+	switch (state.ruleForm.acceptType) {
+		case 5: //举报
+			state.ruleForm.orderReport = val;
+			break;
+		case 6: //投诉
+			state.ruleForm.orderComplain = val;
+			break;
+		default:
+			break;
+	}
 };
-
 // 保存
 const save = () => {
 	ruleFormRef.value.validate((valid: boolean) => {
 		if (valid) {
-			console.log(ruleFormRef.value);
+			state.ruleForm.hotspotExternal = state.hotspotExternal.join(',');
+			let submitObj = JSON.parse(JSON.stringify(state.ruleForm));
+			Reflect.deleteProperty(submitObj, 'ageRangeObj'); // 删除无用的参数 年龄段
+			Reflect.deleteProperty(submitObj, 'pushTypeObj'); // 删除无用的参数 推送分类
+			Reflect.deleteProperty(submitObj, 'licenceTypeObj'); // 删除无用的参数 证件类型
+			if (submitObj.acceptType === 5) Reflect.deleteProperty(submitObj, 'orderComplain'); // 举报 删除投诉表单
+			if (submitObj.acceptType === 6) Reflect.deleteProperty(submitObj, 'orderReport'); // 投诉 删除举报表单
+			if (submitObj.orderType === 1 && submitObj.acceptType) {
+				//拓展表单
+				if (ExpandFormRef.value.state.validated) {
+					//验证通过
+					// 新增
+					orderAdd(submitObj).then(() => {
+						ElMessage.success('操作成功');
+						router.push({
+							path: '/business/order',
+						});
+						// 关闭当前 tagsView
+						mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
+						mittBus.emit('refreshList');
+					});
+				} else {
+					//不通过 展示弹窗
+					ExpandFormRef.value.openDialog(submitObj.acceptType, true); // 立即提交展示验证
+				}
+			} else {
+				// 新增
+				orderAdd(submitObj).then(() => {
+					ElMessage.success('操作成功');
+					router.push({
+						path: '/business/order',
+					});
+					// 关闭当前 tagsView
+					mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
+					mittBus.emit('refreshList');
+				});
+			}
 		} else {
 			return false;
 		}
@@ -644,73 +796,67 @@ const save = () => {
 const submit = () => {
 	ruleFormRef.value.validate((valid: boolean) => {
 		if (valid) {
-			console.log(ruleFormRef.value);
+			state.ruleForm.hotspotExternal = state.hotspotExternal.join(',');
+			let submitObj = JSON.parse(JSON.stringify(state.ruleForm));
+			Reflect.deleteProperty(submitObj, 'ageRangeObj'); // 删除无用的参数 年龄段
+			Reflect.deleteProperty(submitObj, 'pushTypeObj'); // 删除无用的参数 推送分类
+			Reflect.deleteProperty(submitObj, 'licenceTypeObj'); // 删除无用的参数 证件类型
+			if (submitObj.acceptType === 5) Reflect.deleteProperty(submitObj, 'orderComplain'); // 举报 删除投诉表单
+			if (submitObj.acceptType === 6) Reflect.deleteProperty(submitObj, 'orderReport'); // 投诉 删除举报表单
+			if (submitObj.orderType === 1 && submitObj.acceptType) {
+				//拓展表单
+				if (ExpandFormRef.value.state.validated) {
+					// 新增
+					orderAdd(state.ruleForm).then((res: any) => {
+						ElMessage.success('操作成功');
+						processRef.value.openDialog({ id: res.result, title: '提交', commonEeum: commonEeum.Seat, start: true });
+					});
+				} else {
+					//不通过 展示弹窗
+					ExpandFormRef.value.openDialog(submitObj.acceptType, true); // 立即提交展示验证
+				}
+			} else {
+				// 新增
+				orderAdd(state.ruleForm).then((res: any) => {
+					ElMessage.success('操作成功');
+					processRef.value.openDialog({ id: res.result, title: '提交', commonEeum: commonEeum.Seat, start: true });
+				});
+			}
 		} else {
 			return false;
 		}
 	});
 };
-// 检查文件类型
-const checkFile = (fileValue: string) => {
-	let index = fileValue.lastIndexOf('.'); //(考虑严谨用lastIndexOf(".")得到)得到"."在第几位
-	let fileValueSuffix = fileValue.substring(index); //截断"."之前的,得到后缀
-	if (/(.*)\.(mp4|avi|wmv|MP4|AVI|WMV)$/.test(fileValueSuffix)) {
-		//根据后缀,判断是否符合视频格式
-		return 'video';
-	} else if (/(.*)\.(jpg|JPG|bmp|BMP|mpg|MPG|mpeg|MPEG|tis|TIS|svg)$/.test(fileValueSuffix)) {
-		//根据后缀,判断是否符合图片格式
-		return 'image';
-	} else if (/(.*)\.(xls|XLS|xlsx|XLSX)$/.test(fileValueSuffix)) {
-		//根据后缀,判断是否符合OFFICE格式
-		return 'xls';
-	} else if (/(.*)\.(doc|DOC|docx|DOCX)$/.test(fileValueSuffix)) {
-		// 文档类型
-		return 'doc';
-	} else if (/(.*)\.(pdf|PDF)$/.test(fileValueSuffix)) {
-		// PDF
-		return 'pdf';
-	} else if (/(.*)\.(PPT|PPTX|ppt|pptx)$/.test(fileValueSuffix)) {
-		// ppt
-		return 'ppt';
-	}
-	return '';
-};
 // 清除重复件
 const clearRepeat = () => {
-	ruleFormRef.value.resetFields('repeat');
+	state.ruleForm.duplicateTitle = '';
+	state.ruleForm.duplicateId = '';
+	state.tableRadio = '';
 };
 // 选择重复件
 const selectRepat = () => {
-	HistoryOrderRef.value.openDialog();
+	HistoryOrderRef.value.openDialog(state.ruleForm.duplicateId);
 };
 // 弹窗确定选择重复件
 const saveSlect = (row: any) => {
-	console.log(row);
 	state.ruleForm.duplicateId = row.id;
-	state.ruleForm.duplicateName = row.name;
+	state.ruleForm.duplicateTitle = row.title;
+	state.tableRadio = row.id;
 	HistoryOrderRef.value.closeDialog();
 };
 // 右边表格选中重复件
 const handleSelectionChange = (row: any) => {
 	state.ruleForm.duplicateId = row.id;
-	state.ruleForm.duplicateName = row.name;
+	state.ruleForm.duplicateTitle = row.title;
 };
-const summary = {
-	Discriminate: 'Discriminate', //  甄别惯用语
-	Return: 'Return', // 退回惯用语
-	Archive: 'Archive', // 归档惯用语
-	Teti: 'Teti', // 特提惯用语
-	Seat: 'Seat', // 坐席惯用语
-	Circulation: 'Circulation', // 流转惯用语
-	ReturnVisit: 'ReturnVisit', // 回访惯用语
-	HandleAgain: 'HandleAgain', // 办理惯用语
-	Delay: 'Delay', // 延期惯用语
-	Supervise: 'Supervise', // 督办惯用语
-	KnowledgeLocution: 'KnowledgeLocution', // 知识诉求惯用语
+// 选择重复件
+const handleRowChange = (row: any) => {
+	state.ruleForm.duplicateId = row.id;
+	state.ruleForm.duplicateName = row.title;
 };
 // 打开常用意见管理
 const showComents = () => {
-	CommentRef.value.openDialog(summary.Seat);
+	CommentRef.value.openDialog(commonEeum.Seat);
 };
 // 添加到常用意见
 const onAddComments = async () => {
@@ -719,7 +865,7 @@ const onAddComments = async () => {
 		return;
 	}
 	await addCommon({
-		typeCode: summary.Seat,
+		typeCode: commonEeum.Seat,
 		content: state.ruleForm.content,
 	});
 	ElMessage.success('操作成功');
@@ -727,47 +873,53 @@ const onAddComments = async () => {
 };
 // 选中常用意见
 const chooseComment = (item: any) => {
-	state.ruleForm.content+=item.content;
+	state.ruleForm.content += item.content;
 	CommentRef.value.closeDialog();
 };
-// 返回相对应的字段
-const fileType = (file: string) => {
-	switch (file) {
-		case 'video':
-			return 'ele-VideoCamera';
-		case 'image':
-			return 'ele-Picture';
-		case 'xls':
-			return 'iconfont icon-excel';
-		case 'doc':
-			return 'ele-Document';
-		case 'pdf':
-			return 'iconfont icon-pdf';
-		case 'ppt':
-			return 'iconfont icon-ppt';
-		default:
-			break;
-	}
-};
 // 历史工单搜索
 const searchKnowledge = (value?: string) => {
 	if (value) state.KnowledgeKeyword = value;
 	state.loading = true;
-	setTimeout(() => {
-		state.loading = false;
-	}, 300);
+	state.loading = false;
 };
 // 办理工单
 const handleOrder = (val: any) => {
 	processRef.value.openDialog({ id: val, title: '提交' });
 };
-// 
-const hotsoptChange = (val)=>{
-	console.log(val);
-}
+/** 搜索按钮操作 */
+const handleQuery = () => {
+	state.queryParams.PageIndex = 1;
+	searchHistory();
+};
+/** 重置按钮操作 */
+const resetQuery = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	handleQuery();
+};
+/** 获取历史工单 */
+const searchHistory = () => {
+	state.loading = true;
+	let request = {
+		...state.queryParams,
+		PhoneNo: state.ruleForm.fromPhone,
+	};
+	historyOrder(request)
+		.then((response: any) => {
+			state.tableData = response?.result.items ?? [];
+			state.total = response?.result.total;
+			setTimeout(() => {
+				state.loading = false;
+			}, 300);
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
 onMounted(async () => {
-	getList(); //获取历史工单
-	let res: any = await orderBasedataAdd(); //基础数据
+	state.loading = true;
+	const area: any = await treeArea();
+	const res: any = await orderBasedataAdd(); //基础数据
 	state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
 	state.channelOptions = res.result?.channelOptions ?? [];
 	state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
@@ -775,9 +927,13 @@ onMounted(async () => {
 	state.identityTypeOptions = res.result?.identityTypeOptions ?? [];
 	state.orderTypeOptions = res.result?.orderTypeOptions ?? [];
 	state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+	state.licenceTypeOptions = res.result?.licenceTypeOptions ?? [];
+	state.ageRangeOptions = res.result?.ageRangeOptions ?? [];
 	state.ruleForm.seats = `${userInfos.value.name} [${userInfos.value.staffNo}]`;
 	//  route.query.createFrom  createFrom 代表来源  tel:来电弹单  letter:互联网来信 默认表示手动创建
 	if (route.query.createFrom) state.createFrom = route.query.createFrom;
+	state.areaOptions = area.result ?? []; //省市区数据
+	state.loading = false;
 });
 </script>
 
@@ -817,15 +973,7 @@ onMounted(async () => {
 }
 .workorder-container {
 	color: var(--hotline-color-text-main);
-	.left-content {
-		&-form {
-		}
-	}
-
 	.right-content {
-		&-box {
-		}
-
 		&-knowledge {
 			.knowledge-container {
 				position: relative;

+ 1022 - 0
src/views/business/order/orderAccept/edit.vue

@@ -0,0 +1,1022 @@
+<template>
+	<div class="workorder-container layout-padding">
+		<el-row :gutter="20" class="h100">
+			<!-- 左边工单信息 -->
+			<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="left-content mb20 h100">
+				<el-scrollbar class="box pd20">
+					<!-- <div class="flex-center-between mb20">
+						<p class="table-title">工单信息</p>
+					</div> -->
+					<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="110px" label-position="right" scroll-to-error v-loading="state.loading">
+						<p class="border-title mb10">来电信息</p>
+						<el-row :gutter="0">
+							<!-- 来源渠道 -->
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<!-- 手动创建 -->
+								<template v-if="state.createFrom == 'manual'">
+									<el-form-item label="来源渠道" prop="channel" :rules="[{ required: true, message: '请选择来源渠道', trigger: 'change' }]">
+										<el-select v-model="state.ruleForm.channel" placeholder="请选择来源渠道" class="w100">
+											<el-option v-for="item in state.channelOptions" :key="item.key" :label="item.value" :value="item.key" />
+										</el-select>
+									</el-form-item>
+								</template>
+								<!-- 来电弹单 -->
+								<template v-else-if="state.createFrom == 'tel'">
+									<el-form-item label="来源渠道">
+										<span>[{{ telStatusInfo.telsNo }}]</span>
+									</el-form-item>
+								</template>
+								<!-- 互联网来信 -->
+								<template v-else-if="state.createFrom == 'letter'">
+									<el-form-item label="来源渠道">
+										<span>[{{ telStatusInfo.telsNo }}]</span>
+									</el-form-item>
+								</template>
+							</el-col>
+							<!-- 转接来源 -->
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<!-- 手动创建 -->
+								<template v-if="state.createFrom == 'manual'">
+									<el-form-item label="转接来源" prop="transferPhone"> 暂无 </el-form-item>
+								</template>
+								<!-- 来电弹单 -->
+								<template v-else-if="state.createFrom == 'tel'">
+									<el-form-item label="转接来源">
+										<span>[{{ telStatusInfo.telsNo }}]</span>
+									</el-form-item>
+								</template>
+								<!-- 互联网来信 -->
+								<template v-else-if="state.createFrom == 'letter'">
+									<el-form-item label="转接来源">
+										<span>[{{ telStatusInfo.telsNo }}]</span>
+									</el-form-item>
+								</template>
+							</el-col>
+							<!-- 来电号码 -->
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="state.ruleForm.channel == 0">
+								<!-- 手动创建 -->
+								<template v-if="state.createFrom == 'manual'">
+									<el-form-item
+										label="来电号码"
+										prop="fromPhone"
+										:rules="[
+											{ required: true, message: '请填写来电号码', trigger: 'blur' },
+											// {
+											// 	pattern: /^(13[0-9]|14[01456879]|15[0-3,5-9]|16[2567]|17[0-8]|18[0-9]|19[0-3,5-9])d{8}$/,
+											// 	message: '手机号格式错误',
+											// 	trigger: 'blur'
+											// },
+										]"
+									>
+										<el-input v-model="state.ruleForm.fromPhone" placeholder="请填写来电号码" clearable @blur="searchHistory"> </el-input>
+									</el-form-item>
+								</template>
+								<!-- 来电弹单 -->
+								<template v-else-if="state.createFrom == 'tel'">
+									<el-form-item label="来电号码">
+										<span>[{{ telStatusInfo.telsNo }}]</span>
+									</el-form-item>
+								</template>
+								<!-- 互联网来信 -->
+								<template v-else-if="state.createFrom == 'letter'">
+									<el-form-item label="来电号码">
+										<span>[{{ phoneNumber }}]</span>
+									</el-form-item>
+								</template>
+							</el-col>
+							<!-- 服务坐席 -->
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="服务坐席">
+									<!-- 手动创建 -->
+									<template v-if="state.createFrom == 'manual'">
+										<span>{{ state.ruleForm.employeeName + ' [ ' + state.ruleForm.employeeStaffNo + ' ]' }}</span>
+									</template>
+									<!-- 来电弹单 -->
+									<template v-else-if="state.createFrom == 'tel'">
+										<span>[{{ telStatusInfo.telsNo }}]</span>
+									</template>
+									<!-- 互联网来信 -->
+									<template v-else-if="state.createFrom == 'letter'">
+										<span>[{{ telStatusInfo.telsNo }}]</span>
+									</template>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="来电/信人" prop="fromName" :rules="[{ required: true, message: '请填写来电/信人', trigger: 'blur' }]">
+									<el-input v-model="state.ruleForm.fromName" placeholder="请填写来电/信人" clearable> </el-input>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item
+									label="来电/信人性别"
+									prop="fromGender"
+									:rules="[{ required: true, message: '请选择来电/信人性别', trigger: 'change' }]"
+								>
+									<el-radio-group v-model="state.ruleForm.fromGender">
+										<el-radio :label="item.key" v-for="item in state.genderOptions" :key="item.key">{{ item.value }}</el-radio>
+									</el-radio-group>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item
+									label="来电/信人身份"
+									prop="identityType"
+									:rules="[{ required: true, message: '请选择来电/信人身份', trigger: 'change' }]"
+								>
+									<el-radio-group v-model="state.ruleForm.identityType">
+										<el-radio :label="item.key" v-for="item in state.identityTypeOptions" :key="item.key">{{ item.value }}</el-radio>
+									</el-radio-group>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="证件类型" prop="licenceTypeObj" :rules="[{ required: false, message: '请选择证件类型', trigger: 'change' }]">
+									<el-select
+										v-model="state.ruleForm.licenceTypeObj"
+										placeholder="请选择证件类型"
+										class="w100"
+										value-key="dicDataValue"
+										@change="(val:any)=>{state.ruleForm.licenceType = val.dicDataName;
+									state.ruleForm.licenceTypeCode = val.dicDataValue}"
+									>
+										<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="12" :xl="12">
+								<el-form-item
+									label="证件号码"
+									prop="licenceNo"
+									:rules="[{ required: state.ruleForm.licence || state.ruleForm.licence === 0, message: '请填写证件号码', trigger: 'blur' }]"
+								>
+									<el-input v-model="state.ruleForm.licenceNo" placeholder="请填写证件号码" clearable> </el-input>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="年龄段" prop="ageRangeObj" :rules="[{ required: false, message: '请选择年龄段', trigger: 'change' }]">
+									<el-select
+										v-model="state.ruleForm.ageRangeObj"
+										placeholder="请选择年龄段"
+										class="w100"
+										value-key="dicDataValue"
+										@change="(val:any)=>{state.ruleForm.ageRange = val.dicDataName;
+									state.ruleForm.ageRangeCode = val.dicDataValue}"
+									>
+										<el-option v-for="item in state.ageRangeOptions" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
+									</el-select>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item
+									label="联系电话"
+									prop="contact"
+									:rules="[{ required: !state.ruleForm.needContact, message: '请填写联系电话', trigger: 'blur' }]"
+								>
+									<el-input
+										v-model="state.ruleForm.contact"
+										:disabled="state.ruleForm.needContact"
+										:placeholder="state.ruleForm.needContact ? '无需联系' : '请填写联系电话'"
+										clearable
+									>
+									</el-input>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="" prop="acceptSms" :rules="[{ required: false, message: '请选择', trigger: 'blur' }]">
+									<el-checkbox v-model="state.ruleForm.acceptSms" label="受理短信" />
+									<el-checkbox v-model="state.ruleForm.needContact" label="无需联系" @change="(val:boolean)=> ruleFormRef.resetFields('contact')" />
+								</el-form-item>
+							</el-col>
+							<!-- 当“来电/信人身份”为“企业”时必填 -->
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-form-item
+									label="工作单位"
+									prop="company"
+									:rules="[{ required: state.ruleForm.identityType === 2, message: '请填写工作单位', trigger: 'blur' }]"
+								>
+									<el-input v-model="state.ruleForm.company" placeholder="请填写工作单位" clearable> </el-input>
+								</el-form-item>
+							</el-col>
+						</el-row>
+						<p class="border-title mb10">诉求信息</p>
+						<el-row>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="工单编码"> {{ state.ruleForm.no }} </el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-form-item label="工单标题" prop="title" :rules="[{ required: true, message: '请填写工单标题', trigger: 'blur' }]">
+									<el-input v-model="state.ruleForm.title" placeholder="请填写工单标题" clearable> </el-input>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-row :gutter="0">
+									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+										<el-form-item label="工单类型" prop="orderType" :rules="[{ required: true, message: '请填写工单类型', trigger: 'blur' }]">
+											<el-select v-model="state.ruleForm.orderType" placeholder="请选择工单类型" class="w100" @change="selectOrderType">
+												<el-option v-for="item in state.orderTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+											</el-select>
+										</el-form-item>
+									</el-col>
+									<!-- 当“工单类型”为非通用工单时,展示【拓展信息】按钮 -->
+									<el-col :xs="6" :sm="6" :md="6" :lg="6" :xl="6" :offset="1" v-if="state.ruleForm.orderType === 1 && state.ruleForm.acceptType">
+										<el-form-item label="" label-width="0px">
+											<el-button @click="showExpandForm"><SvgIcon name="ele-CirclePlus" class="mr3" size="16px" /> 拓展信息</el-button>
+										</el-form-item>
+									</el-col>
+								</el-row>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="受理类型" prop="acceptType" :rules="[{ required: true, message: '请选择受理类型', trigger: 'change' }]">
+									<el-select v-model="state.ruleForm.acceptType" placeholder="请选择受理类型" class="w100">
+										<el-option
+											v-for="item in state.acceptTypeOptions"
+											:key="item.key"
+											:disabled="item.disabled"
+											:label="item.value"
+											:value="item.key"
+										/>
+									</el-select>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="紧急程度" prop="emergencyLevel" :rules="[{ required: true, message: '请选择紧急程度', trigger: 'change' }]">
+									<el-select v-model="state.ruleForm.emergencyLevel" placeholder="请选择紧急程度" class="w100">
+										<el-option v-for="item in state.emergencyLevelOptions" :key="item.key" :label="item.value" :value="item.key" />
+									</el-select>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-form-item label="热点分类" prop="hotspotId" :rules="[{ required: true, message: '请选择热点分类', trigger: 'change' }]">
+									<el-tree-select
+										class="w100"
+										v-model="state.ruleForm.hotspotId"
+										filterable
+										clearable
+										placeholder="请选择热点分类"
+										:props="HotspotProps"
+										lazy
+										:load="load"
+										node-key="id"
+										check-strictly
+										:render-after-expand="false"
+										@node-click="hotsoptChange"
+										ref="hotspotRef"
+										:default-expanded-keys="state.hotspotExternal"
+									/>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="事发时间" prop="incidentTime" :rules="[{ required: false, message: '请选择事发时间', trigger: 'change' }]">
+									<el-date-picker v-model="state.ruleForm.incidentTime" type="date" placeholder="请选择事发时间" format="YYYY-MM-DD" class="w100" />
+									<!-- value-format="YYYY-MM-DD" -->
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-row :gutter="0">
+									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+										<el-form-item label="事发地址" prop="areaCode" :rules="[{ required: true, message: '请选择事发地址', trigger: 'change' }]">
+											<el-cascader
+												:options="state.areaOptions"
+												filterable
+												:props="{ value: 'id', label: 'areaName', emitPath: false }"
+												placeholder="请选择事发地址"
+												clearable
+												class="w100"
+												v-model="state.ruleForm.areaCode"
+												ref="areaRef"
+												@change="changeArea"
+											>
+												<template #default="{ node, data }">
+													<span>{{ data.areaName }}</span>
+													<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+												</template>
+											</el-cascader>
+										</el-form-item>
+									</el-col>
+									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+										<el-form-item label="" prop="street" :rules="[{ required: true, message: '请填写详细地址', trigger: 'blur' }]" label-width="10px">
+											<el-input v-model="state.ruleForm.street" placeholder="请填写详细地址" clearable> </el-input>
+										</el-form-item>
+									</el-col>
+								</el-row>
+							</el-col>
+
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+								<el-row :gutter="0">
+									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+										<el-form-item label="是否重复" prop="isRepeat" :rules="[{ required: true, message: '请选择是否重复', trigger: 'change' }]">
+											<el-select v-model="state.ruleForm.isRepeat" placeholder="请选择是否重复" class="w100">
+												<el-option v-for="item in state.repeatOptions" :key="item.key" :label="item.value" :value="item.key" />
+											</el-select>
+										</el-form-item>
+									</el-col>
+									<!-- 必填,若“是否重复”为“是”,则展示重复件选择框 -->
+									<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="state.ruleForm.isRepeat === 'true'">
+										<el-form-item
+											label=""
+											prop="duplicateTitle"
+											label-width="10px"
+											:rules="[{ required: true, message: '请选择重复件', trigger: 'change' }]"
+										>
+											<el-input v-model="state.ruleForm.duplicateTitle" placeholder="请选择重复件" readonly>
+												<template #suffix>
+													<el-button link type="danger" v-if="state.ruleForm.duplicateTitle" @click="clearRepeat">
+														<SvgIcon name="ele-Delete" size="16px" />
+													</el-button>
+													<el-button link type="primary" class="ml1" @click="selectRepat">
+														<SvgIcon name="iconfont icon-tianjiatuozhanxinxi" size="18px" />
+													</el-button>
+												</template>
+											</el-input>
+										</el-form-item>
+									</el-col>
+								</el-row>
+							</el-col>
+							<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
+								<el-form-item label="推送分类" prop="pushTypeObj" :rules="[{ required: false, message: '请选择推送分类', trigger: 'change' }]">
+									<el-select
+										v-model="state.ruleForm.pushTypeObj"
+										placeholder="请选择推送分类"
+										class="w100"
+										clearable
+										value-key="dicDataValue"
+										@change="(val:any)=>{state.ruleForm.pushType = val.dicDataName;
+									state.ruleForm.pushTypeCode = val.dicDataValue}"
+									>
+										<el-option v-for="item in state.pushTypeOptions" :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="content"
+									class="textarea"
+									:rules="[{ required: true, message: '请填写诉求详情', trigger: 'blur' }]"
+								>
+									<el-input
+										v-model="state.ruleForm.content"
+										type="textarea"
+										:autosize="{ minRows: 10, maxRows: 20 }"
+										placeholder="请填写诉求详情"
+										clearable
+										maxlength="2000"
+									>
+									</el-input>
+									<span class="bttons">
+										<el-button @click="showComents" class="default-button" :loading="state.loading">常用意见</el-button>
+										<el-button type="primary" @click="onAddComments" :loading="state.loading">添加到常用意见</el-button>
+									</span>
+								</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' }]">
+									<el-upload
+										v-model:file-list="fileList"
+										class="upload-demo w100"
+										action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
+										multiple
+										:before-remove="beforeRemove"
+										:on-exceed="handleExceed"
+										ref="uploadListRef"
+									>
+										<el-button> <SvgIcon name="ele-Upload" /> 上传附件 </el-button>
+										<template #file="{ file }">
+											<div class="el-upload-list__item-info">
+												<a class="el-upload-list__item-name">
+													<SvgIcon class="mr5" :name="fileType(checkFile(file.name))" size="16px" />
+													<span class="el-upload-list__item-file-name">{{ file.name }}</span>
+												</a>
+											</div>
+											<SvgIcon name="ele-Close" class="el-icon--close" size="14px" title="删除文件" @click="handleRemove(file)" />
+										</template>
+									</el-upload>
+								</el-form-item>
+							</el-col>
+							<el-col :xs="24" :sm="12" :md="24" :lg="24" :xl="24">
+								<el-form-item>
+									<el-button class="default-button" @click="save"> 保存 </el-button>
+									<el-button type="primary" v-waves @click="submit"> 提交 </el-button>
+								</el-form-item>
+							</el-col>
+						</el-row>
+					</el-form>
+				</el-scrollbar>
+			</el-col>
+			<!-- 右侧内容 -->
+			<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="right-content h100">
+				<el-scrollbar>
+					<div class="right-content-box box pd20">
+						<!-- <el-tabs v-model="state.activeName">
+							<el-tab-pane label="历史工单" name="first"> </el-tab-pane>
+							<el-tab-pane label="市民画像" name="second"> 市民画像 </el-tab-pane>
+						</el-tabs> -->
+						<el-form :model="state.queryParams" ref="queryParamsRef" :inline="true" @submit.native.prevent>
+							<el-form-item label="关键词" prop="Keyword">
+								<el-input v-model="state.queryParams.Keyword" placeholder="工单标题/工单编码" clearable @keyup.enter="handleQuery" />
+							</el-form-item>
+							<el-form-item>
+								<el-button type="primary" @click="handleQuery" :loading="state.loading" v-waves>
+									<SvgIcon name="ele-Search" class="mr5" />查询
+								</el-button>
+								<el-button @click="resetQuery(queryParamsRef)" v-waves class="default-button">
+									<SvgIcon name="ele-Refresh" class="mr5" />重置
+								</el-button>
+							</el-form-item>
+						</el-form>
+						<el-table :data="state.tableData" v-loading="state.loading" @current-change="handleSelectionChange">
+							<el-table-column prop="phoneNo" label="重复件" width="70" v-if="state.ruleForm.isRepeat === 'true'">
+								<template #default="scope">
+									<el-radio v-model="state.tableRadio" :label="scope.row.id" @change="handleRowChange(scope.row)">&nbsp;</el-radio>
+								</template>
+							</el-table-column>
+							<el-table-column type="index" width="60" label="序号" />
+							<el-table-column prop="phoneNo" label="工单标题" show-overflow-tooltip>
+								<template #default="scope">
+									<span style="color: var(--el-color-primary)">{{ scope.row.title }}</span>
+								</template>
+							</el-table-column>
+							<el-table-column prop="hotspot" label="热点分类" show-overflow-tooltip> </el-table-column>
+							<el-table-column prop="no" label="工单编码" show-overflow-tooltip> </el-table-column>
+							<el-table-column prop="currentStepName" label="当前环节" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="statusText" label="状态" width="70" fixed="right" align="center">
+								<template #default="scope">
+									<el-button text type="primary">
+										{{ scope.row.statusText }}
+									</el-button>
+								</template>
+							</el-table-column>
+						</el-table>
+						<!-- 分页 -->
+						<pagination
+							:total="state.total"
+							v-model:page="state.queryParams.PageIndex"
+							v-model:limit="state.queryParams.PageSize"
+							@pagination="searchHistory"
+						/>
+					</div>
+					<div class="right-content-knowledge mt20 box pd20">
+						<div class="flex-center-between mb20">
+							<p class="table-title">知识检索</p>
+						</div>
+						<div class="knowledge-container">
+							<el-input
+								v-model="state.KnowledgeKeyword"
+								class="knowledge-input mb20"
+								placeholder="请填写搜索内容"
+								clearable
+								@keyup.enter="searchKnowledge(state.KnowledgeKeyword)"
+							>
+								<template #prefix>
+									<SvgIcon name="ele-Search" size="16px" />
+								</template>
+								<template #suffix>
+									<el-button
+										class="knowledge-search-button"
+										type="primary"
+										:loading="state.loading"
+										round
+										@click="searchKnowledge(state.KnowledgeKeyword)"
+									>
+										<SvgIcon name="ele-Search" size="16px" color="#fff" />
+									</el-button>
+								</template>
+							</el-input>
+							<div>
+								<span class="mr10">搜索热词</span>
+								<el-tag
+									v-for="item in state.items"
+									:key="item.label"
+									class="mr5 mb10"
+									style="cursor: pointer"
+									@click="searchKnowledge(item.label)"
+									:type="item.type"
+								>
+									{{ item.label }}
+								</el-tag>
+							</div>
+							<ul class="mt10" v-loading="state.loading">
+								<li v-for="(item, index) in state.knowledgeList" :key="index" class="mb20">
+									<p class="font16">
+										<SvgIcon name="iconfont icon-dian" size="16px" /> <b>{{ item.title }}</b>
+									</p>
+									<p class="pt6 indent">{{ item.content }}</p>
+								</li>
+							</ul>
+						</div>
+					</div>
+				</el-scrollbar>
+			</el-col>
+		</el-row>
+		<!-- 拓展表单 -->
+		<ExpandForm ref="ExpandFormRef" @saveExpandForm="saveExpandForm" />
+		<!-- 常用意见管理 -->
+		<Comment ref="CommentRef" @chooseComment="chooseComment" modal />
+		<!-- 历史工单 -->
+		<History ref="HistoryOrderRef" @saveSlect="saveSlect" />
+		<!-- 提交流程 -->
+		<Process ref="processRef" @handle="handleOrder" />
+	</div>
+</template>
+
+<script setup lang="ts" name="orderAcceptEdit">
+import { defineAsyncComponent, ref, reactive, computed, onMounted, nextTick } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import type { UploadProps, UploadUserFile, FormInstance } from 'element-plus';
+import { storeToRefs } from 'pinia';
+import { useRoute, useRouter } from 'vue-router';
+import { useTelStatus } from '/@/stores/telStatus';
+import { desensitizationPhone, checkFile, fileType, commonEeum } from '/@/utils/tools';
+import { orderBasedataAdd, hotspottype, historyOrder, orderDetail, orderEdit } from '/@/api/business/order';
+import { useUserInfo } from '/@/stores/userInfo';
+import { addCommon, treeArea } from '/@/api/business/commonP';
+import mittBus from '/@/utils/mitt';
+
+// 引入组件
+const Process = defineAsyncComponent(() => import('/@/views/business/order/components/Process.vue'));
+const ExpandForm = defineAsyncComponent(() => import('/@/views/business/order/components/ExpandForm.vue'));
+const History = defineAsyncComponent(() => import('/@/views/business/order/components/History.vue'));
+const Comment = defineAsyncComponent(() => import('/@/views/business/order/components/Comment.vue'));
+// 定义变量内容
+const state = reactive<any>({
+	createFrom: 'manual', // 工单创建方式 默认手动创建  tel:来电弹单  letter:互联网来信 默认表示手动创建
+	activeName: 'first', // tabs
+	ruleForm: {
+		// 表单
+		street: '',
+		transferPhone: '',
+		employeeName: '',
+		employeeStaffNo: '',
+		duplicateTitle: '',
+		duplicateId: '',
+	},
+	acceptTypeOptions: [], // 受理类型
+	channelOptions: [], // 来源频道
+	emergencyLevelOptions: [], // 紧急程度
+	genderOptions: [], // 性别
+	identityTypeOptions: [], //来电人身份
+	licenceTypeOptions: [], // 证件类型
+	ageRangeOptions: [], // 年龄段
+	orderTypeOptions: [], // 工单类型
+	pushTypeOptions: [], //推送分类
+	areaOptions: [], //省市区
+	repeatOptions: [
+		//是否重复
+		{
+			value: '是',
+			key: 'true',
+		},
+		{
+			value: '否',
+			key: 'false',
+		},
+	],
+	tableRadio: null as any, // 重复件选择
+	orgData: [],
+	tableData: [], // 历史工单
+	total: 0,
+	loading: false,
+	queryParams: {
+		PageIndex: 1,
+		PageSize: 10,
+		Keyword: '',
+	},
+	KnowledgeKeyword: '', //知识检索内容
+	items: [],
+	knowledgeList: [],//知识检索列表
+	external: [],
+	hotspotExternal: [], // 热点分类展开
+});
+const ruleFormRef = ref();
+const queryParamsRef = ref();
+const useTelStatusStore = useTelStatus();
+const { telStatusInfo } = storeToRefs(useTelStatusStore);
+const uploadListRef = ref();
+const processRef = ref();
+const storesUserInfo = useUserInfo();
+const { userInfos } = storeToRefs(storesUserInfo);
+state.ruleForm.employeeName = userInfos.value.name;
+state.ruleForm.employeeStaffNo = userInfos.value.staffNo;
+const route = useRoute();
+const router = useRouter();
+const HistoryOrderRef = ref();
+const CommentRef = ref();
+const hotspotRef = ref();
+// 热点分类远程搜索
+const HotspotProps = {
+	label: 'hotSpotFullName',
+	children: 'children',
+	isLeaf: 'isLeaf',
+};
+// 热点分类懒加载
+const load = async (node: any, resolve: any) => {
+	if (node.isLeaf) return resolve([]);
+	const res: any = await hotspottype({ id: node.data.id ? node.data.id : '' });
+	resolve(res.result);
+};
+// 选择热点分类
+const hotsoptChange = (val: any, e: any) => {
+	state.hotspotExternal = [];
+	state.external = [];
+	state.hotspotExternal = getParentId(e, state.external);
+	state.ruleForm.hotspotSpliceName = val.hotSpotFullName;
+	state.ruleForm.hotspot = val.hotSpotName;
+};
+// 递归查找父级Id
+const getParentId = (val: any, arr: string[]) => {
+	if (val.data.parentId) {
+		arr.push(val.data.parentId);
+		getParentId(val.parent, arr);
+	}
+	return arr;
+};
+// 手机号码脱敏处理
+const phoneNumber = computed(() => {
+	return desensitizationPhone(telStatusInfo.value.onCallArr[0]?.from);
+});
+const fileList = ref<UploadUserFile[]>([]);
+// 删除确认
+const beforeRemove: UploadProps['beforeRemove'] = (uploadFile) => {
+	return ElMessageBox.confirm(`确定要删除 ${uploadFile.name} ?`).then(
+		() => true,
+		() => false
+	);
+};
+// 删除文件
+const handleRemove = (file: any) => {
+	uploadListRef.value.handleRemove(file);
+};
+
+const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
+	ElMessage.warning(`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + uploadFiles.length} totally`);
+};
+// 选择工单类型 处理受理类型选择数据
+const selectOrderType = (val: any) => {
+	ruleFormRef.value.resetFields('acceptType');
+	if (val === 1) {
+		// 选择了12315市场监管受理单
+		state.acceptTypeOptions = state.acceptTypeOptions.map((item: any) => {
+			if (item.key === 5 || item.key === 6) {
+				//直接投诉或者建议
+				return {
+					key: item.key,
+					value: item.value,
+					disabled: false,
+				};
+			} else {
+				return {
+					key: item.key,
+					value: item.value,
+					disabled: true,
+				};
+			}
+		});
+	} else {
+		state.acceptTypeOptions = state.acceptTypeOptions.map((item: any) => {
+			return {
+				key: item.key,
+				value: item.value,
+				disabled: false,
+			};
+		});
+	}
+};
+const areaRef = ref();
+// 选择省市区
+const changeArea = () => {
+	const currentNode = areaRef.value.getCheckedNodes();
+	state.ruleForm.province = currentNode[0].pathLabels[0];
+	state.ruleForm.city = currentNode[0].pathLabels[1];
+	state.ruleForm.county = currentNode[0].pathLabels[2];
+};
+const ExpandFormRef = ref();
+// 打开拓展表单
+const showExpandForm = () => {
+	ExpandFormRef.value.openDialog(state.ruleForm.acceptType);
+};
+// 拓展表单保存
+const saveExpandForm = (val: any) => {
+	switch (state.ruleForm.acceptType) {
+		case 5: //举报
+			state.ruleForm.orderReport = val;
+			break;
+		case 6: //投诉
+			state.ruleForm.orderComplain = val;
+			break;
+		default:
+			break;
+	}
+};
+// 保存
+const save = () => {
+	ruleFormRef.value.validate((valid: boolean) => {
+		if (valid) {
+			state.ruleForm.hotspotExternal = state.hotspotExternal.join(',');
+			let submitObj = JSON.parse(JSON.stringify(state.ruleForm));
+			Reflect.deleteProperty(submitObj, 'ageRangeObj'); // 删除无用的参数 年龄段
+			Reflect.deleteProperty(submitObj, 'pushTypeObj'); // 删除无用的参数 推送分类
+			Reflect.deleteProperty(submitObj, 'licenceTypeObj'); // 删除无用的参数 证件类型
+			if (submitObj.acceptType === 5) Reflect.deleteProperty(submitObj, 'orderComplain'); // 举报 删除投诉表单
+			if (submitObj.acceptType === 6) Reflect.deleteProperty(submitObj, 'orderReport'); // 投诉 删除举报表单
+			if (submitObj.orderType === 1 && submitObj.acceptType) {
+				//拓展表单
+				if (ExpandFormRef.value.state.validated) {
+					//验证通过
+					orderEdit(submitObj).then(() => {
+						ElMessage.success('操作成功');
+						router.push({
+							path: '/business/order',
+						});
+						// 关闭当前 tagsView
+						mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
+						mittBus.emit('refreshList');
+					});
+				} else {
+					//不通过 展示弹窗
+					ExpandFormRef.value.openDialog(submitObj.acceptType, true); // 立即提交展示验证
+				}
+			} else {
+				// 修改
+				orderEdit(submitObj).then(() => {
+					ElMessage.success('操作成功');
+					router.push({
+						path: '/business/order',
+					});
+					// 关闭当前 tagsView
+					mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
+					mittBus.emit('refreshList');
+				});
+			}
+		} else {
+			return false;
+		}
+	});
+};
+// 提交
+const submit = () => {
+	ruleFormRef.value.validate((valid: boolean) => {
+		if (valid) {
+			state.ruleForm.hotspotExternal = state.hotspotExternal.join(',');
+			let submitObj = JSON.parse(JSON.stringify(state.ruleForm));
+			Reflect.deleteProperty(submitObj, 'ageRangeObj'); // 删除无用的参数 年龄段
+			Reflect.deleteProperty(submitObj, 'pushTypeObj'); // 删除无用的参数 推送分类
+			Reflect.deleteProperty(submitObj, 'licenceTypeObj'); // 删除无用的参数 证件类型
+			if (submitObj.acceptType === 5) Reflect.deleteProperty(submitObj, 'orderComplain'); // 举报 删除投诉表单
+			if (submitObj.acceptType === 6) Reflect.deleteProperty(submitObj, 'orderReport'); // 投诉 删除举报表单
+			if (submitObj.orderType === 1 && submitObj.acceptType) {
+				//拓展表单
+				if (ExpandFormRef.value.state.validated) {
+					// 修改
+					orderEdit(submitObj).then(() => {
+						ElMessage.success('操作成功');
+						processRef.value.openDialog({ id: route.params.id, title: '提交', commonEeum: commonEeum.Seat, start: true });
+					});
+				} else {
+					//不通过 展示弹窗
+					ExpandFormRef.value.openDialog(submitObj.acceptType, true); // 立即提交展示验证
+				}
+			} else {
+				// 修改
+				orderEdit(submitObj).then(() => {
+					ElMessage.success('操作成功');
+					processRef.value.openDialog({ id: route.params.id, title: '提交', commonEeum: commonEeum.Seat, start: true });
+				});
+			}
+		} else {
+			return false;
+		}
+	});
+};
+// 清除重复件
+const clearRepeat = () => {
+	state.ruleForm.duplicateTitle = '';
+	state.ruleForm.duplicateId = '';
+	state.tableRadio = '';
+};
+// 选择重复件
+const selectRepat = () => {
+	HistoryOrderRef.value.openDialog(state.ruleForm.duplicateId);
+};
+// 弹窗确定选择重复件
+const saveSlect = (row: any) => {
+	state.ruleForm.duplicateId = row.id;
+	state.ruleForm.duplicateTitle = row.title;
+	state.tableRadio = row.id;
+	HistoryOrderRef.value.closeDialog();
+};
+// 右边表格选中重复件
+const handleSelectionChange = (row: any) => {
+	state.ruleForm.duplicateId = row.id;
+	state.ruleForm.duplicateTitle = row.title;
+};
+// 选择重复件
+const handleRowChange = (row: any) => {
+	state.ruleForm.duplicateId = row.id;
+	state.ruleForm.duplicateName = row.title;
+};
+// 打开常用意见管理
+const showComents = () => {
+	CommentRef.value.openDialog(commonEeum.Seat);
+};
+// 添加到常用意见
+const onAddComments = async () => {
+	if (!state.ruleForm.content) {
+		ElMessage.warning('请先输入诉求详情');
+		return;
+	}
+	await addCommon({
+		typeCode: commonEeum.Seat,
+		content: state.ruleForm.content,
+	});
+	ElMessage.success('操作成功');
+	CommentRef.value.closeDialog();
+};
+// 选中常用意见
+const chooseComment = (item: any) => {
+	state.ruleForm.content += item.content;
+	CommentRef.value.closeDialog();
+};
+// 历史工单搜索
+const searchKnowledge = (value?: string) => {
+	if (value) state.KnowledgeKeyword = value;
+	state.loading = true;
+	state.loading = false;
+};
+// 办理工单
+const handleOrder = (val: any) => {
+	processRef.value.openDialog({ id: val, title: '提交' });
+};
+/** 搜索按钮操作 */
+const handleQuery = () => {
+	state.queryParams.PageIndex = 1;
+	searchHistory();
+};
+/** 重置按钮操作 */
+const resetQuery = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	handleQuery();
+};
+/** 获取历史工单 */
+const searchHistory = () => {
+	state.loading = true;
+	let request = {
+		...state.queryParams,
+		PhoneNo: state.ruleForm.fromPhone,
+	};
+	historyOrder(request)
+		.then((response: any) => {
+			state.tableData = response?.result.items ?? [];
+			state.total = response?.result.total;
+			setTimeout(() => {
+				state.loading = false;
+			}, 300);
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
+onMounted(async () => {
+	nextTick(async () => {
+		if (route.params.id) {
+			state.loading = true;
+			const area: any = await treeArea();
+			const res: any = await orderBasedataAdd(); //基础数据
+			state.acceptTypeOptions = res.result?.acceptTypeOptions ?? [];
+			state.channelOptions = res.result?.channelOptions ?? [];
+			state.emergencyLevelOptions = res.result?.emergencyLevelOptions ?? [];
+			state.genderOptions = res.result?.genderOptions ?? [];
+			state.identityTypeOptions = res.result?.identityTypeOptions ?? [];
+			state.orderTypeOptions = res.result?.orderTypeOptions ?? [];
+			state.pushTypeOptions = res.result?.pushTypeOptions ?? [];
+			state.licenceTypeOptions = res.result?.licenceTypeOptions ?? [];
+			state.ageRangeOptions = res.result?.ageRangeOptions ?? [];
+			state.ruleForm.seats = `${userInfos.value.name} [${userInfos.value.staffNo}]`;
+			state.areaOptions = area.result ?? []; //省市区数据
+			// 如果获取到id 调用查询详情
+			const response: any = await orderDetail(route.params.id);
+			state.ruleForm = response.result;
+			if (state.ruleForm.channel === 0) {
+				// 来源渠道为电话查询历史工单
+				searchHistory();
+			}
+			if (state.ruleForm.orderType === 1) {
+				// 工单类型 选择了12315市场监管受理单
+				state.acceptTypeOptions = state.acceptTypeOptions.map((item: any) => {
+					if (item.key === 5 || item.key === 6) {
+						//直接投诉或者建议
+						return {
+							key: item.key,
+							value: item.value,
+							disabled: false,
+						};
+					} else {
+						return {
+							key: item.key,
+							value: item.value,
+							disabled: true,
+						};
+					}
+				});
+			}
+			if (state.ruleForm.duplicateId) {
+				// 是否重复
+				state.ruleForm.isRepeat = 'true';
+				state.tableRadio = state.ruleForm.duplicateId;
+			} else {
+				state.ruleForm.isRepeat = 'false';
+			}
+			if (state.ruleForm.hotspotExternal) {
+				//热点分类默认展开
+				state.hotspotExternal = state.ruleForm.hotspotExternal.split(',');
+			}
+			state.ruleForm.ageRangeObj = {
+				// 年龄段
+				dicDataValue: state.ruleForm.ageRangeCode,
+				dicDataName: state.ruleForm.ageRange,
+			};
+			state.ruleForm.licenceTypeObj = {
+				// 证件类型
+				dicDataValue: state.ruleForm.licenceTypeCode,
+				dicDataName: state.ruleForm.licenceType,
+			};
+			state.ruleForm.pushTypeObj = {
+				// 推送分类
+				dicDataValue: state.ruleForm.pushTypeCode,
+				dicDataName: state.ruleForm.pushType,
+			};
+			state.loading = false;
+		} else {
+			ElMessage.warning('参数有误,请重新进入');
+			state.loading = false;
+		}
+	});
+});
+</script>
+
+<style scoped lang="scss">
+.box {
+	background-color: var(--el-color-white);
+	border-radius: 8px;
+}
+.upload-demo {
+	:deep(.el-upload-list) {
+		display: flex;
+		flex-wrap: wrap;
+		.el-upload-list__item {
+			width: calc(25% - 10px);
+			border: var(--el-border);
+			margin-right: 10px;
+		}
+	}
+}
+:deep(.el-divider--horizontal) {
+	margin-top: 0;
+}
+.border-title {
+	font-size: var(--el-font-size-medium);
+	line-height: var(--el-font-size-medium);
+	color: var(--el-color-primary);
+	border-left: 4px solid var(--el-color-primary);
+	padding-left: 7px;
+}
+.textarea {
+	position: relative;
+	.bttons {
+		position: absolute;
+		right: 10px;
+		bottom: 10px;
+	}
+}
+.workorder-container {
+	color: var(--hotline-color-text-main);
+	.right-content {
+		&-knowledge {
+			.knowledge-container {
+				position: relative;
+				.knowledge-input {
+					:deep(.el-input__wrapper) {
+						border-radius: 20px;
+						background: var(--hotline-bg-main-color);
+					}
+				}
+				.knowledge-search-button {
+					height: calc(100% - 6px);
+				}
+				.indent {
+					text-indent: 1em;
+					color: var(--hotline-color-text-main-light);
+					line-height: 20px;
+					text-overflow: -o-ellipsis-lastline;
+					overflow: hidden; //溢出内容隐藏
+					text-overflow: ellipsis; //文本溢出部分用省略号表示
+					display: -webkit-box; //特别显示模式
+					-webkit-line-clamp: 2; //行数
+					line-clamp: 2;
+					-webkit-box-orient: vertical; //盒子中内容竖直排列
+				}
+			}
+		}
+	}
+}
+</style>

+ 1 - 1
src/views/businessManage/workOrderReturnVist/index.vue → src/views/business/orderReturnVist/index.vue

@@ -6,7 +6,7 @@
     </div>
 </template>
 
-<script setup lang="ts" name="workOrderReturnVisit">
+<script setup lang="ts" name="orderReturnVist">
 
 </script>
 

+ 1 - 1
src/views/businessManage/qualityManage/index.vue → src/views/business/quality/index.vue

@@ -6,7 +6,7 @@
     </div>
 </template>
 
-<script setup lang="ts" name="qualityManage">
+<script setup lang="ts" name="quality">
 
 </script>
 

+ 0 - 0
src/views/businessManage/screeningRequest/index.vue → src/views/business/screening/index.vue


+ 0 - 719
src/views/businessManage/workOrderManage/components/ExpandForm.vue

@@ -1,719 +0,0 @@
-<template>
-	<div>
-		<el-dialog v-model="state.isShowDialog" width="80%" draggable title="拓展信息" append-to-body>
-			<el-form :model="state.expandForm" ref="expandFormRef" label-width="120px">
-				<el-row :gutter="20">
-					<el-col :xs="24" :sm="24" :md="8" :lg="6" :xl="6">
-						<el-form-item label="工单类型"> 12315市场监管局受理单 </el-form-item>
-					</el-col>
-					<el-col :xs="24" :sm="24" :md="8" :lg="6" :xl="6">
-						<el-form-item label="受理类型">
-							{{ state.type === 1 ? '投诉' : '举报' }}
-						</el-form-item>
-					</el-col>
-					<!-- 投诉 -->
-					<template v-if="state.type === 1">
-						<el-divider content-position="left"><b class="formTitle">投诉人信息</b></el-divider>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="证件类型" prop="licenceTypeCode" :rules="[{ required: false, message: '请选择证件类型', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.licenceTypeCode" placeholder="请选择证件类型" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-                        <!-- 选择了证件类型必填 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="证件号码" prop="licenceNo" :rules="[{ required: true, message: '请填写证件号码', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.licenceNo" placeholder="请填写证件号码" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="提供方类型" prop="providerType" :rules="[{ required: false, message: '请选择提供方类型', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.providerType" placeholder="请选择提供方类型" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="提供方身份" prop="providerStatus" :rules="[{ required: false, message: '请选择提供方身份', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.providerStatus" placeholder="请选择提供方身份" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="国籍/地区" prop="nationCode" :rules="[{ required: false, message: '请选择国籍/地区', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.nationCode" placeholder="请选择国籍/地区" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="民族" prop="nation" :rules="[{ required: false, message: '请选择民族', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.nation" placeholder="请选择民族" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="邮政编码" prop="postalCode" :rules="[{ required: false, message: '请填写邮政编码', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.postalCode" placeholder="请填写邮政编码" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="邮箱" prop="email" :rules="[{ required: false, message: '请填写邮箱', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.email" placeholder="请填写邮箱" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="其他联系方式" prop="otherContact" :rules="[{ required: false, message: '请填写其他联系方式', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.otherContact" placeholder="请填写其他联系方式" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-divider content-position="left"><b class="formTitle">投诉对象信息</b></el-divider>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="企业名称" prop="enterpriseName" :rules="[{ required: true, message: '请填写企业名称', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.enterpriseName" placeholder="请填写企业名称" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item
-								label="统一社会信用代码"
-								prop="unifiedSocialCreditCode"
-								:rules="[{ required: false, message: '请填写统一社会信用代码', trigger: 'blur' }]"
-							>
-								<el-input v-model="state.expandForm.unifiedSocialCreditCode" placeholder="请填写统一社会信用代码" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="注册地址" prop="registerAddress" :rules="[{ required: true, message: '请填写注册地址', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.registerAddress" placeholder="请填写注册地址" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="注册号" prop="registerNumber" :rules="[{ required: false, message: '请填写注册号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.registerNumber" placeholder="请填写注册号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="企业联系人" prop="enterpriseContact" :rules="[{ required: false, message: '请填写企业联系人', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.enterpriseContact" placeholder="请填写企业联系人" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item
-								label="市场主体类型"
-								prop="marketTypeCode"
-								:rules="[{ required: false, message: '请选择市场主体类型', trigger: 'change' }]"
-							>
-								<el-select v-model="state.expandForm.marketTypeCode" placeholder="请选择市场主体类型" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="行业分类" prop="industryClassifyCode" :rules="[{ required: false, message: '请选择行业分类', trigger: 'blur' }]">
-								<el-select v-model="state.expandForm.industryClassifyCode" placeholder="请选择行业分类" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-divider content-position="left"><b class="formTitle">投诉详情</b></el-divider>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="商品分类/品牌" prop="brandCode" :rules="[{ required: true, message: '请选择商品分类/品牌', trigger: 'blur' }]">
-								<el-tree-select
-									class="w100"
-									v-model="state.expandForm.brandCode"
-									filterable
-									:data="state.orgData"
-									multiple
-									:render-after-expand="false"
-									show-checkbox
-									placeholder="请选择商品分类/品牌"
-									node-key="id"
-									:props="{ label: 'orgName' }"
-								/>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item
-								label="争议发生时间"
-								prop="occurrenceTime"
-								:rules="[{ required: true, message: '请选择争议发生时间', trigger: 'change' }]"
-							>
-								<el-date-picker
-									v-model="state.expandForm.occurrenceTime"
-									type="datetime"
-									placeholder="请选择争议发生时间"
-									format="YYYY-MM-DD hh:mm:ss"
-									value-format="YYYY-MM-DD h:m:s a"
-									class="w100"
-								/>
-							</el-form-item>
-						</el-col>
-                        <!-- 只能填写数字,且只能填写非负数 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="消费金额" prop="amount" :rules="[{ required: true, message: '请填写消费金额', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.amount" placeholder="请填写消费金额" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="客体类别" prop="time" :rules="[{ required: true, message: '请选择客体类别', trigger: 'change' }]">
-								<el-tree-select
-									class="w100"
-									v-model="state.expandForm.phoneNo"
-									filterable
-									:data="state.orgData"
-									multiple
-									:render-after-expand="false"
-									show-checkbox
-									placeholder="请选择客体类别"
-									node-key="id"
-									:props="{ label: 'orgName' }"
-								/>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item
-								label="投诉问题类别"
-								prop="complainClassifyCode"
-								:rules="[{ required: false, message: '请选择投诉问题类别', trigger: 'blur' }]"
-							>
-								<el-select v-model="state.expandForm.complainClassifyCode" placeholder="请选择投诉问题类别" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="销售方式" prop="salesMode" :rules="[{ required: true, message: '请选择销售方式', trigger: 'blur' }]">
-								<el-select v-model="state.expandForm.salesMode" placeholder="请选择销售方式" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="投诉目标" prop="eCommercePlatformCode" :rules="[{ required: false, message: '请选择投诉目标', trigger: 'blur' }]">
-								<el-select v-model="state.expandForm.eCommercePlatformCode" placeholder="请选择投诉目标" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-                        <!-- 销售方式为“网购”时展示该字段且必填,支持模糊搜索,支持分级模式选择 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="电商平台" prop="eCommercePlatform" :rules="[{ required: true, message: '请选择电商平台', trigger: 'blur' }]">
-								<el-tree-select
-									class="w100"
-									v-model="state.expandForm.eCommercePlatform"
-									filterable
-									:data="state.orgData"
-									multiple
-									:render-after-expand="false"
-									show-checkbox
-									placeholder="请选择电商平台"
-									node-key="id"
-									:props="{ label: 'orgName' }"
-								/>
-							</el-form-item>
-						</el-col>
-                        <!-- 销售方式为“ 网购”时展示该字段且必填,文本框输入 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="订单号" prop="externalOrderNo" :rules="[{ required: true, message: '请填写订单号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.externalOrderNo" placeholder="请填写订单号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 销售方式为“现场”时必填,先选择经营地址所属行政区划,后填写详细地址,行政区划展示本市所有区县名称即可 -->
-						<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
-							<el-form-item label="经营地址" prop="phoneNo" :rules="[{ required: true, message: '请选择经营地址', trigger: 'change' }]">
-								<el-cascader v-model="state.ruleForm.phoneNo" class="w100" :options="state.orgData" placeholder="请选择经营地址" />
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
-							<el-form-item label="经营详细地址" prop="phoneNo" :rules="[{ required: true, message: '请填写经营详细地址', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.phoneNo" placeholder="请填写经营详细地址" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 电视购物:请填写购物的电视频道,电话购物:请填写商品销售者的热线号码,邮购:请填写宣传商品的邮政公司或来件地址 -->
-						<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
-							<el-form-item label="具体渠道" prop="channel" :rules="[{ required: true, message: '请填写经营详细地址', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.channel" placeholder="请填写经营详细地址" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 投诉问题类别”为“专利”时展示该字段 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="专利权人" prop="patentee" :rules="[{ required: false, message: '请填写专利权人', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.patentee" placeholder="请填写专利权人" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 投诉问题类别”为“专利”时展示该字段 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="发明名称" prop="patentName" :rules="[{ required: false, message: '请填写发明名称', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.patentName" placeholder="请填发明名称" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 投诉问题类别”为“专利”时展示该字段 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="专利类型" prop="patentType" :rules="[{ required: false, message: '请选择专利类型', trigger: 'blur' }]">
-								<el-select v-model="state.expandForm.patentType" placeholder="请选择专利类型" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-                        <!-- 投诉问题类别”为“专利”时展示该字段 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="专利号" prop="patentNo" :rules="[{ required: false, message: '请填写专利号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.patentNo" placeholder="请填写专利号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="产品名称" prop="productName" :rules="[{ required: false, message: '请填写产品名称', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.productName" placeholder="请填写产品名称" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="批准文号" prop="phoneNo" :rules="[{ required: false, message: '请填写批准文号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.phoneNo" placeholder="请填写批准文号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="产品批号" prop="approvalNumber" :rules="[{ required: false, message: '请填写产品批号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.approvalNumber" placeholder="请填写产品批号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="产品规格" prop="productStandard" :rules="[{ required: false, message: '请填写产品规格', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.productStandard" placeholder="请填写产品规格" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="产品有效期" prop="productExpriedTime" :rules="[{ required: false, message: '请选择产品有效期', trigger: 'change' }]">
-								<el-date-picker
-									v-model="state.expandForm.productExpriedTime"
-									type="datetime"
-									placeholder="请选择产品有效期"
-									format="YYYY-MM-DD hh:mm:ss"
-									value-format="YYYY-MM-DD h:m:s a"
-									class="w100"
-								/>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="生产厂家" prop="manufacturer" :rules="[{ required: false, message: '请填写生产厂家', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.manufacturer" placeholder="请填写生产厂家" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="销售企业" prop="salesEnterprise" :rules="[{ required: false, message: '请填写销售企业', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.salesEnterprise" placeholder="请填写销售企业" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="消费者地址" prop="consumerAddress" :rules="[{ required: false, message: '请填写消费者地址', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.consumerAddress" placeholder="请填写消费者地址" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-							<el-form-item label="诉求" prop="ComplainType" :rules="[{ required: false, message: '请选择诉求', trigger: 'change' }]">
-								<el-checkbox-group v-model="state.expandForm.ComplainType">
-									<el-checkbox v-for="(item, index) in state.optionsList" :key="index" :label="item.value">{{ item.label }}</el-checkbox>
-								</el-checkbox-group>
-							</el-form-item>
-						</el-col>
-					</template>
-					<!-- 举报 -->
-					<template v-if="state.type === 2">
-						<el-divider content-position="left"><b class="formTitle">举报人信息</b></el-divider>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="证件类型" prop="licenceTypeCode" :rules="[{ required: false, message: '请选择证件类型', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.licenceTypeCode" placeholder="请选择证件类型" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-                        <!-- 选择了证件类型必填 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="证件号码" prop="licenceNo" :rules="[{ required: true, message: '请填写证件号码', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.licenceNo" placeholder="请填写证件号码" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="提供方类型" prop="providerType" :rules="[{ required: false, message: '请选择提供方类型', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.providerType" placeholder="请选择提供方类型" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="提供方身份" prop="providerStatus" :rules="[{ required: false, message: '请选择提供方身份', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.providerStatus" placeholder="请选择提供方身份" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="国籍/地区" prop="nationCode" :rules="[{ required: false, message: '请选择国籍/地区', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.nationCode" placeholder="请选择国籍/地区" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="民族" prop="nation" :rules="[{ required: false, message: '请选择民族', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.nation" placeholder="请选择民族" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="邮政编码" prop="postalCode" :rules="[{ required: false, message: '请填写邮政编码', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.postalCode" placeholder="请填写邮政编码" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="邮箱" prop="email" :rules="[{ required: false, message: '请填写邮箱', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.email" placeholder="请填写邮箱" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="其他联系方式" prop="otherContact" :rules="[{ required: false, message: '请填写其他联系方式', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.otherContact" placeholder="请填写其他联系方式" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-divider content-position="left"><b class="formTitle">举报对象信息</b></el-divider>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="企业名称" prop="phoneNo" :rules="[{ required: true, message: '请填写企业名称', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.phoneNo" placeholder="请填写企业名称" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item
-								label="统一社会信用代码"
-								prop="phoneNo"
-								:rules="[{ required: false, message: '请填写统一社会信用代码', trigger: 'blur' }]"
-							>
-								<el-input v-model="state.expandForm.phoneNo" placeholder="请填写统一社会信用代码" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="注册地址" prop="phoneNo" :rules="[{ required: true, message: '请填写注册地址', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.phoneNo" placeholder="请填写注册地址" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="注册号" prop="phoneNo" :rules="[{ required: false, message: '请填写注册号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.phoneNo" placeholder="请填写注册号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="企业联系人" prop="phoneNo" :rules="[{ required: false, message: '请填写企业联系人', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.phoneNo" placeholder="请填写企业联系人" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="市场主体类型" prop="phoneNo" :rules="[{ required: false, message: '请选择市场主体类型', trigger: 'change' }]">
-								<el-select v-model="state.expandForm.phoneNo" placeholder="请选择市场主体类型" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="行业分类" prop="phoneNo" :rules="[{ required: false, message: '请选择行业分类', trigger: 'blur' }]">
-								<el-select v-model="state.expandForm.phoneNo" placeholder="请选择行业分类" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-divider content-position="left"><b class="formTitle">举报详情</b></el-divider>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="商品分类/品牌" prop="brandCode" :rules="[{ required: true, message: '请选择商品分类/品牌', trigger: 'blur' }]">
-								<el-tree-select
-									class="w100"
-									v-model="state.expandForm.brandCode"
-									filterable
-									:data="state.orgData"
-									multiple
-									:render-after-expand="false"
-									show-checkbox
-									placeholder="请选择商品分类/品牌"
-									node-key="id"
-									:props="{ label: 'orgName' }"
-								/>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item
-								label="争议发生时间"
-								prop="occurrenceTime"
-								:rules="[{ required: true, message: '请选择争议发生时间', trigger: 'change' }]"
-							>
-								<el-date-picker
-									v-model="state.expandForm.occurrenceTime"
-									type="datetime"
-									placeholder="请选择争议发生时间"
-									format="YYYY-MM-DD hh:mm:ss"
-									value-format="YYYY-MM-DD h:m:s a"
-									class="w100"
-								/>
-							</el-form-item>
-						</el-col>
-                        <!-- 只能填写数字,且只能填写非负数 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="消费金额" prop="amount" :rules="[{ required: true, message: '请填写消费金额', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.amount" placeholder="请填写消费金额" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="客体类别" prop="time" :rules="[{ required: true, message: '请选择客体类别', trigger: 'change' }]">
-								<el-tree-select
-									class="w100"
-									v-model="state.expandForm.phoneNo"
-									filterable
-									:data="state.orgData"
-									multiple
-									:render-after-expand="false"
-									show-checkbox
-									placeholder="请选择客体类别"
-									node-key="id"
-									:props="{ label: 'orgName' }"
-								/>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item
-								label="举报问题类别"
-								prop="reportClassifyCode"
-								:rules="[{ required: false, message: '请选择举报问题类别', trigger: 'blur' }]"
-							>
-								<el-select v-model="state.expandForm.reportClassifyCode" placeholder="请选择举报问题类别" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="销售方式" prop="salesMode" :rules="[{ required: true, message: '请选择销售方式', trigger: 'blur' }]">
-								<el-select v-model="state.expandForm.salesMode" placeholder="请选择销售方式" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="举报目标" prop="reportTarget" :rules="[{ required: false, message: '请选择举报目标', trigger: 'blur' }]">
-								<el-select v-model="state.expandForm.reportTarget" placeholder="请选择举报目标" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-                        <!-- 销售方式为“网购”时展示该字段且必填,支持模糊搜索,支持分级模式选择 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="电商平台" prop="eCommercePlatform" :rules="[{ required: true, message: '请选择电商平台', trigger: 'blur' }]">
-								<el-tree-select
-									class="w100"
-									v-model="state.expandForm.eCommercePlatform"
-									filterable
-									:data="state.orgData"
-									multiple
-									:render-after-expand="false"
-									show-checkbox
-									placeholder="请选择电商平台"
-									node-key="id"
-									:props="{ label: 'orgName' }"
-								/>
-							</el-form-item>
-						</el-col>
-                        <!-- 销售方式为“ 网购”时展示该字段且必填,文本框输入 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="订单号" prop="externalOrderNo" :rules="[{ required: true, message: '请填写订单号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.externalOrderNo" placeholder="请填写订单号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 销售方式为“现场”时必填,先选择经营地址所属行政区划,后填写详细地址,行政区划展示本市所有区县名称即可 -->
-						<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
-							<el-form-item label="经营地址" prop="phoneNo" :rules="[{ required: true, message: '请选择经营地址', trigger: 'change' }]">
-								<el-cascader v-model="state.ruleForm.phoneNo" class="w100" :options="state.orgData" placeholder="请选择经营地址" />
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
-							<el-form-item label="经营详细地址" prop="phoneNo" :rules="[{ required: true, message: '请填写经营详细地址', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.phoneNo" placeholder="请填写经营详细地址" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 电视购物:请填写购物的电视频道,电话购物:请填写商品销售者的热线号码,邮购:请填写宣传商品的邮政公司或来件地址 -->
-						<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
-							<el-form-item label="具体渠道" prop="channel" :rules="[{ required: true, message: '请填写经营详细地址', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.channel" placeholder="请填写经营详细地址" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 投诉问题类别”为“专利”时展示该字段 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="专利权人" prop="patentee" :rules="[{ required: false, message: '请填写专利权人', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.patentee" placeholder="请填写专利权人" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 投诉问题类别”为“专利”时展示该字段 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="发明名称" prop="patentName" :rules="[{ required: false, message: '请填写发明名称', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.patentName" placeholder="请填发明名称" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-                        <!-- 投诉问题类别”为“专利”时展示该字段 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="专利类型" prop="patentType" :rules="[{ required: false, message: '请选择专利类型', trigger: 'blur' }]">
-								<el-select v-model="state.expandForm.patentType" placeholder="请选择专利类型" class="w100">
-									<el-option v-for="item in state.levelList" :key="item.key" :label="item.value" :value="item.key" />
-								</el-select>
-							</el-form-item>
-						</el-col>
-                        <!-- 投诉问题类别”为“专利”时展示该字段 -->
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="专利号" prop="patentNo" :rules="[{ required: false, message: '请填写专利号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.patentNo" placeholder="请填写专利号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="产品名称" prop="productName" :rules="[{ required: false, message: '请填写产品名称', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.productName" placeholder="请填写产品名称" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="批准文号" prop="phoneNo" :rules="[{ required: false, message: '请填写批准文号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.phoneNo" placeholder="请填写批准文号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="产品批号" prop="approvalNumber" :rules="[{ required: false, message: '请填写产品批号', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.approvalNumber" placeholder="请填写产品批号" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="产品规格" prop="productStandard" :rules="[{ required: false, message: '请填写产品规格', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.productStandard" placeholder="请填写产品规格" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="产品有效期" prop="productExpriedTime" :rules="[{ required: false, message: '请选择产品有效期', trigger: 'change' }]">
-								<el-date-picker
-									v-model="state.expandForm.productExpriedTime"
-									type="datetime"
-									placeholder="请选择产品有效期"
-									format="YYYY-MM-DD hh:mm:ss"
-									value-format="YYYY-MM-DD h:m:s a"
-									class="w100"
-								/>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="生产厂家" prop="manufacturer" :rules="[{ required: false, message: '请填写生产厂家', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.manufacturer" placeholder="请填写生产厂家" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="销售企业" prop="salesEnterprise" :rules="[{ required: false, message: '请填写销售企业', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.salesEnterprise" placeholder="请填写销售企业" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-						<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6">
-							<el-form-item label="消费者地址" prop="consumerAddress" :rules="[{ required: false, message: '请填写消费者地址', trigger: 'blur' }]">
-								<el-input v-model="state.expandForm.consumerAddress" placeholder="请填写消费者地址" clearable> </el-input>
-							</el-form-item>
-						</el-col>
-					</template>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<span class="dialog-footer">
-					<el-button @click="state.isShowDialog = false" class="default-button">取 消</el-button>
-					<el-button type="primary" @click="saveExpandForm">保 存</el-button>
-				</span>
-			</template>
-		</el-dialog>
-	</div>
-</template>
-
-<script setup lang="ts" name="workOrderExpandForm">
-import { reactive, ref } from 'vue';
-import { orderBaseExt } from '/@/api/businessManage/workOrderManage';
-// import { ElMessage } from 'element-plus';
-// 定义变量内容
-const state = reactive<any>({
-	isShowDialog: false,
-	type: 1,
-	expandForm: {
-		phoneNo: '',
-	},
-	levelList: [
-		{
-			value: '呼入限制',
-			key: 0,
-		},
-		{
-			value: '坐席限制',
-			key: 1,
-		},
-		{
-			value: '友情提示',
-			key: 2,
-		},
-	],
-	optionsList: [
-		{
-			label: '修理',
-			value: 1,
-		},
-		{
-			label: '重做',
-			value: 2,
-		},
-		{
-			label: '退货',
-			value: 3,
-		},
-		{
-			label: '补足商品数量',
-			value: 4,
-		},
-		{
-			label: '退赔费用',
-			value: 5,
-		},
-		{
-			label: '赔偿损失',
-			value: 6,
-		},
-		{
-			label: '停止侵权',
-			value: 7,
-		},
-		{
-			label: '核定侵权责任',
-			value: 8,
-		},
-	],
-});
-const expandFormRef = ref();
-// 打开弹窗
-const openDialog =  async(id: any) => {
-    const res: any = await orderBaseExt(); //基础数据
-	state.isShowDialog = true;
-};
-// 保存拓展表单
-const saveExpandForm = () => {
-	expandFormRef.value.validate((valid: boolean) => {
-		if (valid) {
-			console.log(expandFormRef.value);
-		} else {
-			return false;
-		}
-	});
-};
-// 关闭弹窗
-const closeDialog = () => {
-	state.isShowDialog = false;
-};
-// 暴露变量
-defineExpose({
-	openDialog,
-	closeDialog,
-});
-</script>
-<style lang="scss" scoped>
-
-</style>

+ 3 - 3
src/views/deviceManagement/iverConfig/index.vue → src/views/device/iverConfig/index.vue

@@ -236,9 +236,9 @@ import { useThemeConfig } from '/@/stores/themeConfig';
 import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
 
 // 引入api
-import { getIvrTree, baseInfo, getIvrById, voicequerylist , addEditIvr,delIvrTree,replaceRootApi} from "/@/api/deviceManagement/ivr"
-import { getTelsGroupList } from '/@/api/deviceManagement/telsGroup';
-import { getTelsList } from '/@/api/deviceManagement/tels';
+import { getIvrTree, baseInfo, getIvrById, voicequerylist , addEditIvr,delIvrTree,replaceRootApi} from "/@/api/device/ivr"
+import { getTelsGroupList } from '/@/api/device/telsGroup';
+import { getTelsList } from '/@/api/device/tels';
 
 // 定义变量内容
 let cloneNodeDrag = ref(false);

+ 2 - 2
src/views/deviceManagement/ivrCategroy/component/addCategroy.vue → src/views/device/ivrCategroy/component/addCategroy.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="deviceManagement-add-categroy-container">
+    <div class="device-add-categroy-container">
         <el-dialog v-model="isShowDialog" width="600px" draggable title="新增ivr分类">
             <el-form :model="ruleForm" label-width="100px" ref="ruleFormRef">
                 <el-row :gutter="35">
@@ -30,7 +30,7 @@
 <script lang="ts" setup>
 import { reactive, ref, toRefs } from "vue";
 import { ElMessage } from 'element-plus'
-import { addIvrCategroies } from "/@/api/deviceManagement/ivr";
+import { addIvrCategroies } from "/@/api/device/ivr";
 
 // 定义接口来定义对象的类型
 interface StateIvrCategroy {

+ 2 - 2
src/views/deviceManagement/ivrCategroy/component/editCatehroy.vue → src/views/device/ivrCategroy/component/editCatehroy.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="deviceManagement-edit-categroy-container">
+    <div class="device-edit-categroy-container">
         <el-dialog v-model="isShowDialog" width="600px" draggable title="编辑ivr分类">
             <el-form :model="ruleForm" label-width="100px" ref="ruleFormRef">
                 <el-row :gutter="35">
@@ -30,7 +30,7 @@
 <script lang="ts" setup>
 import { ref, reactive, toRefs  } from 'vue';
 import {  ElMessage } from 'element-plus';
-import { updateIvrCategroies} from "/@/api/deviceManagement/ivr";
+import { updateIvrCategroies} from "/@/api/device/ivr";
 
 // 定义接口来定义对象的类型
 interface StateIvrCategroy {

+ 141 - 0
src/views/device/ivrCategroy/index.vue

@@ -0,0 +1,141 @@
+<template>
+	<div class="device-ivrCategroy-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<div class="flex-center-between mb20">
+				<p class="table-title">信息列表</p>
+				<div>
+					<el-button type="primary" @click="onAddCategory" v-waves v-auth="'300302'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
+					<el-button type="primary" v-waves @click="onImportTable" :disabled="!state.multipleSelection.length">
+						<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+					</el-button>
+				</div>
+			</div>
+			<!-- 表格 -->
+			<el-table :data="tableData" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
+				<el-table-column type="selection" width="55" :reserve-selection="true" />
+				<el-table-column prop="name" label="分类名称" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="remark" label="备注" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="creationTime" label="创建时间" show-overflow-tooltip width="170">
+					<template #default="scope">
+						<span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column label="操作" width="100" fixed="right" align="center">
+					<template #default="scope">
+						<el-button text type="primary" @click="onEditCategroy(scope.row)" v-auth="'300303'" title="修改">
+							<SvgIcon name="ele-EditPen" size="var(--hotline-table-icon-font-size)" />
+						</el-button>
+						<el-button text type="danger" @click="onDelCategroy(scope.row)" v-auth="'300304'" title="删除">
+							<SvgIcon name="ele-Delete" size="var(--hotline-table-icon-font-size)" />
+						</el-button>
+						<!-- <el-button text type="success" @click="configIvr(scope.row)">配置ivr</el-button> -->
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+		</div>
+
+		<AddCategroy ref="addCategroyRef" @updateList="handleQuery" />
+		<EditCategroy ref="editCategroyRef" @updateList="handleQuery" />
+	</div>
+</template>
+<script lang="ts" setup name="ivrCategroy">
+import { defineAsyncComponent, onMounted, ref, reactive, toRefs } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { getIvrCategories, deleteIvrCategroies } from '/@/api/device/ivr';
+import { formatDate } from '/@/utils/formatTime';
+import table2excel from 'js-table2excel';
+
+// 定义接口来定义对象的类型
+interface IvrCategroyState {
+	loading: boolean;
+	tableData: Array<any>; //列表数据
+	multipleSelection: Array<any>; //多选列表
+}
+
+// 引入组件
+const AddCategroy = defineAsyncComponent(() => import('/@/views/device/ivrCategroy/component/addCategroy.vue'));
+const EditCategroy = defineAsyncComponent(() => import('/@/views/device/ivrCategroy/component/editCatehroy.vue'));
+
+// 定义变量内容
+// import { useRouter } from "vue-router";
+const state = reactive<IvrCategroyState>({
+	loading: false,
+	tableData: [],
+	multipleSelection: [],
+});
+const { loading, tableData } = toRefs(state);
+
+const addCategroyRef = ref();
+const editCategroyRef = ref();
+
+// 新增分类
+const onAddCategory = () => {
+	addCategroyRef.value.openDialog();
+};
+// 编辑分类
+const onEditCategroy = (row: any) => {
+	editCategroyRef.value.openDialog(row);
+};
+//删除分类
+const onDelCategroy = (row: any) => {
+	ElMessageBox.confirm(`此操作将永久删除分类:【${row.name}】,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			deleteIvrCategroies(row.id).then(() => {
+				ElMessage.success('删除成功');
+				handleQuery();
+			});
+		})
+		.catch(() => {});
+};
+//查询列表
+const handleQuery = () => {
+	state.loading = true;
+	getIvrCategories().then((res: any) => {
+		state.tableData = res?.result ?? [];
+		state.loading = false;
+	});
+};
+// 配置ivr
+// const configIvr = (row:any)=>{
+//     router.push({
+//         // path:"/ivrConfig/details",
+//         name:"ivrConfigDetails",
+//         params:{
+//             tagsViewName:row.name+'ivr配置',
+//             id: row.id,
+//         }
+//     })
+// }
+// 表格多选
+const handleSelectionChange = (val: any) => {
+	state.multipleSelection = val;
+};
+// 导出表格
+const onImportTable = () => {
+	const tabeHeader = [
+		{ key: 'name', colWidth: '', title: '分类名称', type: 'text', isCheck: true },
+		{ key: 'remark', colWidth: '', title: '备注', type: 'text', isCheck: true },
+		{ key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
+	];
+	table2excel(tabeHeader, state.multipleSelection, `ivr分类管理 ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
+};
+onMounted(() => {
+	handleQuery();
+});
+</script>
+<style scoped lang="scss">
+.device-ivrCategroy-container {
+	.el-table {
+		flex: 1;
+	}
+}
+</style>

+ 5 - 9
src/views/deviceManagement/ivrList/index.vue → src/views/device/ivrList/index.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="deviceManagement-ivrlist-container layout-padding">
+    <div class="device-ivrlist-container layout-padding">
         <div class="layout-padding-auto layout-padding-view pd20">
             <div class="flex-center-between mb20">
                 <p class="table-title">信息列表</p>
@@ -492,9 +492,9 @@ import { useUserInfo } from '/@/stores/userInfo';
 import table2excel from 'js-table2excel';
 import { formatDate } from '/@/utils/formatTime';
 // 引入api
-import { getIvrCategories, baseInfo, addIvr, updateIvr, getIvrById, addEditIvr, getIvrList, voicequerylist, resetConfig } from "/@/api/deviceManagement/ivr";
-import { getTelsGroupList } from '/@/api/deviceManagement/telsGroup';
-import { getTelsList } from '/@/api/deviceManagement/tels';
+import { getIvrCategories, baseInfo, addIvr, updateIvr, getIvrById, addEditIvr, getIvrList, voicequerylist, resetConfig } from "/@/api/device/ivr";
+import { getTelsGroupList } from '/@/api/device/telsGroup';
+import { getTelsList } from '/@/api/device/tels';
 
 // 定义接口来定义对象的类型
 interface IvrListState {
@@ -632,9 +632,7 @@ const getList = () => {
     state.loading = true;
     getIvrList().then((response: any) => {
         state.tableData = response?.result ?? [];
-        setTimeout(() => {
             state.loading = false;
-        }, 300);
     }).catch(() => {
         state.loading = false;
     });
@@ -648,9 +646,7 @@ const getAudioList = () => {
                 label: item
             }
         })
-        setTimeout(() => {
             state.loading = false;
-        }, 300);
     }).catch(() => {
         state.loading = false;
     });
@@ -1015,7 +1011,7 @@ onMounted(() => {
 </script>
 
 <style lang="scss" scoped>
-.deviceManagement-ivrlist-container {
+.device-ivrlist-container {
     .el-table {
         flex: 1;
     }

+ 114 - 0
src/views/device/tels/index.vue

@@ -0,0 +1,114 @@
+<template>
+	<div class="device-tels-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<div class="flex-center-between mb20">
+				<p class="table-title">信息列表</p>
+				<div>
+					<el-button type="primary" @click="asyncDevice" v-waves v-auth="'300101'"> <SvgIcon name="ele-Refresh" class="mr5" />同步 </el-button>
+					<el-button type="primary" v-waves @click="onImportTable" :disabled="!state.multipleSelection.length">
+						<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+					</el-button>
+				</div>
+			</div>
+			<!-- 表格 -->
+			<el-table :data="tableData" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
+				<el-table-column type="selection" width="55" :reserve-selection="true" />
+				<el-table-column prop="no" label="分机编号" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="groupNames" label="所属分机组" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="registerIP" label="注册IP" show-overflow-tooltip></el-table-column>
+				<el-table-column label="分机状态" show-overflow-tooltip prop="telStatusText"></el-table-column>
+				<el-table-column label="创建时间" show-overflow-tooltip width="170">
+					<template #default="scope">
+						<span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+		</div>
+	</div>
+</template>
+
+<script lang="ts" name="tels" setup>
+import { onMounted, reactive, toRefs } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { formatDate } from '/@/utils/formatTime';
+import table2excel from 'js-table2excel';
+// 引入api
+import { getTelsList, syncTel } from '/@/api/device/tels';
+
+// 定义接口来定义对象的类型
+interface TelsState {
+	loading: boolean;
+	tableData: Array<any>;
+	multipleSelection: Array<any>;
+}
+
+// 定义变量内容
+const state = reactive<TelsState>({
+	loading: false,
+	tableData: [],
+	multipleSelection: [],
+});
+const { loading, tableData } = toRefs(state);
+/** 获取分机列表 */
+const getList = () => {
+	state.loading = true;
+	getTelsList()
+		.then((response: any) => {
+			state.tableData = response.result ?? [];
+			state.loading = false;
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
+// 同步
+const asyncDevice = () => {
+	ElMessageBox.confirm(`确定要将设备信息同步到数据库,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			syncTel()
+				.then(() => {
+					getList();
+					ElMessage.success('同步成功');
+				})
+				.catch((err: any) => {
+					console.log(err, '同步失败');
+				});
+		})
+		.catch(() => {});
+};
+// 表格多选
+const handleSelectionChange = (val: any) => {
+	state.multipleSelection = val;
+};
+// 导出表格
+const onImportTable = () => {
+	const tabeHeader = [
+		{ key: 'no', colWidth: '', title: '分机编号', type: 'text', isCheck: true },
+		{ key: 'groupNames', colWidth: '', title: '所属分机组', type: 'text', isCheck: true },
+		{ key: 'registerIP', colWidth: '', title: '注册IP', type: 'text', isCheck: true },
+		{ key: '分机状态', colWidth: '', title: '分机状态', type: 'text', isCheck: true },
+		{ key: '创建时间', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
+	];
+	table2excel(tabeHeader, state.multipleSelection, `话机管理 ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
+};
+onMounted(() => {
+	getList();
+});
+</script>
+
+<style lang="scss" scoped>
+.device-tels-container {
+	.el-table {
+		flex: 1;
+	}
+}
+</style>

+ 330 - 0
src/views/device/telsGroup/index.vue

@@ -0,0 +1,330 @@
+<template>
+	<div class="device-telsGroup-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<div class="flex-center-between mb20">
+				<p class="table-title">信息列表</p>
+				<div>
+					<el-button type="primary" @click="onAddTelsGroup" v-waves v-auth="'300202'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
+					<el-button type="primary" v-waves @click="onImportTable" :disabled="!state.multipleSelection.length">
+						<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+					</el-button>
+				</div>
+			</div>
+			<el-table :data="tableData" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
+				<el-table-column type="selection" width="55" :reserve-selection="true" />
+				<el-table-column prop="no" label="编号" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="name" label="分机组名称" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="distributionText" label="呼叫分配方式" show-overflow-tooltip></el-table-column>
+				<el-table-column label="是否默认分组" show-overflow-tooltip>
+					<template #default="scope">
+						{{ scope.row.isDefault ? '是' : '否' }}
+					</template>
+				</el-table-column>
+				<el-table-column prop="remark" label="备注" show-overflow-tooltip></el-table-column>
+				<el-table-column prop="creationTime" label="创建时间" show-overflow-tooltip width="170">
+					<template #default="scope">
+						<span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column label="操作" width="100" fixed="right" align="center">
+					<template #default="scope">
+						<el-button text type="primary" @click="configure(scope.row)" v-auth="'300203'" title="配置分机组">
+							<SvgIcon name="ele-EditPen" size="var(--hotline-table-icon-font-size)" />
+						</el-button>
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+		</div>
+		<!-- 配置分机组 -->
+		<el-dialog v-model="isShowDialog" draggable :title="dialogTitle">
+			<el-form :model="ruleForm" label-width="110px" ref="ruleFormRef">
+				<el-row :gutter="35">
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="分机编号" prop="no">
+							<el-input v-model="ruleForm.no" disabled></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="分机组名称" prop="name" :rules="[{ required: true, message: '请输入分机组名称', trigger: 'blur' }]">
+							<el-input v-model="ruleForm.name" placeholder="请输入分机组名称" clearable></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="呼叫分配方式" prop="distribution" :rules="[{ required: true, message: '请选择ivr类型', trigger: 'change' }]">
+							<el-select v-model="ruleForm.distribution" placeholder="请选择呼叫分配方式" class="w100">
+								<el-option v-for="item in distributions" :key="item.key" :label="item.value" :value="item.key" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="默认分组" prop="isDefault" :rules="[{ required: false, message: '请选择ivr类型', trigger: 'change' }]">
+							<el-switch v-model="ruleForm.isDefault" />
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+						<el-form-item label="选择分机" prop="telNos" :rules="[{ required: true, message: '请选择分机', trigger: 'change' }]">
+							<el-transfer v-model="ruleForm.telNos" :titles="['所有分机', '已选分机']" :props="{ key: 'no' }" :data="telsList" :filterable="true">
+								<template #default="{ option }">
+									<span>分机 - {{ option.no }}</span>
+								</template>
+							</el-transfer>
+						</el-form-item>
+					</el-col>
+					<!-- 语音文件 -->
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+						<el-form-item label="语音文件" prop="voiceList" :rules="[{ required: false, message: '选择语音文件', trigger: 'change' }]">
+							<el-transfer
+								v-model="ruleForm.voiceList"
+								:titles="['选择语音文件', '按照选择顺序播放']"
+								target-order="push"
+								:data="voiceData"
+								:filterable="true"
+							>
+								<template #default="{ option }">
+									<span>{{ option.label }}</span>
+								</template>
+							</el-transfer>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+						<el-form-item label="备注" prop="remark">
+							<el-input
+								v-model="ruleForm.remark"
+								type="textarea"
+								:autosize="{ minRows: 4, maxRows: 6 }"
+								placeholder="请输入备注"
+								clearable
+							></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="isShowDialog = false" class="default-button">取 消</el-button>
+					<el-button type="primary" @click="save" :loading="loading">保 存</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts" name="tels" setup>
+import { ref, reactive, toRefs, onMounted } from 'vue';
+import { ElMessage } from 'element-plus';
+import { storeToRefs } from 'pinia';
+import { formatDate } from '/@/utils/formatTime';
+import { useUserInfo } from '/@/stores/userInfo';
+import table2excel from 'js-table2excel';
+// 引入需要的api
+import { getTelsGroupList, addTelsGroup, updateTelsGroup, baseInfoTelsGroup } from '/@/api/device/telsGroup';
+import { getTelsList } from '/@/api/device/tels';
+import { voicequerylist } from '/@/api/device/ivr';
+
+// 定义接口来定义对象的类型
+interface TelsGroupState {
+	ruleForm: {
+		no: string; // 分机组编号
+		name: string; // 分机组名称
+		remark: string; // 分机组备注
+		telNos: Array<any>; //选择的分机
+		voiceList: Array<any>; //语音列表
+		voice: string; //格式化之后的语音列表
+		distribution: object; //呼叫分配方式
+		isDefault: boolean; //是否默认分组
+	};
+	distributions: Array<any>; //呼叫分配方式列表
+	loading: boolean;
+	tableData: Array<any>; //列表数据
+	voiceData: Array<any>; //音频文件
+	isShowDialog: boolean;
+	telsList: Array<any>; //分机列表
+	multipleSelection: Array<any>; //多选列表
+}
+
+// 定义变量内容
+const dialogTitle = ref('配置分机组');
+const ruleFormRef = ref();
+const state = reactive<TelsGroupState>({
+	ruleForm: {
+		no: '', // 分机组编号
+		name: '', // 分机组名称
+		remark: '', // 分机组备注
+		telNos: [],
+		voiceList: [],
+		voice: '',
+		distribution: {},
+		isDefault: false,
+	},
+	distributions: [],
+	loading: false,
+	tableData: [],
+	voiceData: [],
+	isShowDialog: false,
+	telsList: [],
+	multipleSelection: [],
+});
+const storesUserInfo = useUserInfo();
+const { userInfos } = storeToRefs(storesUserInfo);
+const { ruleForm, distributions, loading, tableData, voiceData, isShowDialog, telsList } = toRefs(state);
+/** 获取所有语音文件列表 */
+const getAudioList = () => {
+	if (userInfos.value.authBtnList.includes('300201')) {
+		// 校验是否有权限 页面基础信息
+		voicequerylist()
+			.then((response: any) => {
+				state.voiceData = response.result.map((item: any) => {
+					return {
+						key: item,
+						label: item,
+					};
+				});
+				state.loading = false;
+			})
+			.catch(() => {
+				state.loading = false;
+			});
+		baseInfoTelsGroup().then((res: any) => {
+			// 获取页面基础信息
+			state.distributions = res?.result.distributions ?? [];
+		});
+	} else {
+		ElMessage.warning('您没有权限查看页面基础信息');
+	}
+};
+/** 获取分机列表 */
+const getList = () => {
+	state.loading = true;
+	getTelsGroupList()
+		.then((response: any) => {
+			state.tableData = response?.result ?? [];
+			for (let i of state.tableData) {
+				i.voiceList = i.voice ? i.voice.split('+') : [];
+				i.telNos = i.tels;
+			}
+			state.loading = false;
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
+const configure = (row: any) => {
+	//配置分机
+	state.ruleForm = JSON.parse(JSON.stringify(row));
+	dialogTitle.value = '配置分机组';
+	if (row.telNos) {
+		//处理成穿梭框需要的数据格式
+		let arr: string[] = [];
+		for (let i of row.telNos) {
+			arr.push(i.no);
+		}
+		state.ruleForm.telNos = arr;
+	} else {
+		state.ruleForm.telNos = <any>[];
+	}
+	state.isShowDialog = true;
+};
+//新增分机组
+const onAddTelsGroup = () => {
+	dialogTitle.value = '新增分机组';
+	ruleFormRef.value?.resetFields();
+	ruleFormRef.value?.resetFields();
+	if (state.tableData.length) {
+		state.ruleForm = {
+			no: String(Number(state.tableData.length + 1)), // ivr编号
+			name: '',
+			remark: '',
+			telNos: [],
+			voiceList: [],
+			voice: '',
+			distribution: {},
+			isDefault: false,
+		};
+	} else {
+		state.ruleForm.no = '1';
+	}
+	state.isShowDialog = true;
+};
+/** 获取分机列表 */
+const getTelList = () => {
+	getTelsList()
+		.then((response: any) => {
+			state.telsList = response?.result ?? [];
+		})
+		.catch(() => {});
+};
+// 保存分机组配置
+const save = () => {
+	ruleFormRef.value.validate((valid: boolean) => {
+		if (valid) {
+			if (state.ruleForm.voiceList.length) {
+				state.ruleForm.voice = state.ruleForm.voiceList.join('+');
+			}
+			state.loading = true;
+			if (dialogTitle.value == '新增分机组') {
+				addTelsGroup(state.ruleForm)
+					.then(() => {
+						ElMessage.success('操作成功');
+						setTimeout(() => {
+							getList();
+						}, 1000);
+						state.isShowDialog = false;
+						state.loading = false;
+					})
+					.catch(() => {
+						state.loading = false;
+					});
+			} else if (dialogTitle.value == '配置分机组') {
+				updateTelsGroup(state.ruleForm)
+					.then(() => {
+						ElMessage.success('操作成功');
+						setTimeout(() => {
+							getList();
+						}, 1000);
+						state.isShowDialog = false;
+						state.loading = false;
+					})
+					.catch(() => {
+						state.loading = false;
+					});
+			}
+		} else {
+			return false;
+		}
+	});
+};
+// 表格多选
+const handleSelectionChange = (val: any) => {
+	state.multipleSelection = val;
+};
+// 导出表格
+const onImportTable = () => {
+	const tabeHeader = [
+		{ key: 'no', colWidth: '', title: '编号', type: 'text', isCheck: true },
+		{ key: 'name', colWidth: '', title: '分机组名称', type: 'text', isCheck: true },
+		{ key: 'distributionText', colWidth: '', title: '呼叫分配方式', type: 'text', isCheck: true },
+		{ key: 'isDefault', colWidth: '', title: '是否默认分组', type: 'text', isCheck: true },
+		{ key: 'remark', colWidth: '', title: '备注', type: 'text', isCheck: true },
+		{ key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
+	];
+	table2excel(tabeHeader, state.multipleSelection, `分机组管理 ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
+};
+// 页面加载时
+onMounted(() => {
+	getTelList(); //获取分机列表
+	getList();
+	getAudioList();
+});
+</script>
+
+<style lang="scss" scoped>
+.device-telsGroup-container {
+	.el-table {
+		flex: 1;
+	}
+}
+</style>

+ 1 - 1
src/views/deviceManagement/trunks/component/add.vue → src/views/device/trunks/component/add.vue

@@ -110,7 +110,7 @@
 <script setup lang="ts" name="trunksAdd">
 import { reactive, ref } from 'vue';
 import { ElMessage, FormInstance } from 'element-plus';
-import { addtrunk, baseInfo } from '/@/api/deviceManagement/trunks';
+import { addtrunk, baseInfo } from '/@/api/device/trunks';
 
 // 定义接口来定义对象的类型
 interface OrgFormState {

+ 1 - 1
src/views/deviceManagement/trunks/component/edit.vue → src/views/device/trunks/component/edit.vue

@@ -102,7 +102,7 @@ import { reactive, ref } from 'vue';
 import { ElMessage, FormInstance } from 'element-plus';
 import { storeToRefs } from 'pinia';
 import { useUserInfo } from '/@/stores/userInfo';
-import { updatetrunk, getTrunkDetail, baseInfo } from '/@/api/deviceManagement/trunks';
+import { updatetrunk, getTrunkDetail, baseInfo } from '/@/api/device/trunks';
 
 // 定义接口来定义对象的类型
 interface OrgFormState {

+ 174 - 0
src/views/device/trunks/index.vue

@@ -0,0 +1,174 @@
+<template>
+	<div class="device-tels-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<div class="flex-center-between mb20">
+				<p class="table-title">信息列表</p>
+				<div>
+					<el-button type="primary" @click="addTrunks" v-waves v-auth="'300502'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
+					<el-button type="primary" v-waves @click="onImportTable" :disabled="!state.multipleSelection.length">
+						<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+					</el-button>
+				</div>
+			</div>
+			<!-- 表格 -->
+			<el-table :data="tableData" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
+				<el-table-column type="selection" width="55" :reserve-selection="true" />
+				<el-table-column prop="trunkId" label="线路号" show-overflow-tooltip width="100"></el-table-column>
+				<el-table-column prop="morningBegin" label="早上开始时间" show-overflow-tooltip width="130"></el-table-column>
+				<el-table-column prop="morningEnd" label="早上结束时间" show-overflow-tooltip width="130"></el-table-column>
+				<el-table-column prop="afterBegin" label="下午开始时间" show-overflow-tooltip width="130"></el-table-column>
+				<el-table-column prop="afterEnd" label="下午结束时间" show-overflow-tooltip width="130"></el-table-column>
+				<el-table-column prop="afterBegin" label="工作日" show-overflow-tooltip width="150">
+					<template #default="scope">
+						<span v-for="(item, index) in scope.row.workDay" :key="index"> <span v-show="index">,</span>{{ item.weekName }} </span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="workCategoryModel" label="工作时间IVR" show-overflow-tooltip width="150">
+					<template #default="scope">
+						<span>{{ scope.row.workCategoryModel.name }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column prop="restCategoryModel" label="休息时间IVR" show-overflow-tooltip width="150">
+					<template #default="scope">
+						{{ scope.row.restCategoryModel.name }}
+					</template>
+				</el-table-column>
+				<el-table-column prop="workToGroupModel" label="工作时间直转分机组" show-overflow-tooltip width="160">
+					<template #default="scope">
+						{{ scope.row.workToGroupModel.name }}
+					</template>
+				</el-table-column>
+				<el-table-column prop="restToGroupModel" label="休息时间直转分机组" show-overflow-tooltip width="160">
+					<template #default="scope">
+						{{ scope.row.restToGroupModel.name }}
+					</template>
+				</el-table-column>
+				<el-table-column label="是否启用" show-overflow-tooltip prop="isEnable">
+					<template #default="scope">
+						<el-tag type="success" v-if="scope.row.isEnable">启用</el-tag>
+						<el-tag type="info" v-else>禁用</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column label="创建时间" show-overflow-tooltip width="170">
+					<template #default="scope">
+						<span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column label="操作" show-overflow-tooltip width="100" fixed="right" align="center">
+					<template #default="scope">
+						<el-button text type="primary" @click="updateTrunks(scope.row)" v-auth="'300503'" title="修改线路">
+							<SvgIcon name="ele-EditPen" size="var(--hotline-table-icon-font-size)" />
+						</el-button>
+						<el-button text type="success" @click="ivrConfigure(scope.row)" v-auth="'300504'" title="删除线路">
+							<SvgIcon name="ele-Delete" size="var(--hotline-table-icon-font-size)" />
+						</el-button>
+					</template>
+				</el-table-column>
+				<template #empty>
+					<Empty />
+				</template>
+			</el-table>
+		</div>
+		<AddTrunks ref="addTrunksRef" @updateList="getListFn" />
+		<EditTrunks ref="EditTrunksRef" @updateList="getListFn" />
+	</div>
+</template>
+<script lang="ts" name="trunks" setup>
+import { onMounted, reactive, toRefs, defineAsyncComponent, ref } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { formatDate } from '/@/utils/formatTime';
+import table2excel from 'js-table2excel';
+// 引入api
+import { getList, removetrunk } from '/@/api/device/trunks';
+
+// 引入组件
+const AddTrunks = defineAsyncComponent(() => import('/@/views/device/trunks/component/add.vue'));
+const EditTrunks = defineAsyncComponent(() => import('/@/views/device/trunks/component/edit.vue'));
+
+// 定义接口来定义对象的类型
+interface TelsState {
+	loading: boolean;
+	tableData: Array<any>;
+	multipleSelection: Array<any>;
+}
+
+// 定义变量内容
+const state = reactive<TelsState>({
+	loading: false,
+	tableData: [],
+	multipleSelection: [],
+});
+const { loading, tableData } = toRefs(state);
+const addTrunksRef = ref();
+const EditTrunksRef = ref();
+/** 获取线路列表 */
+const getListFn = () => {
+	state.loading = true;
+	getList()
+		.then((response: any) => {
+			state.tableData = response.result ?? [];
+			state.loading = false;
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
+// 新增线路
+const addTrunks = () => {
+	addTrunksRef.value?.openDialog();
+};
+// 修改路线
+const updateTrunks = (row: any) => {
+	EditTrunksRef.value?.openDialog(row);
+};
+// 删除路线
+const ivrConfigure = (row: any) => {
+	ElMessageBox.confirm(`此操作将永久删除线路:【${row.trunkId}】, 是否继续?`, '提示', {
+		confirmButtonText: '删除',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			removetrunk(row.id).then(() => {
+				ElMessage.success('删除成功');
+				getListFn();
+			});
+		})
+		.catch(() => {});
+};
+// 表格多选
+const handleSelectionChange = (val: any) => {
+	state.multipleSelection = val;
+};
+// 导出表格
+const onImportTable = () => {
+	const tabeHeader = [
+		{ key: 'trunkId', colWidth: '', title: '线路号', type: 'text', isCheck: true },
+		{ key: 'morningBegin', colWidth: '', title: '早上开始时间', type: 'text', isCheck: true },
+		{ key: 'morningEnd', colWidth: '', title: '早上结束时间', type: 'text', isCheck: true },
+		{ key: 'afterBegin', colWidth: '', title: '下午开始时间', type: 'text', isCheck: true },
+		{ key: 'afterEnd', colWidth: '', title: '下午结束时间', type: 'text', isCheck: true },
+		{ key: 'telStatusText', colWidth: '', title: '工作日', type: 'text', isCheck: true },
+		{ key: 'afterBegin', colWidth: '', title: '工作时间IVR', type: 'text', isCheck: true },
+		{ key: 'afterBegin', colWidth: '', title: '休息时间IVR', type: 'text', isCheck: true },
+		{ key: 'afterBegin', colWidth: '', title: '工作时间直转分机组', type: 'text', isCheck: true },
+		{ key: 'afterBegin', colWidth: '', title: '休息时间直转分机组', type: 'text', isCheck: true },
+		{ key: 'afterBegin', colWidth: '', title: '是否启用', type: 'text', isCheck: true },
+		{ key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
+	];
+	table2excel(tabeHeader, state.multipleSelection, `线路管理 ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
+};
+onMounted(() => {
+	getListFn();
+});
+</script>
+
+<style lang="scss" scoped>
+.device-tels-container {
+	.el-table {
+		flex: 1;
+	}
+}
+</style>

+ 0 - 144
src/views/deviceManagement/ivrCategroy/index.vue

@@ -1,144 +0,0 @@
-<template>
-    <div class="deviceManagement-ivrCategroy-container layout-padding">
-        <div class="layout-padding-auto layout-padding-view pd20">
-            <div class="flex-center-between mb20">
-                <p class="table-title">信息列表</p>
-                <div>
-                    <el-button type="primary" @click="onAddCategory" v-waves v-auth="'300302'">
-                        <SvgIcon name="ele-Plus" class="mr5" />新增
-                    </el-button>
-                    <el-button type="primary" v-waves @click="onImportTable" :disabled="!state.multipleSelection.length">
-                        <SvgIcon name="iconfont icon-daochu" class="mr5"/>导出
-                    </el-button>
-                </div>
-            </div>
-            <!-- 表格 -->
-            <el-table :data="tableData" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
-                <el-table-column type="selection" width="55" :reserve-selection="true"/>
-                <el-table-column prop="name" label="分类名称" show-overflow-tooltip></el-table-column>
-                <el-table-column prop="remark" label="备注" show-overflow-tooltip></el-table-column>
-                <el-table-column prop="creationTime" label="创建时间" show-overflow-tooltip width="170">
-                    <template #default="scope">
-                        <span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
-                    </template>
-                </el-table-column>
-                <el-table-column label="操作" width="100" fixed="right" align="center">
-                    <template #default="scope">
-                        <el-button text type="primary" @click="onEditCategroy(scope.row)" v-auth="'300303'" title="修改">
-                            <SvgIcon name="ele-EditPen" size="var(--hotline-table-icon-font-size)" />
-                        </el-button>
-                        <el-button text type="danger" @click="onDelCategroy(scope.row)" v-auth="'300304'" title="删除">
-                            <SvgIcon name="ele-Delete" size="var(--hotline-table-icon-font-size)" />
-                        </el-button>
-                        <!-- <el-button text type="success" @click="configIvr(scope.row)">配置ivr</el-button> -->
-                    </template>
-                </el-table-column>
-                <template #empty>
-                    <Empty />
-                </template>
-            </el-table>
-        </div>
-
-        <AddCategroy ref="addCategroyRef" @updateList="handleQuery" />
-        <EditCategroy ref="editCategroyRef" @updateList="handleQuery" />
-    </div>
-</template>
-<script lang="ts" setup name="ivrCategroy">
-import { defineAsyncComponent, onMounted, ref,reactive, toRefs } from "vue";
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { getIvrCategories, deleteIvrCategroies } from "/@/api/deviceManagement/ivr";
-import { formatDate } from '/@/utils/formatTime';
-import table2excel from 'js-table2excel';
-
-// 定义接口来定义对象的类型
-interface IvrCategroyState{
-    loading:boolean;
-    tableData:Array<any>; //列表数据
-    multipleSelection:Array<any>; //多选列表
-}
-
-// 引入组件
-const AddCategroy = defineAsyncComponent(() => import('/@/views/deviceManagement/ivrCategroy/component/addCategroy.vue'))
-const EditCategroy = defineAsyncComponent(() => import('/@/views/deviceManagement/ivrCategroy/component/editCatehroy.vue'))
-
-// 定义变量内容
-// import { useRouter } from "vue-router";
-const state = reactive<IvrCategroyState>({
-    loading:false,
-    tableData:[],
-    multipleSelection:[]
-})
-const {loading,tableData} = toRefs(state)
-
-const addCategroyRef = ref();
-const editCategroyRef = ref();
-
-// 新增分类
-const onAddCategory = () => {
-    addCategroyRef.value.openDialog()
-}
-// 编辑分类
-const onEditCategroy = (row: any) => {
-    editCategroyRef.value.openDialog(row)
-}
- //删除分类
-const onDelCategroy = (row: any) => {
-    ElMessageBox.confirm(`此操作将永久删除分类:【${row.name}】,是否继续?`, '提示', {
-        confirmButtonText: '确认',
-        cancelButtonText: '取消',
-        type: 'warning',
-        draggable: true,
-        cancelButtonClass:'default-button'
-    }).then(() => {
-        deleteIvrCategroies(row.id).then(() => {
-            ElMessage.success('删除成功');
-            handleQuery();
-        });
-    }).catch(() => { });
-}
- //查询列表
-const handleQuery = () => {
-    state.loading = true;
-    getIvrCategories().then((res: any) => {
-        state.tableData = res?.result ?? [];
-        setTimeout(() => {
-            state.loading = false;
-        }, 300);
-    })
-}
-// 配置ivr
-// const configIvr = (row:any)=>{
-//     router.push({
-//         // path:"/ivrConfig/details",
-//         name:"ivrConfigDetails",
-//         params:{
-//             tagsViewName:row.name+'ivr配置',
-//             id: row.id,
-//         }
-//     })
-// }
-// 表格多选
-const handleSelectionChange = (val: any) => {
-	state.multipleSelection = val;
-}
-// 导出表格
-const onImportTable = ()=>{
-	const tabeHeader = [
-		{ key: 'name', colWidth: '', title: '分类名称', type: 'text', isCheck: true },
-        { key: 'remark', colWidth: '', title: '备注', type: 'text', isCheck: true },
-		{ key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
-	]
-	table2excel(tabeHeader, state.multipleSelection, `ivr分类管理 ${formatDate(new Date(),'YYYY-mm-dd HH-MM')}`);
-}
-onMounted(() => {
-    handleQuery();
-})
-
-</script>
-<style scoped lang="scss">
-.deviceManagement-ivrCategroy-container {
-    .el-table {
-        flex: 1;
-    }
-}
-</style>

+ 0 - 115
src/views/deviceManagement/tels/index.vue

@@ -1,115 +0,0 @@
-<template>
-    <div class="deviceManagement-tels-container layout-padding">
-        <div class="layout-padding-auto layout-padding-view pd20">
-            <div class="flex-center-between mb20">
-                <p class="table-title">信息列表</p>
-                <div>
-                    <el-button type="primary" @click="asyncDevice" v-waves v-auth="'300101'">
-                        <SvgIcon name="ele-Refresh" class="mr5" />同步
-                    </el-button>
-                    <el-button type="primary" v-waves @click="onImportTable" :disabled="!state.multipleSelection.length">
-                        <SvgIcon name="iconfont icon-daochu" class="mr5"/>导出
-                    </el-button>
-                </div>
-            </div>
-            <!-- 表格 -->
-            <el-table :data="tableData" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
-                <el-table-column type="selection" width="55" :reserve-selection="true"/>
-                <el-table-column prop="no" label="分机编号" show-overflow-tooltip></el-table-column>
-                <el-table-column prop="groupNames" label="所属分机组" show-overflow-tooltip></el-table-column>
-                <el-table-column prop="registerIP" label="注册IP" show-overflow-tooltip></el-table-column>
-                <el-table-column label="分机状态" show-overflow-tooltip prop="telStatusText"></el-table-column>
-                <el-table-column label="创建时间" show-overflow-tooltip width="170">
-                    <template #default="scope">
-                        <span>{{ formatDate(scope.row.creationTime,'YYYY-mm-dd HH:MM:SS') }}</span>
-                    </template>
-                </el-table-column>
-                <template #empty>
-                    <Empty />
-                </template>
-            </el-table>
-        </div>
-    </div>
-</template>
-
-<script lang="ts" name="tels" setup>
-import {  onMounted, reactive,toRefs } from "vue";
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { formatDate } from '/@/utils/formatTime';
-import table2excel from 'js-table2excel';
-// 引入api
-import { getTelsList, syncTel } from '/@/api/deviceManagement/tels';
-
-// 定义接口来定义对象的类型
-interface TelsState {
-    loading:boolean;
-    tableData:Array<any>;
-    multipleSelection:Array<any>
-}
-
-// 定义变量内容
-const state = reactive<TelsState>({
-    loading:false,
-    tableData:[],
-    multipleSelection:[]
-})
-const {loading,tableData} = toRefs(state)
-/** 获取分机列表 */
-const getList = () => {
-    state.loading = true;
-    getTelsList()
-        .then((response: any) => {
-            state.tableData = response.result ?? [];
-            setTimeout(() => {
-                state.loading = false;
-            }, 300);
-        })
-        .catch(() => {
-            state.loading = false;
-        });
-};
-// 同步
-const asyncDevice = () => {
-    ElMessageBox.confirm(`确定要将设备信息同步到数据库,是否继续?`, '提示', {
-        confirmButtonText: '确认',
-        cancelButtonText: '取消',
-        type: 'warning',
-        draggable: true,
-        cancelButtonClass:'default-button'
-    }).then(() => {
-        syncTel().then(() => {
-            getList();
-            ElMessage.success('同步成功');
-        }).catch((err: any) => {
-            console.log(err, '同步失败')
-        })
-    }).catch(() => { });
-}
-// 表格多选
-const handleSelectionChange = (val: any) => {
-	state.multipleSelection = val;
-}
-// 导出表格
-const onImportTable = ()=>{
-	const tabeHeader = [
-		{ key: 'no', colWidth: '', title: '分机编号', type: 'text', isCheck: true },
-		{ key: 'groupNames', colWidth: '', title: '所属分机组', type: 'text', isCheck: true },
-		{ key: 'registerIP', colWidth: '', title: '注册IP', type: 'text', isCheck: true },
-		{ key: '分机状态', colWidth: '', title: '分机状态', type: 'text', isCheck: true },
-		{ key: '创建时间', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
-	]
-	table2excel(tabeHeader, state.multipleSelection, `话机管理 ${formatDate(new Date(),'YYYY-mm-dd HH-MM')}`);
-}
-onMounted(() => {
-    getList();
-})
-
-</script>
-
-<style lang="scss" scoped>
-.deviceManagement-tels-container {
-    .el-table {
-        flex: 1;
-    }
-}
-</style>

+ 0 - 324
src/views/deviceManagement/telsGroup/index.vue

@@ -1,324 +0,0 @@
-<template>
-    <div class="deviceManagement-telsGroup-container layout-padding">
-        <div class="layout-padding-auto layout-padding-view pd20">
-            <div class="flex-center-between mb20">
-                <p class="table-title">信息列表</p>
-                <div>
-                    <el-button type="primary" @click="onAddTelsGroup" v-waves v-auth="'300202'">
-                        <SvgIcon name="ele-Plus" class="mr5" />新增
-                    </el-button>
-                    <el-button type="primary" v-waves @click="onImportTable"
-                        :disabled="!state.multipleSelection.length">
-                        <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
-                    </el-button>
-                </div>
-            </div>
-            <el-table :data="tableData" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
-                <el-table-column type="selection" width="55" :reserve-selection="true" />
-                <el-table-column prop="no" label="编号" show-overflow-tooltip></el-table-column>
-                <el-table-column prop="name" label="分机组名称" show-overflow-tooltip></el-table-column>
-                <el-table-column prop="distributionText" label="呼叫分配方式" show-overflow-tooltip></el-table-column>
-                <el-table-column label="是否默认分组" show-overflow-tooltip>
-                    <template #default="scope">
-                        {{ scope.row.isDefault ? '是' : '否' }}
-                    </template>
-                </el-table-column>
-                <el-table-column prop="remark" label="备注" show-overflow-tooltip></el-table-column>
-                <el-table-column prop="creationTime" label="创建时间" show-overflow-tooltip width="170">
-                    <template #default="scope">
-                        <span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
-                    </template>
-                </el-table-column>
-                <el-table-column label="操作" width="100" fixed="right" align="center">
-                    <template #default="scope">
-                        <el-button text type="primary" @click="configure(scope.row)" v-auth="'300203'" title="配置分机组">
-                            <SvgIcon name="ele-EditPen" size="var(--hotline-table-icon-font-size)" />
-                        </el-button>
-                    </template>
-                </el-table-column>
-                <template #empty>
-                    <Empty />
-                </template>
-            </el-table>
-        </div>
-        <!-- 配置分机组 -->
-        <el-dialog v-model="isShowDialog" draggable :title="dialogTitle">
-            <el-form :model="ruleForm" label-width="110px" ref="ruleFormRef">
-                <el-row :gutter="35">
-                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
-                        <el-form-item label="分机编号" prop="no">
-                            <el-input v-model="ruleForm.no" disabled></el-input>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
-                        <el-form-item label="分机组名称" prop="name"
-                            :rules="[{ required: true, message: '请输入分机组名称', trigger: 'blur' }]">
-                            <el-input v-model="ruleForm.name" placeholder="请输入分机组名称" clearable></el-input>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
-                        <el-form-item label="呼叫分配方式" prop="distribution"
-                            :rules="[{ required: true, message: '请选择ivr类型', trigger: 'change' }]">
-                            <el-select v-model="ruleForm.distribution" placeholder="请选择呼叫分配方式" class="w100">
-                                <el-option v-for="item in distributions" :key="item.key" :label="item.value"
-                                    :value="item.key" />
-                            </el-select>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
-                        <el-form-item label="默认分组" prop="isDefault"
-                            :rules="[{ required: false, message: '请选择ivr类型', trigger: 'change' }]">
-                            <el-switch v-model="ruleForm.isDefault" />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                        <el-form-item label="选择分机" prop="telNos"
-                            :rules="[{ required: true, message: '请选择分机', trigger: 'change' }]">
-                            <el-transfer v-model="ruleForm.telNos" :titles="['所有分机', '已选分机']" :props="{ key: 'no' }"
-                                :data="telsList" :filterable="true">
-                                <template #default="{ option }">
-                                    <span>分机 - {{ option.no }}</span>
-                                </template>
-                            </el-transfer>
-                        </el-form-item>
-                    </el-col>
-                    <!-- 语音文件 -->
-                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                        <el-form-item label="语音文件" prop="voiceList"
-                            :rules="[{ required: false, message: '选择语音文件', trigger: 'change' }]">
-                            <el-transfer v-model="ruleForm.voiceList" :titles="['选择语音文件', '按照选择顺序播放']"
-                                target-order="push" :data="voiceData" :filterable="true">
-                                <template #default="{ option }">
-                                    <span>{{ option.label }}</span>
-                                </template>
-                            </el-transfer>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                        <el-form-item label="备注" prop="remark">
-                            <el-input v-model="ruleForm.remark" type="textarea" :autosize="{ minRows: 4, maxRows: 6 }"
-                                placeholder="请输入备注" clearable></el-input>
-                        </el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-
-            <template #footer>
-                <span class="dialog-footer">
-                    <el-button @click="isShowDialog = false" class="default-button">取 消</el-button>
-                    <el-button type="primary" @click="save" :loading="loading">保 存</el-button>
-                </span>
-            </template>
-        </el-dialog>
-    </div>
-</template>
-
-<script lang="ts" name="tels" setup>
-import { ref, reactive, toRefs, onMounted } from "vue";
-import { ElMessage } from 'element-plus';
-import { storeToRefs } from 'pinia';
-import { formatDate } from '/@/utils/formatTime';
-import { useUserInfo } from '/@/stores/userInfo';
-import table2excel from 'js-table2excel';
-// 引入需要的api
-import { getTelsGroupList, addTelsGroup, updateTelsGroup, baseInfoTelsGroup } from '/@/api/deviceManagement/telsGroup';
-import { getTelsList } from '/@/api/deviceManagement/tels';
-import { voicequerylist } from '/@/api/deviceManagement/ivr';
-
-// 定义接口来定义对象的类型
-interface TelsGroupState {
-    ruleForm: {
-        no: string; // 分机组编号
-        name: string; // 分机组名称
-        remark: string; // 分机组备注
-        telNos: Array<any>; //选择的分机
-        voiceList: Array<any>; //语音列表
-        voice: string; //格式化之后的语音列表
-        distribution: object; //呼叫分配方式
-        isDefault: boolean;  //是否默认分组
-    }
-    distributions: Array<any>; //呼叫分配方式列表
-    loading: boolean;
-    tableData: Array<any>; //列表数据
-    voiceData: Array<any>; //音频文件
-    isShowDialog: boolean;
-    telsList: Array<any>; //分机列表
-    multipleSelection: Array<any>; //多选列表
-}
-
-// 定义变量内容
-const dialogTitle = ref('配置分机组');
-const ruleFormRef = ref();
-const state = reactive<TelsGroupState>({
-    ruleForm: {
-        no: '', // 分机组编号
-        name: '', // 分机组名称
-        remark: '', // 分机组备注
-        telNos: [],
-        voiceList: [],
-        voice: "",
-        distribution: {},
-        isDefault: false
-    },
-    distributions: [],
-    loading: false,
-    tableData: [],
-    voiceData: [],
-    isShowDialog: false,
-    telsList: [],
-    multipleSelection: []
-})
-const storesUserInfo = useUserInfo();
-const { userInfos } = storeToRefs(storesUserInfo);
-const { ruleForm, distributions, loading, tableData, voiceData, isShowDialog, telsList } = toRefs(state);
-/** 获取所有语音文件列表 */
-const getAudioList = () => {
-    if (userInfos.value.authBtnList.includes('300201')) { // 校验是否有权限 页面基础信息
-        voicequerylist().then((response: any) => {
-            state.voiceData = response.result.map((item: any) => {
-                return {
-                    key: item,
-                    label: item
-                }
-            })
-            setTimeout(() => {
-                state.loading = false;
-            }, 300);
-        }).catch(() => {
-            state.loading = false;
-        });
-        baseInfoTelsGroup().then((res: any) => {// 获取页面基础信息
-            state.distributions = res?.result.distributions ?? [];
-        })
-    } else {
-        ElMessage.warning('您没有权限查看页面基础信息');
-    }
-};
-/** 获取分机列表 */
-const getList = () => {
-    state.loading = true;
-    getTelsGroupList().then((response: any) => {
-        state.tableData = response?.result ?? [];
-        for (let i of state.tableData) {
-            i.voiceList = i.voice ? i.voice.split('+') : [];
-            i.telNos = i.tels;
-        }
-        setTimeout(() => {
-            state.loading = false;
-        }, 300);
-    }).catch(() => {
-        state.loading = false;
-    });
-};
-const configure = (row: any) => { //配置分机
-    state.ruleForm = JSON.parse(JSON.stringify(row));
-    dialogTitle.value = "配置分机组";
-    if (row.telNos) { //处理成穿梭框需要的数据格式
-        let arr: string[] = [];
-        for (let i of row.telNos) {
-            arr.push(i.no)
-        }
-        state.ruleForm.telNos = arr;
-    } else {
-        state.ruleForm.telNos = <any>[]
-    }
-    state.isShowDialog = true;
-}
-//新增分机组
-const onAddTelsGroup = () => {
-    dialogTitle.value = "新增分机组";
-    ruleFormRef.value?.resetFields();
-	ruleFormRef.value?.resetFields();
-    if (state.tableData.length) {
-        state.ruleForm = {
-            no: String(Number(state.tableData.length + 1)), // ivr编号
-            name: '',
-            remark: '',
-            telNos: [],
-            voiceList: [],
-            voice: "",
-            distribution: {},
-            isDefault: false
-        }
-    } else {
-        state.ruleForm.no = '1';
-    }
-    state.isShowDialog = true;
-}
-/** 获取分机列表 */
-const getTelList = () => {
-    getTelsList().then((response: any) => {
-        state.telsList = response?.result ?? [];
-    }).catch(() => {
-
-    });
-};
-// 保存分机组配置
-const save = () => {
-    ruleFormRef.value.validate((valid: boolean) => {
-        if (valid) {
-            if (state.ruleForm.voiceList.length) {
-                state.ruleForm.voice = state.ruleForm.voiceList.join("+");
-            }
-            state.loading = true;
-            if (dialogTitle.value == '新增分机组') {
-                addTelsGroup(state.ruleForm).then(() => {
-                    ElMessage.success("操作成功");
-                    setTimeout(() => {
-                        getList();
-                    }, 1000);
-                    state.isShowDialog = false;
-                    state.loading = false;
-                }).catch(() => {
-                    state.loading = false;
-                });
-            } else if (dialogTitle.value == '配置分机组') {
-                updateTelsGroup(state.ruleForm).then(() => {
-                    ElMessage.success("操作成功");
-                    setTimeout(() => {
-                        getList();
-                    }, 1000);
-                    state.isShowDialog = false;
-                    state.loading = false;
-                }).catch(() => {
-                    state.loading = false;
-                });
-            }
-
-        } else {
-            return false;
-        }
-    });
-}
-// 表格多选
-const handleSelectionChange = (val: any) => {
-    state.multipleSelection = val;
-}
-// 导出表格
-const onImportTable = () => {
-    const tabeHeader = [
-        { key: 'no', colWidth: '', title: '编号', type: 'text', isCheck: true },
-        { key: 'name', colWidth: '', title: '分机组名称', type: 'text', isCheck: true },
-        { key: 'distributionText', colWidth: '', title: '呼叫分配方式', type: 'text', isCheck: true },
-        { key: 'isDefault', colWidth: '', title: '是否默认分组', type: 'text', isCheck: true },
-        { key: 'remark', colWidth: '', title: '备注', type: 'text', isCheck: true },
-        { key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
-    ]
-    table2excel(tabeHeader, state.multipleSelection, `分机组管理 ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
-}
-// 页面加载时
-onMounted(() => {
-    getTelList(); //获取分机列表
-    getList();
-    getAudioList();
-});
-
-</script>
-
-<style lang="scss" scoped>
-.deviceManagement-telsGroup-container {
-    .el-table {
-        flex: 1;
-    }
-}
-</style>

+ 0 - 179
src/views/deviceManagement/trunks/index.vue

@@ -1,179 +0,0 @@
-<template>
-    <div class="deviceManagement-tels-container layout-padding">
-        <div class="layout-padding-auto layout-padding-view pd20">
-            <div class="flex-center-between mb20">
-                <p class="table-title">信息列表</p>
-                <div>
-                    <el-button type="primary" @click="addTrunks" v-waves v-auth="'300502'">
-                        <SvgIcon name="ele-Plus" class="mr5" />新增
-                    </el-button>
-                    <el-button type="primary" v-waves @click="onImportTable"
-                        :disabled="!state.multipleSelection.length">
-                        <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
-                    </el-button>
-                </div>
-            </div>
-            <!-- 表格 -->
-            <el-table :data="tableData" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
-                <el-table-column type="selection" width="55" :reserve-selection="true" />
-                <el-table-column prop="trunkId" label="线路号" show-overflow-tooltip width="100"></el-table-column>
-                <el-table-column prop="morningBegin" label="早上开始时间" show-overflow-tooltip width="130"></el-table-column>
-                <el-table-column prop="morningEnd" label="早上结束时间" show-overflow-tooltip width="130"></el-table-column>
-                <el-table-column prop="afterBegin" label="下午开始时间" show-overflow-tooltip width="130"></el-table-column>
-                <el-table-column prop="afterEnd" label="下午结束时间" show-overflow-tooltip width="130"></el-table-column>
-                <el-table-column prop="afterBegin" label="工作日" show-overflow-tooltip width="150">
-                    <template #default="scope">
-                        <span v-for="(item, index) in scope.row.workDay" :key="index">
-                            <span v-show="index">,</span>{{ item.weekName }}
-                        </span>
-                    </template>
-                </el-table-column>
-                <el-table-column prop="workCategoryModel" label="工作时间IVR" show-overflow-tooltip width="150">
-                    <template #default="scope">
-                        <span>{{ scope.row.workCategoryModel.name }}</span>
-                    </template>
-                </el-table-column>
-                <el-table-column prop="restCategoryModel" label="休息时间IVR" show-overflow-tooltip width="150">
-                    <template #default="scope">
-                        {{ scope.row.restCategoryModel.name }}
-                    </template>
-                </el-table-column>
-                <el-table-column prop="workToGroupModel" label="工作时间直转分机组" show-overflow-tooltip width="160">
-                    <template #default="scope">
-                        {{ scope.row.workToGroupModel.name }}
-                    </template>
-                </el-table-column>
-                <el-table-column prop="restToGroupModel" label="休息时间直转分机组" show-overflow-tooltip width="160">
-                    <template #default="scope">
-                        {{ scope.row.restToGroupModel.name }}
-                    </template>
-                </el-table-column>
-                <el-table-column label="是否启用" show-overflow-tooltip prop="isEnable">
-                    <template #default="scope">
-                        <el-tag type="success" v-if="scope.row.isEnable">启用</el-tag>
-                        <el-tag type="info" v-else>禁用</el-tag>
-                    </template>
-                </el-table-column>
-                <el-table-column label="创建时间" show-overflow-tooltip width="170">
-                    <template #default="scope">
-                        <span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
-                    </template>
-                </el-table-column>
-                <el-table-column label="操作" show-overflow-tooltip width="100" fixed="right" align="center">
-                    <template #default="scope">
-                        <el-button text type="primary" @click="updateTrunks(scope.row)" v-auth="'300503'" title="修改线路">
-                            <SvgIcon name="ele-EditPen" size="var(--hotline-table-icon-font-size)" />
-                        </el-button>
-                        <el-button text type="success" @click="ivrConfigure(scope.row)" v-auth="'300504'" title="删除线路">
-                            <SvgIcon name="ele-Delete" size="var(--hotline-table-icon-font-size)" />
-                        </el-button>
-                    </template>
-                </el-table-column>
-                <template #empty>
-                    <Empty />
-                </template>
-            </el-table>
-        </div>
-        <AddTrunks ref="addTrunksRef" @updateList="getListFn" />
-        <EditTrunks ref="EditTrunksRef" @updateList="getListFn" />
-    </div>
-</template>
-<script lang="ts" name="trunks" setup>
-import { onMounted, reactive, toRefs, defineAsyncComponent, ref } from "vue";
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { formatDate } from '/@/utils/formatTime';
-import table2excel from 'js-table2excel';
-// 引入api
-import { getList, removetrunk } from '/@/api/deviceManagement/trunks';
-
-// 引入组件
-const AddTrunks = defineAsyncComponent(() => import('/@/views/deviceManagement/trunks/component/add.vue'))
-const EditTrunks = defineAsyncComponent(() => import('/@/views/deviceManagement/trunks/component/edit.vue'))
-
-// 定义接口来定义对象的类型
-interface TelsState {
-    loading: boolean;
-    tableData: Array<any>;
-    multipleSelection: Array<any>
-}
-
-// 定义变量内容
-const state = reactive<TelsState>({
-    loading: false,
-    tableData: [],
-    multipleSelection: []
-})
-const { loading, tableData } = toRefs(state);
-const addTrunksRef = ref();
-const EditTrunksRef = ref();
-/** 获取线路列表 */
-const getListFn = () => {
-    state.loading = true;
-    getList().then((response: any) => {
-        state.tableData = response.result ?? [];
-        setTimeout(() => {
-            state.loading = false;
-        }, 300);
-    })
-        .catch(() => {
-            state.loading = false;
-        });
-};
-// 新增线路
-const addTrunks = () => {
-    addTrunksRef.value?.openDialog();
-}
-// 修改路线
-const updateTrunks = (row: any) => {
-    EditTrunksRef.value?.openDialog(row);
-}
-// 删除路线
-const ivrConfigure = (row: any) => {
-    ElMessageBox.confirm(`此操作将永久删除线路:【${row.trunkId}】, 是否继续?`, '提示', {
-        confirmButtonText: '删除',
-        cancelButtonText: '取消',
-        type: 'warning',
-        draggable: true,
-        cancelButtonClass: 'default-button'
-    }).then(() => {
-        removetrunk(row.id).then(() => {
-            ElMessage.success('删除成功');
-            getListFn();
-        })
-    }).catch(() => { });
-}
-// 表格多选
-const handleSelectionChange = (val: any) => {
-    state.multipleSelection = val;
-}
-// 导出表格
-const onImportTable = () => {
-    const tabeHeader = [
-        { key: 'trunkId', colWidth: '', title: '线路号', type: 'text', isCheck: true },
-        { key: 'morningBegin', colWidth: '', title: '早上开始时间', type: 'text', isCheck: true },
-        { key: 'morningEnd', colWidth: '', title: '早上结束时间', type: 'text', isCheck: true },
-        { key: 'afterBegin', colWidth: '', title: '下午开始时间', type: 'text', isCheck: true },
-        { key: 'afterEnd', colWidth: '', title: '下午结束时间', type: 'text', isCheck: true },
-        { key: 'telStatusText', colWidth: '', title: '工作日', type: 'text', isCheck: true },
-        { key: 'afterBegin', colWidth: '', title: '工作时间IVR', type: 'text', isCheck: true },
-        { key: 'afterBegin', colWidth: '', title: '休息时间IVR', type: 'text', isCheck: true },
-        { key: 'afterBegin', colWidth: '', title: '工作时间直转分机组', type: 'text', isCheck: true },
-        { key: 'afterBegin', colWidth: '', title: '休息时间直转分机组', type: 'text', isCheck: true },
-        { key: 'afterBegin', colWidth: '', title: '是否启用', type: 'text', isCheck: true },
-        { key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
-    ]
-    table2excel(tabeHeader, state.multipleSelection, `线路管理 ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
-}
-onMounted(() => {
-    getListFn();
-})
-
-</script>
-
-<style lang="scss" scoped>
-.deviceManagement-tels-container {
-    .el-table {
-        flex: 1;
-    }
-}
-</style>

+ 206 - 196
src/views/home/component/entrance.vue

@@ -1,243 +1,253 @@
 <template>
-    <div class="home-entrance-container">
-        <el-dialog v-model="isShowDialog" draggable title="常用入口设置" @opened="opened">
-            <div class="entrance-list">
-                <p class="entrance-list-title">首页入口</p>
-                <div class="mb20" v-loading="loading">
-                    <ul class="entrance-list-box" v-show="entranceList.length">
-                        <li v-for="(item, index) in entranceList" :key="index"
-                            class="entrance-list-box-item animate__animated animate__fadeInUp" :data-id="item.id">
-                            <img v-lazy="getImageUrl(item.fastIcon)" alt="" class="my-handle" />
-                            <p class="entrance-list-box-item-name">{{ item.pageName }}</p>
-                            <SvgIcon name="ele-RemoveFilled" class="plus-icon location" color="#ccc" size="24px"
-                                @click="removeOne(item)" />
-                        </li>
-                    </ul>
-                    <Empty v-show="!entranceList.length" />
-                </div>
-            </div>
-            <div class="entrance-select">
-                <p class="entrance-select-title">
-                    <span>系统功能</span>
-                    <el-input v-model="searchKey" :prefix-icon="Search" placeholder="请输入关键字" class="input"
-                        @keyup.enter="getEntranceSelect">
-                        <template #suffix>
-                            <el-button type="primary" size="small" round @click="getEntranceSelect">搜索</el-button>
-                        </template>
-                    </el-input>
-                </p>
-                <div class="mb20" v-loading="selectLoading">
-                    <template v-if="entranceSelect.length">
-                        <ul class="entrance-list-box">
-                            <li class="entrance-list-box-item animate__animated animate__fadeInDown"
-                                v-for="(item, index) in entranceSelect" :key="index">
-                                <img v-lazy="getImageUrl(item.fastIcon)" alt="" class="mb10" />
-                                <p class="entrance-list-box-item-name">{{ item.pageName }}</p>
-                                <SvgIcon name="ele-CirclePlusFilled" class="remove-icon location"
-                                    color="var(--el-color-primary)" size="24px" @click="plusOne(item)" />
-                            </li>
-                        </ul>
-                    </template>
-                    <Empty v-else />
-                </div>
-            </div>
-            <template #footer>
-                <span class="dialog-footer">
-                    <el-button @click="isShowDialog = false" class="default-button">取 消</el-button>
-                    <el-button type="primary" @click="onSubmit">保 存</el-button>
-                </span>
-            </template>
-        </el-dialog>
-    </div>
+	<div class="home-entrance-container">
+		<el-dialog v-model="isShowDialog" draggable title="常用入口设置" @opened="opened">
+			<div class="entrance-list">
+				<p class="entrance-list-title">首页入口</p>
+				<div class="mb20" v-loading="loading">
+					<ul class="entrance-list-box" v-show="entranceList.length">
+						<li
+							v-for="(item, index) in entranceList"
+							:key="index"
+							class="entrance-list-box-item animate__animated animate__fadeInUp"
+							:data-id="item.id"
+						>
+							<img v-lazy="getImageUrl(item.fastIcon)" alt="" class="my-handle" />
+							<p class="entrance-list-box-item-name">{{ item.pageName }}</p>
+							<SvgIcon name="ele-RemoveFilled" class="plus-icon location" color="#ccc" size="24px" @click="removeOne(item)" />
+						</li>
+					</ul>
+					<Empty v-show="!entranceList.length" />
+				</div>
+			</div>
+			<div class="entrance-select">
+				<p class="entrance-select-title">
+					<span>系统功能</span>
+					<el-input v-model="searchKey" :prefix-icon="Search" placeholder="请输入关键字" class="input" @keyup.enter="getEntranceSelect">
+						<template #suffix>
+							<el-button type="primary" size="small" round @click="getEntranceSelect">搜索</el-button>
+						</template>
+					</el-input>
+				</p>
+				<div class="mb20" v-loading="selectLoading">
+					<template v-if="entranceSelect.length">
+						<ul class="entrance-list-box">
+							<li class="entrance-list-box-item animate__animated animate__fadeInDown" v-for="(item, index) in entranceSelect" :key="index">
+								<img v-lazy="getImageUrl(item.fastIcon)" alt="" class="mb10" />
+								<p class="entrance-list-box-item-name" :title="item.pageName">{{ item.pageName }}</p>
+								<SvgIcon
+									name="ele-CirclePlusFilled"
+									class="remove-icon location"
+									color="var(--el-color-primary)"
+									size="24px"
+									@click="plusOne(item)"
+								/>
+							</li>
+						</ul>
+					</template>
+					<Empty v-else />
+				</div>
+			</div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="isShowDialog = false" class="default-button">取 消</el-button>
+					<el-button type="primary" @click="onSubmit">保 存</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
 </template>
 
 <script lang="ts" setup>
 import { reactive, toRefs } from 'vue';
 import { ElMessage } from 'element-plus';
 import { Search } from '@element-plus/icons-vue';
-import { getImageUrl } from "/@/utils/tools";
+import { getImageUrl } from '/@/utils/tools';
 import { geFastMenu, fastMenu, setFastMenu } from '/@/api/home';
 import Sortable from 'sortablejs';
 interface StateBacklist {
-    isShowDialog: boolean;
-    searchKey: string;
-    entranceList: any[];
-    sortEntranceList: any[];
-    entranceSelect: any[];
-    loading: boolean;
-    selectLoading: boolean;
-    sortable: any;
+	isShowDialog: boolean;
+	searchKey: string;
+	entranceList: any[];
+	sortEntranceList: any[];
+	entranceSelect: any[];
+	loading: boolean;
+	selectLoading: boolean;
+	sortable: any;
 }
 const state = reactive<StateBacklist>({
-    isShowDialog: false,
-    searchKey: '',
-    entranceList: [],
-    sortEntranceList: [],
-    entranceSelect: [],
-    loading: false,
-    sortable: '',
-    selectLoading: false,
-})
+	isShowDialog: false,
+	searchKey: '',
+	entranceList: [],
+	sortEntranceList: [],
+	entranceSelect: [],
+	loading: false,
+	sortable: '',
+	selectLoading: false,
+});
 const { isShowDialog, searchKey, entranceList, entranceSelect, loading, selectLoading } = toRefs(state);
-const emit = defineEmits(['updateEntrance', 'openDialog', 'closeDialog'])
+const emit = defineEmits(['updateEntrance', 'openDialog', 'closeDialog']);
 // 打开弹窗
 const openDialog = () => {
-    state.isShowDialog = true;
-    getEntrance();
-    getEntranceSelect();
-    emit('openDialog')
-}
+	state.isShowDialog = true;
+	getEntrance();
+	getEntranceSelect();
+	emit('openDialog');
+};
 // 打开完成
 const opened = () => {
-    initSortable();
-}
+	initSortable();
+};
 // 关闭弹窗
 const closeDialog = () => {
-    state.isShowDialog = false;
-    emit('closeDialog')
+	state.isShowDialog = false;
+	emit('closeDialog');
 };
 // 拖拽排序
 const initSortable = () => {
-    const el = <HTMLElement>document.querySelector('.entrance-list-box');
-    if (!el) return false;
-    state.sortable.el && state.sortable.destroy();
-    state.sortable = Sortable.create(el, {
-        animation: 300,
-        handle: '.my-handle',
-        onEnd: () => {
-            const sortEndList: any = [];
-            state.sortable.toArray().map((val: any) => {
-                state.entranceList.map((v: any) => {
-                    if (v.id == val) sortEndList.push({ ...v });
-                });
-            });
-            state.sortEntranceList = sortEndList;
-        },
-    });
-}
+	const el = <HTMLElement>document.querySelector('.entrance-list-box');
+	if (!el) return false;
+	state.sortable.el && state.sortable.destroy();
+	state.sortable = Sortable.create(el, {
+		animation: 300,
+		handle: '.my-handle',
+		onEnd: () => {
+			const sortEndList: any = [];
+			state.sortable.toArray().map((val: any) => {
+				state.entranceList.map((v: any) => {
+					if (v.id == val) sortEndList.push({ ...v });
+				});
+			});
+			state.sortEntranceList = sortEndList;
+		},
+	});
+};
 // 获取我的入口
 const getEntrance = () => {
-    state.loading = true;
-    geFastMenu().then((res: any) => {
-        state.entranceList = res?.result ?? [];
-        setTimeout(() => {
-            state.loading = false;
-        }, 300);
-    }).catch(() => {
-        state.loading = false;
-    })
-}
+	state.loading = true;
+	geFastMenu()
+		.then((res: any) => {
+			state.entranceList = res?.result ?? [];
+			state.loading = false;
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
 // 获取可选入口
 const getEntranceSelect = () => {
-    state.selectLoading = true;
-    fastMenu({ name: state.searchKey }).then((res: any) => {
-        state.entranceSelect = res?.result ?? [];
-        setTimeout(() => {
-            state.selectLoading = false;
-        }, 300);
-    }).catch(() => {
-        state.selectLoading = false;
-    })
-}
+	state.selectLoading = true;
+	fastMenu({ name: state.searchKey })
+		.then((res: any) => {
+			state.entranceSelect = res?.result ?? [];
+			setTimeout(() => {
+				state.selectLoading = false;
+			}, 300);
+		})
+		.catch(() => {
+			state.selectLoading = false;
+		});
+};
 // 移除
 const removeOne = (val: any) => {
-    state.entranceList = state.entranceList.filter((i: any) => i.id !== val.id);
-    state.entranceSelect.push(val);
-}
+	state.entranceList = state.entranceList.filter((i: any) => i.id !== val.id);
+	state.entranceSelect.push(val);
+};
 // 新增
 const plusOne = (val: any) => {
-    state.entranceList.push(val)
-    state.entranceSelect = state.entranceSelect.filter((i: any) => i.id !== val.id);
-}
+	state.entranceList.push(val);
+	state.entranceSelect = state.entranceSelect.filter((i: any) => i.id !== val.id);
+};
 // 保存
 const onSubmit = async () => {
-    try {
-        let req = state.sortEntranceList.length ? state.sortEntranceList.map((item: any) => item.permissionCode) : state.entranceList.map((item: any) => item.permissionCode);
-        await setFastMenu({ fastMenuArr: req });
-        ElMessage.success("操作成功");
-        emit("updateEntrance");
-    } catch {
-        // 处理错误
-        isShowDialog.value = false;
-    } finally {
-        isShowDialog.value = false;
-    }
-}
-defineExpose({ closeDialog, openDialog }) //暴漏方法
+	try {
+		let req = state.sortEntranceList.length
+			? state.sortEntranceList.map((item: any) => item.permissionCode)
+			: state.entranceList.map((item: any) => item.permissionCode);
+		await setFastMenu({ fastMenuArr: req });
+		ElMessage.success('操作成功');
+		emit('updateEntrance');
+	} catch {
+		// 处理错误
+		isShowDialog.value = false;
+	} finally {
+		isShowDialog.value = false;
+	}
+};
+defineExpose({ closeDialog, openDialog }); //暴漏方法
 </script>
 <style lang="scss" scoped>
 .home-entrance-container {
-    .entrance-list {
-        color: var(--hotline-color-text-main);
+	.entrance-list {
+		color: var(--hotline-color-text-main);
 
-        &-title {
-            padding-bottom: 20px;
-            font-size: var(--el-font-size-medium);
-        }
+		&-title {
+			padding-bottom: 20px;
+			font-size: var(--el-font-size-medium);
+		}
 
-        &-box {
-            display: grid;
-            justify-content: space-between;
-            grid-template-columns: repeat(auto-fill, 110px);
-            grid-gap: 15px;
-            margin-bottom: 20px;
+		&-box {
+			display: grid;
+			justify-content: space-between;
+			grid-template-columns: repeat(auto-fill, 110px);
+			grid-gap: 15px;
+			margin-bottom: 20px;
 
-            &-item {
-                background: #F0F4FF;
-                border-radius: 8px;
-                text-align: center;
-                padding: 10px 20px;
-                width: 110px;
-                height: 110px;
-                color: var(--el-text-color-regular);
-                position: relative;
-                user-select: none;
+			&-item {
+				background: #f0f4ff;
+				border-radius: 8px;
+				text-align: center;
+				padding: 10px 20px;
+				width: 110px;
+				height: 110px;
+				color: var(--el-text-color-regular);
+				position: relative;
+				user-select: none;
 
-                .my-handle {
-                    width: 40px;
-                    height: 50px;
-                    margin-bottom: 10px;
-                    cursor: grab;
-                }
+				.my-handle {
+					width: 40px;
+					height: 50px;
+					margin-bottom: 10px;
+					cursor: grab;
+				}
 
-                .location {
-                    position: absolute;
-                    top: -5px;
-                    right: -5px;
-                    cursor: pointer;
-                }
+				.location {
+					position: absolute;
+					top: -5px;
+					right: -5px;
+					cursor: pointer;
+				}
 
-                &-name {
-                    width: 70px;
-                    overflow: hidden;
-                    white-space: nowrap;
-                    text-overflow: ellipsis;
-                }
-            }
-        }
-    }
+				&-name {
+					width: 70px;
+					overflow: hidden;
+					white-space: nowrap;
+					text-overflow: ellipsis;
+				}
+			}
+		}
+	}
 
-    .entrance-select {
-        color: var(--hotline-color-text-main);
+	.entrance-select {
+		color: var(--hotline-color-text-main);
 
-        &-title {
-            padding-bottom: 20px;
-            font-size: var(--el-font-size-medium);
+		&-title {
+			padding-bottom: 20px;
+			font-size: var(--el-font-size-medium);
 
-            span {
-                display: inline-block;
-                min-width: 80px;
-                margin-right: 40px;
-            }
+			span {
+				display: inline-block;
+				min-width: 80px;
+				margin-right: 40px;
+			}
 
-            .input {
-                max-width: 350px;
+			.input {
+				max-width: 350px;
 
-                :deep(.el-input__wrapper) {
-                    border-radius: 40px;
-                }
-            }
-        }
-    }
+				:deep(.el-input__wrapper) {
+					border-radius: 40px;
+				}
+			}
+		}
+	}
 }
-</style>
+</style>

+ 80 - 70
src/views/home/index.vue

@@ -22,7 +22,7 @@
 						</div>
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="6">
-						<div class="statistics-item box"  v-loading="loading">
+						<div class="statistics-item box" v-loading="loading">
 							<div class="statistics-title">
 								<img v-lazy="getImageUrl('home/connectionRate.png')" alt="" />
 								今日接通率
@@ -40,7 +40,7 @@
 						</div>
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="6">
-						<div class="statistics-item box"  v-loading="loading">
+						<div class="statistics-item box" v-loading="loading">
 							<div class="statistics-title">
 								<img v-lazy="getImageUrl('home/workOrder.png')" alt="" />
 								受理工单
@@ -51,7 +51,7 @@
 						</div>
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="6">
-						<div class="statistics-item box"  v-loading="loading">
+						<div class="statistics-item box" v-loading="loading">
 							<div class="statistics-title">
 								<img v-lazy="getImageUrl('home/wait.png')" alt="" />
 								当前等待
@@ -66,24 +66,38 @@
 
 				<div class="list-content box w100 mb20" v-loading="listLoading">
 					<div class="list-content-tabs">
-						<div class="list-content-tabs-item" :class="active === 'gd' ? 'active animate__animated animate__fadeInRight' : ''"
-							@click="changeList('gd')">工单池 <span v-show="activities.length">({{activities.length}})</span></div>
-						<div class="list-content-tabs-item" :class="active === 'db' ? 'active animate__animated animate__fadeInLeft' : ''"
-							@click="changeList('db')">待办列表 <span v-show="activities.length">({{activities.length}})</span></div>
+						<div
+							class="list-content-tabs-item"
+							:class="active === 'gd' ? 'active animate__animated animate__fadeInRight' : ''"
+							@click="changeList('gd')"
+						>
+							工单池 <span v-show="activities.length">({{ activities.length }})</span>
+						</div>
+						<div
+							class="list-content-tabs-item"
+							:class="active === 'db' ? 'active animate__animated animate__fadeInLeft' : ''"
+							@click="changeList('db')"
+						>
+							待办列表 <span v-show="activities.length">({{ activities.length }})</span>
+						</div>
 					</div>
 					<div class="list-content-timeline">
 						<p class="list-content-timeline-title">
-							<span>
-								<SvgIcon :name="getImageUrl('home/clock.png')" class="icons" size="28px"/><b>期满时间</b>
-							</span>
-							<el-button type="primary" text bg round v-show="activities.length"  @click="more('workOrder')">更多
-								<SvgIcon name="ele-Right" class="ml5" color="var(--el-color-primary-light-4)"/>
+							<span> <SvgIcon :name="getImageUrl('home/clock.png')" class="icons" size="28px" /><b>期满时间</b> </span>
+							<el-button type="primary" text bg round v-show="activities.length" @click="more('workOrder')"
+								>更多
+								<SvgIcon name="ele-Right" class="ml5" color="var(--el-color-primary-light-4)" />
 							</el-button>
 						</p>
 						<template v-if="activities.length">
 							<el-timeline>
-								<el-timeline-item v-for="(activity, index) in activities" :key="index" :type="activity.type"
-									placement="top" :timestamp="activity.timestamp">
+								<el-timeline-item
+									v-for="(activity, index) in activities"
+									:key="index"
+									:type="activity.type"
+									placement="top"
+									:timestamp="activity.timestamp"
+								>
 									<el-card shadow="never">
 										<h4>{{ activity.content }}</h4>
 									</el-card>
@@ -97,15 +111,14 @@
 			<!-- 常用入口 -->
 			<el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8" class="right-content">
 				<div class="right-entrance box w100" v-loading="entranceLoading">
-					<p class="right-entrance-title">常用入口
-						<span @click="customEntry">
-							<SvgIcon name="ele-Setting" class="mr5"/>自定义
-						</span>
+					<p class="right-entrance-title">
+						常用入口
+						<span @click="customEntry"> <SvgIcon name="ele-Setting" class="mr5" />自定义 </span>
 					</p>
 					<template v-if="entranceList.length">
 						<ul class="right-entrance-list">
 							<li class="right-entrance-list-item" v-for="(item, index) in entranceList" :key="index" :data-id="item.id" @click="goLink(item.path)">
-								<img v-lazy="getImageUrl(item.fastIcon)" alt="" class="my-handle"/>
+								<img v-lazy="getImageUrl(item.fastIcon)" alt="" class="my-handle" />
 								<p>{{ item.pageName }}</p>
 							</li>
 						</ul>
@@ -113,26 +126,25 @@
 					<Empty descriptionData="暂无常用入口" v-else />
 				</div>
 				<div class="right-notice mt20 box w100" v-loading="noticeLoading">
-					<p class="right-notice-title">通知公告
+					<p class="right-notice-title">
+						通知公告
 						<el-button type="primary" text bg round v-show="noticeList.length" @click="more('notice')">
 							更多
-							<SvgIcon name="ele-Right" class="ml5" color="var(--el-color-primary-light-4)"/>
+							<SvgIcon name="ele-Right" class="ml5" color="var(--el-color-primary-light-4)" />
 						</el-button>
 					</p>
 					<template v-if="noticeList.length">
-						<vue3-seamless-scroll :list="noticeList" class="right-notice-scroll" :hover="true"
-							:limitScrollNum="6">
+						<vue3-seamless-scroll :list="noticeList" class="right-notice-scroll" :hover="true" :limitScrollNum="6">
 							<div class="right-notice-scroll-item" v-for="(item, index) in noticeList" :key="index">
-								<span class="right-notice-scroll-item-name">
-									<SvgIcon name="iconfont icon-jiadayinliang" class="mr5 vd"/>{{ item.title }}
-								</span>
-								<span class="right-notice-scroll-item-date">{{ formatDate(item.date, 'YYYY-mm-dd')}}
+								<span class="right-notice-scroll-item-name"> <SvgIcon name="iconfont icon-jiadayinliang" class="mr5 vd" />{{ item.title }} </span>
+								<span class="right-notice-scroll-item-date"
+									>{{ formatDate(item.date, 'YYYY-mm-dd') }}
 									<SvgIcon name="ele-DArrowRight" class="ml5" />
 								</span>
 							</div>
 						</vue3-seamless-scroll>
 					</template>
-					<Empty v-else  descriptionData="暂无通知公告"/>
+					<Empty v-else descriptionData="暂无通知公告" />
 				</div>
 			</el-col>
 		</el-row>
@@ -141,10 +153,10 @@
 </template>
 
 <script lang="ts" setup name="home">
-import { defineAsyncComponent, reactive, toRefs, ref, onMounted } from "vue";
-import {useRouter} from "vue-router"
-import { Vue3SeamlessScroll } from "vue3-seamless-scroll";
-import { getImageUrl } from "/@/utils/tools";
+import { defineAsyncComponent, reactive, toRefs, ref, onMounted } from 'vue';
+import { useRouter } from 'vue-router';
+import { Vue3SeamlessScroll } from 'vue3-seamless-scroll';
+import { getImageUrl } from '/@/utils/tools';
 import { formatDate } from '/@/utils/formatTime';
 import { geFastMenu } from '/@/api/home';
 const Entrance = defineAsyncComponent(() => import('/@/views/home/component/entrance.vue'));
@@ -154,29 +166,29 @@ const state = reactive({
 	entranceList: <any>[],
 	noticeList: [
 		{
-			title: "市城区迁改23处盲道优化446个临时停车泊位",
+			title: '市城区迁改23处盲道优化446个临时停车泊位',
 			date: Date.now(),
 		},
 		{
-			title: "彭清华在成都调研指导疫情防控工作时强调",
+			title: '彭清华在成都调研指导疫情防控工作时强调',
 			date: Date.now(),
 		},
 		{
-			title: "广元市第二次全国污染源普查公报",
+			title: '广元市第二次全国污染源普查公报',
 			date: Date.now(),
 		},
 		{
-			title: "昭化:发展高效农林产业 打造乡村振兴“新引擎”",
+			title: '昭化:发展高效农林产业 打造乡村振兴“新引擎”',
 			date: Date.now(),
 		},
 		{
-			title: "市城区迁改23处盲道优化446个临时停车泊位",
+			title: '市城区迁改23处盲道优化446个临时停车泊位',
 			date: Date.now(),
 		},
 		{
-			title: "广元市第二次全国污染源普查公报",
+			title: '广元市第二次全国污染源普查公报',
 			date: Date.now(),
-		}
+		},
 	],
 	active: 'gd',
 	activities: [
@@ -189,58 +201,56 @@ const state = reactive({
 			content: '这是内容',
 			timestamp: '2018-04-03 20:46',
 			type: 'primary',
-		}
+		},
 	],
-	loading:false, //头部
-	listLoading:false,// 列表
-	entranceLoading:false, //入口
-	noticeLoading:false,// 公告
-	sortEntranceList:[],
-	sortable:<any>'',
-})
+	loading: false, //头部
+	listLoading: false, // 列表
+	entranceLoading: false, //入口
+	noticeLoading: false, // 公告
+	sortEntranceList: [],
+	sortable: <any>'',
+});
 const entranceRef = ref();
 // 自定义入口
 const customEntry = () => {
 	entranceRef.value.openDialog();
-}
+};
 //获取入口设置
 const getEntrance = () => {
 	state.entranceLoading = true;
-	geFastMenu().then((res:any)=>{
-		state.entranceList = res?.result ?? [];
-		setTimeout(() => {
+	geFastMenu()
+		.then((res: any) => {
+			state.entranceList = res?.result ?? [];
 			state.entranceLoading = false;
-		}, 300);
-	}).catch(()=>{
-		state.entranceLoading = false;
-	})
-}
+		})
+		.catch(() => {
+			state.entranceLoading = false;
+		});
+};
 // 跳转
-const goLink = (val:string)=>{
+const goLink = (val: string) => {
 	router.push(val);
-}
- //切换列表
+};
+//切换列表
 const changeList = (val: string) => {
 	if (state.active === val) return;
 	state.active = val;
-}
+};
 // 更多
-const more = (val:string)=>{
+const more = (val: string) => {
 	switch (val) {
 		case 'workOrder':
-			
 			break;
 		case 'notice':
-			
 			break;
 		default:
 			break;
 	}
-}
-onMounted(()=>{
+};
+onMounted(() => {
 	getEntrance();
-})
-const { entranceList, noticeList, active, activities,loading,entranceLoading,listLoading,noticeLoading } = toRefs(state);
+});
+const { entranceList, noticeList, active, activities, loading, entranceLoading, listLoading, noticeLoading } = toRefs(state);
 </script>
 <style lang="scss" scoped>
 .box {
@@ -384,11 +394,11 @@ const { entranceList, noticeList, active, activities,loading,entranceLoading,lis
 					height: 110px;
 					cursor: pointer;
 					color: var(--el-text-color-regular);
-					user-select:none;
-					.my-handle{
+					user-select: none;
+					.my-handle {
 						width: 40px;
 						height: 50px;
-						margin-top:15px;
+						margin-top: 15px;
 						margin-bottom: 13px;
 					}
 					&:hover {

+ 0 - 0
src/views/knowledgeBase/knowledgeMange/index.vue → src/views/knowledge/knowledge/index.vue


+ 3 - 3
src/views/system/configureManage/dictionarie/component/add.vue → src/views/system/configure/dict/component/add.vue

@@ -50,16 +50,16 @@
     </div>
 </template>
 
-<script setup lang="ts" name="systemAddUser">
+<script setup lang="ts" name="systemAddDict">
 import { reactive, ref } from 'vue';
 import { ElMessage } from 'element-plus';
 import { throttle } from '/@/utils/tools';
-import { addDic, dictypeList } from "/@/api/system/dictionarie";
+import { addDic, dictypeList } from "/@/api/system/dict";
 // 定义子组件向父组件传值/事件
 const emit = defineEmits(['updateList']);
 
 // 定义变量内容
-const state = reactive<UserState>({
+const state = reactive<any>({
     isShowDialog: false,
     ruleForm: {
         dicTypeId: '', // 分类id

+ 3 - 4
src/views/system/configureManage/dictionarie/component/edit.vue → src/views/system/configure/dict/component/edit.vue

@@ -50,20 +50,19 @@
     </div>
 </template>
 
-<script setup lang="ts" name="systemEditUser">
+<script setup lang="ts" name="systemEditDict">
 import { reactive, ref } from 'vue';
 import type { FormInstance } from 'element-plus';
 import { storeToRefs } from 'pinia';
 import { useUserInfo } from '/@/stores/userInfo';
 import { ElMessage } from 'element-plus';
 import { throttle } from '/@/utils/tools';
-import { editDic, getDetail, dictypeList } from "/@/api/system/dictionarie";
-import {UserState} from './data'
+import { editDic, getDetail, dictypeList } from "/@/api/system/dict";
 // 定义子组件向父组件传值/事件
 const emit = defineEmits(['updateList']);
 
 // 定义变量内容
-const state = reactive<UserState>({
+const state = reactive<any>({
     isShowDialog: false,
     ruleForm: {
         dicTypeId: '', // 分类id

+ 76 - 95
src/views/system/configureManage/dictionarie/index.vue → src/views/system/configure/dict/index.vue

@@ -30,8 +30,8 @@
 						<div class="flex-column">
 							<div class="flex-between mb20">
 								<el-form :model="state.queryParams" ref="ruleFormRef" :inline="true" @submit.native.prevent>
-									<el-form-item label="字典值" prop="dicDataValue">
-										<el-input v-model="state.queryParams.dicDataValue" placeholder="请输入字典值" clearable @keyup.enter="handleQuery" />
+									<el-form-item label="关键字" prop="keyword">
+										<el-input v-model="state.queryParams.keyword" placeholder="字典值名称/字典值" clearable @keyup.enter="handleQuery" />
 									</el-form-item>
 									<el-form-item>
 										<el-button type="primary" @click="handleQuery" :loading="state.loading" v-waves>
@@ -44,61 +44,34 @@
 								</el-form>
 								<div>
 									<el-button type="primary" @click="onOpenAddUser" v-waves v-auth="'100603'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
-									<!-- <el-button type="primary" @click="onRowDel" v-waves v-auth="'100104'"
-                                    :disabled="!state.multipleSelection.length">
+									<!-- <el-button type="primary" @click="onRowDel" v-waves v-auth="'100104'">
                                     <SvgIcon name="ele-Delete" class="mr5" />注销
                                 </el-button> -->
-									<el-button type="primary" v-waves @click="onImportTable" :disabled="!state.multipleSelection.length">
+									<!-- <el-button type="primary" v-waves @click="onImportTable">
 										<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
-									</el-button>
+									</el-button> -->
 								</div>
 							</div>
 							<!-- 表格 -->
-
-							<el-auto-resizer>
+							<el-auto-resizer class="table">
 								<template #default="{ height, width }">
 									<el-table-v2
-										v-model:expanded-row-keys="expandedRowKeys"
+										v-model:expanded-row-keys="state.expandedRowKeys"
 										:columns="state.columns"
 										:data="state.tableData"
 										expand-column-key="dicDataName"
 										fixed
 										:width="width"
 										:height="height"
-										@row-expand="onRowExpanded"
-										@expanded-rows-change="onExpandedRowsChange"
 									>
 										<template #overlay v-if="state.loading">
 											<div class="el-loading-mask" style="display: flex; align-items: center; justify-content: center">
-												<SvgIcon name="ele-Loading" saize="18px"></SvgIcon>
+												<SvgIcon name="ele-Loading" class="is-loading" size="28px" color="var(--el-color-primary)"></SvgIcon>
 											</div>
 										</template>
 									</el-table-v2>
 								</template>
 							</el-auto-resizer>
-
-							<!-- <el-table :data="state.tableData" v-loading="state.loading" row-key="id" @selection-change="handleSelectionChange">
-								<el-table-column type="selection" width="55" :reserve-selection="true" />
-								<el-table-column type="index" width="60" label="序号" />
-								<el-table-column prop="dicDataName" label="字典名称" show-overflow-tooltip></el-table-column>
-								<el-table-column prop="dicDataValue" label="字典值" show-overflow-tooltip></el-table-column>
-								<el-table-column prop="dicTypeCode" label="字典code" show-overflow-tooltip></el-table-column>
-								<el-table-column prop="creationTime" label="更新时间" show-overflow-tooltip width="170">
-									<template #default="scope">
-										<span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
-									</template>
-								</el-table-column>
-								<el-table-column label="操作" width="120" fixed="right" align="center">
-									<template #default="scope">
-										<el-button text type="primary" @click="onOpenEditUser(scope.row)" v-auth="'100604'" title="修改">
-											<SvgIcon name="ele-Edit" size="var(--hotline-table-icon-font-size)" />
-										</el-button>
-									</template>
-								</el-table-column>
-								<template #empty>
-									<Empty />
-								</template>
-							</el-table> -->
 						</div>
 					</el-scrollbar>
 				</el-col>
@@ -109,47 +82,30 @@
 		<Edit ref="editRef" @updateList="handleQuery" />
 	</div>
 </template>
-<script lang="ts" setup name="dictionarie">
+<script lang="ts" setup name="systemDict">
 import { defineAsyncComponent, ref, reactive, onMounted, h } from 'vue';
-import { ElButton,ElCheckbox } from 'element-plus';
-import type { ExpandedRowsChangeHandler, RowExpandHandler, FormInstance } from 'element-plus';
+import { ElButton } from 'element-plus';
+import type { FormInstance } from 'element-plus';
 import { storeToRefs } from 'pinia';
 import { useUserInfo } from '/@/stores/userInfo';
 import { ElMessage } from 'element-plus';
-import table2excel from 'js-table2excel';
 import { formatDate } from '/@/utils/formatTime';
 import { throttle } from '/@/utils/tools';
-import { dictypeList, getDataByTypeid } from '/@/api/system/dictionarie';
+import { dictypeList, getDataByTypeid } from '/@/api/system/dict';
 
 // 引入组件
-const Add = defineAsyncComponent(() => import('/@/views/system/configureManage/dictionarie/component/add.vue'));
-const Edit = defineAsyncComponent(() => import('/@/views/system/configureManage/dictionarie/component/edit.vue'));
+const Add = defineAsyncComponent(() => import('/@/views/system/configure/dict/component/add.vue'));
+const Edit = defineAsyncComponent(() => import('/@/views/system/configure/dict/component/edit.vue'));
 
-// 定义接口来定义对象的类型
-interface QueryState {
-	queryParams: {
-		dicDataValue: string;
-		typeid?: string;
-	};
-	tableData: Array<any>;
-	total: number;
-	loading: boolean;
-	multipleSelection: Array<any>;
-	dictypeList: Array<any>;
-	options: Array<any>;
-}
-
-const expandedRowKeys = ref<string[]>([]);
 // 定义变量内容
 const state = reactive<any>({
 	queryParams: {
-		dicDataValue: '',
+		keyword: '',
 		typeid: '',
 	},
 	tableData: [],
 	total: 0,
 	loading: false,
-	multipleSelection: [],
 	dictypeList: [],
 	options: [],
 	columns: [
@@ -157,13 +113,13 @@ const state = reactive<any>({
 			key: 'dicDataName',
 			dataKey: 'dicDataName', //需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填name
 			title: '字典名称',
-			width: 400,
+			width: 500,
 		},
 		{
 			key: 'dicDataValue',
 			dataKey: 'dicDataValue', //需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填name
 			title: '字典值',
-			width: 100,
+			width: 200,
 		},
 		{
 			key: 'dicTypeCode',
@@ -176,7 +132,7 @@ const state = reactive<any>({
 			dataKey: 'creationTime',
 			title: '更新时间',
 			width: 200,
-			cellRenderer: (data: any) => h('span', {  }, { default: () => formatDate(new Date(data.rowData.creationTime),'YYYY-mm-dd HH-MM')  }),
+			cellRenderer: (data: any) => h('span', {}, { default: () => formatDate(new Date(data.rowData.creationTime), 'YYYY-mm-dd HH-MM') }),
 		},
 		{
 			key: 'handle',
@@ -184,10 +140,15 @@ const state = reactive<any>({
 			width: 80,
 			fixed: 'right',
 			align: 'center',
-			cellRenderer: (data: any) =>
-				h(ElButton, { onClick: () => onOpenEditUser(data), type: 'primary', icon: 'Edit', link: true }, { default: () => '修改' }),
+			cellRenderer: (data: any) => {
+				if (userInfos.value.authBtnList.includes('100604')) {
+					// 权限判断
+					return h(ElButton, { onClick: () => onOpenEditUser(data), type: 'primary', icon: 'Edit', link: true }, { default: () => '修改' });
+				}
+			},
 		},
 	],
+	expandedRowKeys: [],
 });
 const addRef = ref(); //新增字典
 const editRef = ref(); //修改字典
@@ -195,16 +156,20 @@ const treRef = ref();
 const ruleFormRef = ref();
 const storesUserInfo = useUserInfo();
 const { userInfos } = storeToRefs(storesUserInfo);
-const onRowExpanded = ({ expanded }: Parameters<RowExpandHandler<any>>[0]) => {
-	console.log('Expanded:', expanded);
-};
-
-const onExpandedRowsChange = (expandedKeys: Parameters<ExpandedRowsChangeHandler>[0]) => {
-	console.log(expandedKeys);
-};
 /** 搜索按钮操作 节流操作 */
 const handleQuery = throttle(() => {
-	getList();
+	if (state.queryParams.keyword) {
+		state.loading = true;
+		state.expandedRowKeys = [];
+		emptyArr = [];
+		state.tableData = formatTable(state.tableData, state.queryParams.keyword);
+		state.expandedRowKeys = getExpand(state.tableData);
+		setTimeout(() => {
+			state.loading = false;
+		}, 300);
+	} else {
+		getList();
+	}
 }, 1000);
 // 获取字典类型列表
 const getDictypeList = () => {
@@ -228,10 +193,7 @@ const getList = () => {
 		getDataByTypeid(state.queryParams)
 			.then((response: any) => {
 				state.tableData = response?.result ?? [];
-				console.log(state.tableData);
-				setTimeout(() => {
-					state.loading = false;
-				}, 300);
+				state.loading = false;
 			})
 			.catch(() => {
 				state.loading = false;
@@ -240,10 +202,40 @@ const getList = () => {
 		ElMessage.warning('您没有字典列表权限');
 	}
 };
+// 搜索
+const formatTable = (list: any[], keyword: string) => {
+	if (!list.length || !Array.isArray(list)) return [];
+	let emptyArr: any[] = [];
+	list.map((item) => {
+		if (item.dicDataName.includes(keyword) || item.dicDataValue.includes(keyword)) {
+			if (item.children && Array.isArray(item.children) && item.children.length > 0) {
+				item.children = formatTable(item.children, keyword);
+			}
+			emptyArr.push(item);
+		} else if (item.children && Array.isArray(item.children) && item.children.length > 0) {
+			item.children = formatTable(item.children, keyword);
+			if (item.children.length) {
+				emptyArr.push(item);
+			}
+		}
+	});
+	return emptyArr;
+};
+let emptyArr: any[] = [];
+const getExpand = (list: any[]) => {
+	if (!list.length || !Array.isArray(list)) return [];
+	list.map((item) => {
+		if (item.children && Array.isArray(item.children) && item.children.length > 0) {
+			getExpand(item.children);
+		}
+		emptyArr.push(item.id);
+	});
+	return emptyArr;
+};
 // 点击节点
 const handleNodeClick = (data: any) => {
 	state.queryParams.typeid = data.id;
-	getList();
+	resetQuery(ruleFormRef.value)
 };
 // 打开新增字典弹窗
 const onOpenAddUser = () => {
@@ -251,19 +243,16 @@ const onOpenAddUser = () => {
 };
 // 打开修改字典弹窗
 const onOpenEditUser = (row: any) => {
-	console.log(row);
 	editRef.value.openDialog(row.rowData, state.tableData);
 };
-// 表格多选
-const handleSelectionChange = (val: any) => {
-	state.multipleSelection = val;
-};
 /** 重置按钮操作 */
-const resetQuery = throttle((formEl: FormInstance | undefined) => {
+const resetQuery = (formEl: FormInstance | undefined) => {
 	if (!formEl) return;
 	formEl.resetFields();
-	handleQuery();
-}, 1000);
+	getList();
+	state.expandedRowKeys = [];
+	emptyArr = [];
+}
 
 // 删除字典
 // const onRowDel = (row: any) => {
@@ -281,15 +270,7 @@ const resetQuery = throttle((formEl: FormInstance | undefined) => {
 //     }).catch(() => { });
 // };
 // 导出表格
-const onImportTable = () => {
-	const tabeHeader = [
-		{ key: 'dicDataName', colWidth: '', title: '字典名称', type: 'text', isCheck: true },
-		{ key: 'dicDataValue', colWidth: '', title: '字典值', type: 'text', isCheck: true },
-		{ key: 'dicTypeCode', colWidth: '', title: '字典code', type: 'text', isCheck: true },
-		{ key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
-	];
-	table2excel(tabeHeader, state.multipleSelection, `用户信息 ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
-};
+// const onImportTable = () => {};
 onMounted(() => {
 	getDictypeList();
 });
@@ -307,7 +288,7 @@ onMounted(() => {
 			display: flex;
 			flex-direction: column;
 			height: 100%;
-			.el-table {
+			.table {
 				flex: 1;
 			}
 		}

+ 4 - 41
src/views/system/configureManage/workflowManage/component/Jump.vue → src/views/system/configure/workflow/component/Jump.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="system-workflowManage-jump-container">
+    <div class="system-workflow-jump-container">
         <el-dialog v-model="state.isShowDialog" width="700px" draggable title="流程跳转">
             <el-form :model="state.ruleForm" ref="blacklistFormRef" label-width="100px">
                 <el-row :gutter="5">
@@ -58,20 +58,7 @@
 <script lang="ts" setup name="addBlacklist">
 import { ref, reactive } from 'vue';
 import { ElMessage } from 'element-plus';
-import { addBlacklist } from '/@/api/telsManage/blacklist';
-
-// 定义接口来定义对象的类型
-interface StateBacklist {
-    ruleForm: {
-        phoneNo: string; //电话号码
-        level: string; //级别
-        time: Array<any>; // 时间
-        remark: string; //清空说明
-    }
-    isShowDialog: boolean;
-    jumpList: Array<any>; // 跳转列表
-    personList: Array<any>; // 处理人列表
-}
+import { addBlacklist } from '/@/api/tels/blacklist';
 
 // 定义子组件向父组件传值/事件
 const emit = defineEmits(['updateList', 'openDialog', 'closeDialog'])
@@ -86,32 +73,8 @@ const state = reactive<any>({
         remark: ''
     },
     isShowDialog: false,
-    jumpList: [
-        {
-            label: '0',
-            value: '0'
-        },
-        {
-            label: '1',
-            value: '1'
-        }, {
-            label: '2',
-            value: '2'
-        },
-    ],
-    personList: [
-        {
-            label: '0',
-            value: '0'
-        },
-        {
-            label: '1',
-            value: '1'
-        }, {
-            label: '2',
-            value: '2'
-        },
-    ]
+    jumpList: [],
+    personList: []
 })
 // 打开弹窗
 const openDialog = (row: any) => {

+ 47 - 0
src/views/system/configure/workflow/component/add.vue

@@ -0,0 +1,47 @@
+<template>
+    <div class="layout-pd">
+        <LogicFlow ref='designerRef' v-model="flowData" />
+    </div>
+</template>
+<script setup lang="ts" name="workflowAdd">
+import { defineAsyncComponent, ref } from "vue";
+const LogicFlow = defineAsyncComponent(() => import('/@/components/LogicFlow/index.vue'));
+const designerRef = ref(null as any);
+let flowData = ref({
+    "name": "",
+    "code": "",
+    "id": "",
+    "moduleName": "",
+    "moduleCode": "",
+    "nodes": [
+        {
+            "id": "start",
+            "type": "hotline:start",
+            "x": 780,
+            "y": 120,
+            "properties": {},
+            "text": {
+                "x": 780,
+                "y": 80,
+                "value": "开始"
+            }
+        },
+        {
+            "id": "end",
+            "type": "hotline:end",
+            "x": 780,
+            "y": 400,
+            "properties": {},
+            "text": {
+                "x": 780,
+                "y": 440,
+                "value": "结束"
+            }
+        }
+    ],
+    "edges": []
+});
+</script>
+
+<style scoped>
+</style>

+ 4 - 4
src/views/system/configureManage/workflowManage/component/index.vue → src/views/system/configure/workflow/component/edit.vue

@@ -3,10 +3,10 @@
         <LogicFlow ref='designerRef' v-model="flowData" />
     </div>
 </template>
-<script setup lang="ts" name="workflowTemplate">
+<script setup lang="ts" name="workflowEdit">
 import { defineAsyncComponent, ref, onMounted } from "vue";
 import { useRoute } from "vue-router";
-import { getWorkFlowDetail } from '/@/api/system/workflowManage';
+import { getWorkFlowDetail } from '/@/api/system/workflow';
 const LogicFlow = defineAsyncComponent(() => import('/@/components/LogicFlow/index.vue'));
 const designerRef = ref(null as any);
 let flowData = ref({
@@ -46,8 +46,8 @@ let flowData = ref({
 const route = useRoute();
 onMounted(async () => {
     // 查询详情
-    if (route.query.id) {
-        const res: any = await getWorkFlowDetail(route.query.id);
+    if (route.params.id) {
+        const res: any = await getWorkFlowDetail(route.params.id);
         flowData.value = res.result;
     }
 })

+ 397 - 0
src/views/system/configure/workflow/index.vue

@@ -0,0 +1,397 @@
+<template>
+	<div class="system-workflow-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<el-tabs v-model="activeName" @tab-change="handleClick" class="h100">
+				<el-tab-pane label="流程模板" name="template"></el-tab-pane>
+				<el-tab-pane label="流程实例" name="example"></el-tab-pane>
+				<div class="flex-column">
+					<el-form :model="queryParams" ref="ruleFormRef" :inline="true" @submit.native.prevent class="mt15" v-show="activeName === 'example'">
+						<el-form-item label="关键字查询" prop="Keyword">
+							<el-input
+								v-model="queryParams.Keyword"
+								placeholder="流程标题/业务模块/流程ID"
+								style="width: 300px"
+								clearable
+								@keyup.enter="getList(activeName)"
+							/>
+						</el-form-item>
+						<el-form-item>
+							<el-button type="primary" @click="getList(activeName)" :loading="loading" v-waves>
+								<SvgIcon name="ele-Search" class="mr5" />查询
+							</el-button>
+							<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+						</el-form-item>
+					</el-form>
+					<div class="flex-center-between mb20">
+						<p class="table-title">信息列表</p>
+						<div>
+							<el-button type="primary" @click="onAddTemp" v-waves v-if="activeName === 'template'">
+								<SvgIcon name="ele-Plus" class="mr5" />新增
+							</el-button>
+							<el-button type="primary" :disabled="!state.multipleSelection.length" v-waves @click="onImportTable">
+								<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+							</el-button>
+						</div>
+					</div>
+					<!-- 表格 -->
+					<el-table :data="tableList" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
+						<el-table-column type="selection" width="55" :reserve-selection="true" />
+						<el-table-column type="index" width="60" label="序号" />
+						<!-- 模板 -->
+						<template v-if="activeName === 'template'">
+							<el-table-column prop="moduleName" label="业务模块" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="name" label="模板名称" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="code" label="模板编码" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="creationTime" label="更新时间" show-overflow-tooltip>
+								<template #default="scope">
+									<span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+								</template>
+							</el-table-column>
+							<el-table-column prop="statusText" label="状态" show-overflow-tooltip></el-table-column>
+							<el-table-column label="操作" width="150" fixed="right" align="center">
+								<!-- 草稿0 启用1 禁用2 -->
+								<template #default="scope">
+									<el-button text type="primary" @click="onEditTemp(scope.row)" title="修改">
+										修改
+										<!-- <SvgIcon name="ele-VideoPlay" size="var(--hotline-table-icon-font-size)" /> -->
+									</el-button>
+									<el-button text type="success" v-if="scope.row.status === 0" @click="onReleaseTemp(scope.row)" title="发布">
+										发布
+										<!-- <SvgIcon name="ele-Download" size="var(--hotline-table-icon-font-size)" /> -->
+									</el-button>
+									<el-button text type="warning" v-if="scope.row.status === 2" @click="tempEnable(scope.row)" title="启用">
+										启用
+										<!-- <SvgIcon name="ele-Connection" size="var(--hotline-table-icon-font-size)" /> -->
+									</el-button>
+									<el-button text type="danger" v-if="scope.row.status === 1" @click="tempDisable(scope.row)" title="禁用">
+										禁用
+										<!-- <SvgIcon name="ele-Connection" size="var(--hotline-table-icon-font-size)" /> -->
+									</el-button>
+									<!-- 发布之后不能修改 -->
+									<el-button text v-if="scope.row.status === 0" type="danger" @click="onDeleteTemp(scope.row)" title="删除">
+										删除
+										<!-- <SvgIcon name="ele-Delete" size="var(--hotline-table-icon-font-size)" /> -->
+									</el-button>
+								</template>
+							</el-table-column>
+						</template>
+						<!-- 实例 -->
+						<template v-else-if="activeName === 'example'">
+							<el-table-column prop="name" label="流程标题" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="id" label="流程ID" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="moudleName" label="业务模块" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="temName" label="流程模板" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="time" label="创建时间" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="huanjie" label="当前环节到达" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="huanjie1" label="当前环节" show-overflow-tooltip></el-table-column>
+							<el-table-column prop="person" label="当前处理人" show-overflow-tooltip></el-table-column>
+							<el-table-column label="操作" width="120" fixed="right" align="center">
+								<template #default="scope">
+									<el-button text type="primary" @click="onLink(scope.row)" title="跳转">
+										跳转
+										<!-- <SvgIcon name="ele-VideoPlay" size="var(--hotline-table-icon-font-size)" /> -->
+									</el-button>
+									<el-button text type="danger" @click="onStopProcess(scope.row)" title="终止流程">
+										终止流程
+										<!-- <SvgIcon name="ele-Download" size="var(--hotline-table-icon-font-size)" /> -->
+									</el-button>
+								</template>
+							</el-table-column>
+						</template>
+						<template #empty>
+							<Empty />
+						</template>
+					</el-table>
+					<!-- 分页 -->
+					<pagination :total="total" v-model:page="queryParams.PageIndex" v-model:limit="queryParams.PageSize" @pagination="getList(activeName)" />
+				</div>
+			</el-tabs>
+		</div>
+		<Jump ref="jumpRef" @updateList="getList(state.activeName)" />
+	</div>
+</template>
+
+<script lang="ts" setup name="systemWorkflow">
+import { ref, reactive, toRefs, onMounted, defineAsyncComponent,onActivated,onUnmounted } from 'vue';
+import { useRouter } from 'vue-router';
+import type { FormInstance } from 'element-plus';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { formatDate } from '/@/utils/formatTime';
+import table2excel from 'js-table2excel';
+import { storeToRefs } from 'pinia';
+import { useThemeConfig } from '/@/stores/themeConfig';
+import mittBus from '/@/utils/mitt';
+// 引入节流
+import { throttle } from '/@/utils/tools';
+import {
+	workflowList,
+	workflowPaged,
+	workflowDelete,
+	publishOnList,
+	workflowEnable,
+	workflowDisable,
+	workflowRerminate,
+	WorkflowHasdefine,
+} from '/@/api/system/workflow';
+
+// 引入组件
+const Jump = defineAsyncComponent(() => import('/@/views/system/configure/workflow/component/Jump.vue'));
+
+// 定义接口来定义对象的类型
+interface QueryState {
+	activeName: string;
+	queryParams: {
+		PageIndex: number;
+		PageSize: number;
+		Keyword: string;
+	};
+	tableList: Array<any>;
+	loading: boolean;
+	total: number;
+	multipleSelection: Array<any>;
+}
+
+// 定义变量内容
+const state = reactive(<QueryState>{
+	activeName: 'template',
+	queryParams: {
+		PageIndex: 1,
+		PageSize: 10,
+		Keyword: '',
+	},
+	tableList: [],
+	loading: false,
+	total: 0,
+	multipleSelection: [],
+});
+const storesThemeConfig = useThemeConfig();
+const { themeConfig } = storeToRefs(storesThemeConfig);
+const { queryParams, tableList, loading, total, activeName } = toRefs(state);
+const ruleFormRef = ref<FormInstance>();
+const jumpRef = ref(null as any);
+const router = useRouter();
+/** 获取列表 */
+const getList = (val: string) => {
+	queryParams.value.PageIndex = 1;
+	state.loading = true;
+	switch (val) {
+		case 'template':
+			workflowList(queryParams.value)
+				.then((response: any) => {
+					state.tableList = response?.result.items ?? [];
+					state.total = response?.result.total;
+					state.loading = false;
+				})
+				.catch(() => {
+					state.loading = false;
+				});
+			break;
+		case 'example':
+			workflowPaged(queryParams.value)
+				.then((response: any) => {
+					state.tableList = response.result?.items ?? [];
+					state.total = response.result?.total ?? 0;
+					state.total = 1;
+					state.loading = false;
+				})
+				.catch(() => {
+					state.loading = false;
+				});
+			break;
+		default:
+			break;
+	}
+};
+// 多选表格
+const handleSelectionChange = (val: any) => {
+	state.multipleSelection = val;
+};
+/** 重置按钮操作 */
+const resetQuery = throttle((formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	getList(state.activeName);
+}, 1000);
+// 切换tab 查询列表
+const handleClick = (val: string) => {
+	getList(val);
+};
+// 导出表格
+const onImportTable = () => {
+	const tableHeader = [
+		{ key: 'userName', colWidth: '', title: '用户名称', type: 'text', isCheck: true },
+		{ key: 'fromNo', colWidth: '', title: '主叫号码', type: 'text', isCheck: true },
+		{ key: 'toNo', colWidth: '', title: '被叫号码', type: 'text', isCheck: true },
+		{ key: 'callTypeText', colWidth: '', title: '通话类型', type: 'text', isCheck: true },
+		{ key: 'callStatusText', colWidth: '', title: '通话状态', type: 'text', isCheck: true },
+		{ key: 'callDirectionText', colWidth: '', title: '呼叫方向', type: 'text', isCheck: true },
+		{ key: 'endByText', colWidth: '', title: '通话结束方', type: 'text', isCheck: true },
+		{ key: 'phoneIspText', colWidth: '', title: '运营商', type: 'text', isCheck: true },
+		{ key: 'ringOffTypeText', colWidth: '', title: '挂断类型', type: 'text', isCheck: true },
+		{ key: 'attribution', colWidth: '', title: '归属地', type: 'text', isCheck: true },
+		// { key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
+		// { key: 'image', colWidth: '', width: '70', height: '40', title: '图片描述', type: 'image', isCheck: true },
+	];
+	table2excel(tableHeader, state.multipleSelection, `${themeConfig.value.globalTitle} ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
+};
+// 新增模板
+const onAddTemp = () => {
+	router.push({
+		path: '/system/configure/workflow/detail',
+		query: {
+			tagsViewName: '新增流程模板',
+		},
+	});
+};
+// 修改模板
+const onEditTemp = (row: any) => {
+	router.push({
+		name:'workflowEdit',
+		params: {
+			tagsViewName: '流程模板 '+row.id,
+			id: row.id,
+		},
+	});
+};
+// 删除模板
+const onDeleteTemp = (row: any) => {
+	ElMessageBox.confirm(`此操作将删除模板:“${row.name}”,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			workflowDelete(row.id).then(() => {
+				ElMessage.success('删除成功');
+				getList(state.activeName);
+			});
+		})
+		.catch(() => {});
+};
+// 发布模板
+const onReleaseTemp = async (row: any) => {
+	const response: any = await WorkflowHasdefine(row.moduleCode);
+	if (response.result) {
+		//若已存在有效模板
+		ElMessageBox.confirm(`业务模块【${row.moduleName}】已有流程模板,确认覆盖当前版本?`, '提示', {
+			confirmButtonText: '确认',
+			cancelButtonText: '取消',
+			type: 'warning',
+			draggable: true,
+			cancelButtonClass: 'default-button',
+			autofocus: false,
+		})
+			.then(() => {
+				publishOnList(row.id).then(() => {
+					ElMessage.success('发布成功');
+					getList(state.activeName);
+				});
+			})
+			.catch(() => {});
+	} else {
+		ElMessageBox.confirm(`此操作将发布模板:“${row.name}”,是否继续?`, '提示', {
+			confirmButtonText: '确认',
+			cancelButtonText: '取消',
+			type: 'warning',
+			draggable: true,
+			cancelButtonClass: 'default-button',
+			autofocus: false,
+		})
+			.then(() => {
+				publishOnList(row.id).then(() => {
+					ElMessage.success('发布成功');
+					getList(state.activeName);
+				});
+			})
+			.catch(() => {});
+	}
+};
+// 启用模板
+const tempEnable = (row: any) => {
+	ElMessageBox.confirm(`此操作将启用模板:“${row.name}”,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			workflowEnable(row.id).then(() => {
+				ElMessage.success('启用成功');
+				getList(state.activeName);
+			});
+		})
+		.catch(() => {});
+};
+// 禁用模板
+const tempDisable = (row: any) => {
+	ElMessageBox.confirm(`此操作将禁用模板:“${row.name}”,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			workflowDisable(row.id).then(() => {
+				ElMessage.success('禁用成功');
+				getList(state.activeName);
+			});
+		})
+		.catch(() => {});
+};
+// 跳转流程
+const onLink = (row: any) => {
+	jumpRef.value.openDialog(row);
+};
+// 终止流程
+const onStopProcess = (row: any) => {
+	ElMessageBox.confirm(`终止后,当前处理人将无法处理该流程,确定终止?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			workflowRerminate(row.id).then(() => {
+				ElMessage.success('禁用成功');
+				getList(state.activeName);
+			});
+		})
+		.catch(() => {});
+};
+//
+onMounted(() => {
+	getList(state.activeName);
+});
+onActivated(()=>{
+	mittBus.on('refreshList',()=>{
+		getList(state.activeName);
+	});
+})
+onUnmounted(() => {
+	mittBus.off('refreshList', () => {});
+});
+</script>
+<style lang="scss" scoped>
+.system-workflow-container {
+	:deep(.el-tabs__content) {
+		height: 100%;
+	}
+	.flex-column {
+		display: flex;
+		flex-direction: column;
+		height: calc(100% - 55px);
+		.el-table {
+			flex: 1;
+		}
+	}
+}
+</style>

+ 0 - 12
src/views/system/configureManage/dictionarie/component/data.d.ts

@@ -1,12 +0,0 @@
-// 定义接口来定义对象的类型
-export interface UserState {
-    isShowDialog: boolean;
-    ruleForm: {
-        dicTypeId: string; // 分类id
-        dicDataName: string; // 名称
-        dicDataValue: string; // 值
-        parentId: string; // 父级id
-    };
-    dictypeList: Array<any>;
-    parentData: Array<any>;
-}

+ 0 - 380
src/views/system/configureManage/workflowManage/index.vue

@@ -1,380 +0,0 @@
-<template>
-    <div class="system-workflow-container layout-padding">
-        <div class="layout-padding-auto layout-padding-view pd20">
-            <el-tabs v-model="activeName" @tab-change="handleClick" class="h100">
-                <el-tab-pane label="流程模板" name="template"></el-tab-pane>
-                <el-tab-pane label="流程实例" name="example"></el-tab-pane>
-                <div class="flex-column">
-                  <el-form :model="queryParams" ref="ruleFormRef" :inline="true" @submit.native.prevent class="mt15"
-                           v-show="activeName === 'example'">
-                    <el-form-item label="关键字查询" prop="Keyword">
-                      <el-input v-model="queryParams.Keyword" placeholder="流程标题/业务模块/流程ID" style="width:300px"
-                                clearable @keyup.enter="getList(activeName)" />
-                    </el-form-item>
-                    <el-form-item>
-                      <el-button type="primary" @click="getList(activeName)" :loading="loading" v-waves>
-                        <SvgIcon name="ele-Search" class="mr5" />查询
-                      </el-button>
-                      <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button">
-                        <SvgIcon name="ele-Refresh" class="mr5" />重置
-                      </el-button>
-                    </el-form-item>
-                  </el-form>
-                  <div class="flex-center-between mb20">
-                    <p class="table-title">信息列表</p>
-                    <div>
-                      <el-button type="primary" @click="onAddTemp" v-waves v-if="activeName === 'template'">
-                        <SvgIcon name="ele-Plus" class="mr5" />新增
-                      </el-button>
-                      <el-button type="primary" :disabled="!state.multipleSelection.length" v-waves
-                                 @click="onImportTable">
-                        <SvgIcon name="iconfont icon-daochu" class="mr5" />导出
-                      </el-button>
-                    </div>
-                  </div>
-                  <!-- 表格 -->
-                  <el-table :data="tableList" v-loading="loading" row-key="id" @selection-change="handleSelectionChange">
-                    <el-table-column type="selection" width="55" :reserve-selection="true" />
-                    <el-table-column type="index" width="60" label="序号" />
-                    <!-- 模板 -->
-                    <template v-if="activeName === 'template'">
-                      <el-table-column prop="moduleName" label="业务模块" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="name" label="模板名称" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="code" label="模板编码" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="creationTime" label="更新时间" show-overflow-tooltip>
-                        <template #default="scope">
-                          <span>{{ formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
-                        </template>
-                      </el-table-column>
-                      <el-table-column prop="statusText" label="状态" show-overflow-tooltip></el-table-column>
-                      <el-table-column label="操作" width="150" fixed="right" align="center">
-                        <!-- 草稿0 启用1 禁用2 -->
-                        <template #default="scope">
-                          <el-button text type="primary" @click="onEditTemp(scope.row)" title="修改">
-                            修改
-                            <!-- <SvgIcon name="ele-VideoPlay" size="var(--hotline-table-icon-font-size)" /> -->
-                          </el-button>
-                          <el-button text type="success" v-if="scope.row.status === 0"
-                                     @click="onReleaseTemp(scope.row)" title="发布">
-                            发布
-                            <!-- <SvgIcon name="ele-Download" size="var(--hotline-table-icon-font-size)" /> -->
-                          </el-button>
-                          <el-button text type="warning" v-if="scope.row.status === 2" @click="tempEnable(scope.row)"
-                                     title="启用">
-                            启用
-                            <!-- <SvgIcon name="ele-Connection" size="var(--hotline-table-icon-font-size)" /> -->
-                          </el-button>
-                          <el-button text type="danger" v-if="scope.row.status === 1" @click="tempDisable(scope.row)"
-                                     title="禁用">
-                            禁用
-                            <!-- <SvgIcon name="ele-Connection" size="var(--hotline-table-icon-font-size)" /> -->
-                          </el-button>
-                          <!-- 发布之后不能修改 -->
-                          <el-button text v-if="scope.row.status === 0" type="danger" @click="onDeleteTemp(scope.row)"
-                                     title="删除">
-                            删除
-                            <!-- <SvgIcon name="ele-Delete" size="var(--hotline-table-icon-font-size)" /> -->
-                          </el-button>
-                        </template>
-                      </el-table-column>
-                    </template>
-                    <!-- 实例 -->
-                    <template v-else-if="activeName === 'example'">
-                      <el-table-column prop="name" label="流程标题" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="id" label="流程ID" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="moudleName" label="业务模块" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="temName" label="流程模板" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="time" label="创建时间" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="huanjie" label="当前环节到达" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="huanjie1" label="当前环节" show-overflow-tooltip></el-table-column>
-                      <el-table-column prop="person" label="当前处理人" show-overflow-tooltip></el-table-column>
-                      <el-table-column label="操作" width="120" fixed="right" align="center">
-                        <template #default="scope">
-                          <el-button text type="primary" @click="onLink(scope.row)" title="跳转">
-                            跳转
-                            <!-- <SvgIcon name="ele-VideoPlay" size="var(--hotline-table-icon-font-size)" /> -->
-                          </el-button>
-                          <el-button text type="danger" @click="onStopProcess(scope.row)" title="终止流程">
-                            终止流程
-                            <!-- <SvgIcon name="ele-Download" size="var(--hotline-table-icon-font-size)" /> -->
-                          </el-button>
-                        </template>
-                      </el-table-column>
-                    </template>
-                    <template #empty>
-                      <Empty />
-                    </template>
-                  </el-table>
-                  <!-- 分页 -->
-                  <pagination :total="total" v-model:page="queryParams.PageIndex" v-model:limit="queryParams.PageSize"
-                              @pagination="getList(activeName)" />
-                </div>
-            </el-tabs>
-        </div>
-        <Jump ref="jumpRef" @updateList="getList(state.activeName)" />
-    </div>
-</template>
-
-<script lang="ts" setup name="workflowManage">
-import { ref, reactive, toRefs, onMounted, defineAsyncComponent, onBeforeUnmount } from 'vue';
-import { useRouter } from "vue-router";
-import type { FormInstance } from 'element-plus';
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { formatDate } from '/@/utils/formatTime';
-import table2excel from 'js-table2excel';
-import { storeToRefs } from 'pinia';
-import { useThemeConfig } from '/@/stores/themeConfig';
-import Cookies from 'js-cookie';
-// 引入节流
-import { throttle } from '/@/utils/tools';
-import { workflowList, workflowPaged, workflowDelete, publishOnList, workflowEnable, workflowDisable, workflowRerminate, WorkflowHasdefine } from '/@/api/system/workflowManage';
-
-// 引入组件
-const Jump = defineAsyncComponent(() => import('/@/views/system/configureManage/workflowManage/component/Jump.vue'));
-
-// 定义接口来定义对象的类型
-interface QueryState {
-    activeName: string;
-    queryParams: {
-        PageIndex: number;
-        PageSize: number;
-        Keyword: string;
-    };
-    tableList: Array<any>;
-    loading: boolean;
-    total: number;
-    multipleSelection: Array<any>;
-}
-
-// 定义变量内容
-const state = reactive(<QueryState>{
-    activeName: "template",
-    queryParams: {
-        PageIndex: 1,
-        PageSize: 10,
-        Keyword: ''
-    },
-    tableList: [],
-    loading: false,
-    total: 0,
-    multipleSelection: [],
-})
-const storesThemeConfig = useThemeConfig();
-const { themeConfig } = storeToRefs(storesThemeConfig);
-const { queryParams, tableList, loading, total, activeName } = toRefs(state);
-const ruleFormRef = ref<FormInstance>();
-const jumpRef = ref(null as any)
-const router = useRouter();
-/** 获取列表 */
-const getList = (val: string) => {
-    queryParams.value.PageIndex = 1;
-    state.loading = true;
-    switch (val) {
-        case 'template':
-            workflowList(queryParams.value).then((response: any) => {
-                state.tableList = response?.result.items ?? [];
-                state.total = response?.result.total;
-                setTimeout(() => {
-                    state.loading = false;
-                }, 300);
-            }).catch(() => {
-                state.loading = false;
-            });
-            break;
-        case 'example':
-            workflowPaged(queryParams.value).then((response: any) => {
-                state.tableList = response.result?.items ?? [];
-                state.total = response.result?.total ?? 0;
-                state.total = 1;
-                setTimeout(() => {
-                    state.loading = false;
-                }, 300);
-            }).catch(() => {
-                state.loading = false;
-            });
-            break;
-        default:
-            break;
-    }
-};
-// 多选表格
-const handleSelectionChange = (val: any) => {
-    state.multipleSelection = val;
-}
-/** 重置按钮操作 */
-const resetQuery = throttle((formEl: FormInstance | undefined) => {
-    if (!formEl) return;
-    formEl.resetFields();
-    getList(state.activeName);
-}, 1000);
-// 切换tab 查询列表
-const handleClick = (val: string) => {
-    getList(val);
-    Cookies.set('activeName', val);
-}
-// 导出表格
-const onImportTable = () => {
-    const tableHeader = [
-        { key: 'userName', colWidth: '', title: '用户名称', type: 'text', isCheck: true },
-        { key: 'fromNo', colWidth: '', title: '主叫号码', type: 'text', isCheck: true },
-        { key: 'toNo', colWidth: '', title: '被叫号码', type: 'text', isCheck: true },
-        { key: 'callTypeText', colWidth: '', title: '通话类型', type: 'text', isCheck: true },
-        { key: 'callStatusText', colWidth: '', title: '通话状态', type: 'text', isCheck: true },
-        { key: 'callDirectionText', colWidth: '', title: '呼叫方向', type: 'text', isCheck: true },
-        { key: 'endByText', colWidth: '', title: '通话结束方', type: 'text', isCheck: true },
-        { key: 'phoneIspText', colWidth: '', title: '运营商', type: 'text', isCheck: true },
-        { key: 'ringOffTypeText', colWidth: '', title: '挂断类型', type: 'text', isCheck: true },
-        { key: 'attribution', colWidth: '', title: '归属地', type: 'text', isCheck: true },
-        // { key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
-        // { key: 'image', colWidth: '', width: '70', height: '40', title: '图片描述', type: 'image', isCheck: true },
-    ]
-    table2excel(tableHeader, state.multipleSelection, `${themeConfig.value.globalTitle} ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
-}
-// 新增模板
-const onAddTemp = () => {
-    router.push(
-        {
-            path: "/system/configureManage/workflowManage/detail",
-            query: {
-                tagsViewName: '新增流程模板'
-            }
-        }
-    )
-}
-// 修改模板
-const onEditTemp = (row: any) => {
-    router.push(
-        {
-            path: "/system/configureManage/workflowManage/detail",
-            query: {
-                tagsViewName: '编辑流程模板',
-                id: row.id
-            }
-        }
-    )
-}
-// 删除模板
-const onDeleteTemp = (row: any) => {
-    ElMessageBox.confirm(`此操作将删除模板:“${row.name}”,是否继续?`, '提示', {
-        confirmButtonText: '确认',
-        cancelButtonText: '取消',
-        type: 'warning',
-        draggable: true,
-        cancelButtonClass: 'default-button',
-        autofocus: false
-    }).then(() => {
-        workflowDelete(row.id).then(() => {
-            ElMessage.success('删除成功');
-            getList(state.activeName);
-        });
-    }).catch(() => { });
-}
-// 发布模板
-const onReleaseTemp = async (row: any) => {
-    const response: any = await WorkflowHasdefine(row.moduleCode)
-    if (response.result) { //若已存在有效模板
-        ElMessageBox.confirm(`业务模块【${row.moduleName}】已有流程模板,确认覆盖当前版本?`, '提示', {
-            confirmButtonText: '确认',
-            cancelButtonText: '取消',
-            type: 'warning',
-            draggable: true,
-            cancelButtonClass: 'default-button',
-            autofocus: false
-        }).then(() => {
-            publishOnList(row.id).then(() => {
-                ElMessage.success('发布成功');
-                getList(state.activeName);
-            });
-        }).catch(() => { });
-    } else {
-        ElMessageBox.confirm(`此操作将发布模板:“${row.name}”,是否继续?`, '提示', {
-            confirmButtonText: '确认',
-            cancelButtonText: '取消',
-            type: 'warning',
-            draggable: true,
-            cancelButtonClass: 'default-button',
-            autofocus: false
-        }).then(() => {
-            publishOnList(row.id).then(() => {
-                ElMessage.success('发布成功');
-                getList(state.activeName);
-            });
-        }).catch(() => { });
-    }
-}
-// 启用模板
-const tempEnable = (row: any) => {
-    ElMessageBox.confirm(`此操作将启用模板:“${row.name}”,是否继续?`, '提示', {
-        confirmButtonText: '确认',
-        cancelButtonText: '取消',
-        type: 'warning',
-        draggable: true,
-        cancelButtonClass: 'default-button',
-        autofocus: false
-    }).then(() => {
-        workflowEnable(row.id).then(() => {
-            ElMessage.success('启用成功');
-            getList(state.activeName);
-        });
-    }).catch(() => { });
-}
-// 禁用模板
-const tempDisable = (row: any) => {
-    ElMessageBox.confirm(`此操作将禁用模板:“${row.name}”,是否继续?`, '提示', {
-        confirmButtonText: '确认',
-        cancelButtonText: '取消',
-        type: 'warning',
-        draggable: true,
-        cancelButtonClass: 'default-button',
-        autofocus: false
-    }).then(() => {
-        workflowDisable(row.id).then(() => {
-            ElMessage.success('禁用成功');
-            getList(state.activeName);
-        });
-    }).catch(() => { });
-}
-// 跳转流程
-const onLink = (row: any) => {
-    jumpRef.value.openDialog(row);
-}
-// 终止流程
-const onStopProcess = (row: any) => {
-    ElMessageBox.confirm(`终止后,当前处理人将无法处理该流程,确定终止?`, '提示', {
-        confirmButtonText: '确认',
-        cancelButtonText: '取消',
-        type: 'warning',
-        draggable: true,
-        cancelButtonClass: 'default-button',
-        autofocus: false
-    }).then(() => {
-        workflowRerminate(row.id).then(() => {
-            ElMessage.success('禁用成功');
-            getList(state.activeName);
-        });
-    }).catch(() => { });
-}
-// 
-onMounted(() => {
-    state.activeName = Cookies.get('activeName') ?? 'template';
-    getList(state.activeName);
-});
-onBeforeUnmount(() => {
-    Cookies.remove('activeName');
-})
-</script>
-<style lang="scss" scoped>
-.system-workflow-container {
-  :deep(.el-tabs__content){
-    height: 100%;
-  }
-  .flex-column{
-    display: flex;
-    flex-direction: column;
-    height: calc(100% - 55px);
-    .el-table {
-      flex: 1;
-    }
-  }
-}
-</style>

+ 125 - 0
src/views/system/dataAuth/component/AddAuth.vue

@@ -0,0 +1,125 @@
+<template>
+	<div class="system-add-user-container">
+		<el-dialog v-model="state.isShowDialog" width="700px" draggable title="新增数据权限" ref="dialogRef">
+			<el-form :model="state.ruleForm" label-width="90px" ref="ruleFormRef">
+				<el-row :gutter="10">
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="数据表" prop="tableId" :rules="[{ required: true, message: '请选择数据表', trigger: 'change' }]">
+                            <el-select v-model="state.ruleForm.tableId" placeholder="请选择数据表" class="w100">
+								<el-option v-for="item in state.tableData" :key="item.id" :label="item.displayName" :value="item.id" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="权限方式" prop="authorityType" :rules="[{ required: true, message: '请选择权限方式', trigger: 'change' }]">
+							<el-select v-model="state.ruleForm.authorityType" placeholder="请选择权限方式" class="w100">
+								<el-option v-for="item in state.options" :key="item.value" :label="item.label" :value="item.value" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="onCancel" class="default-button">取 消</el-button>
+					<el-button type="primary" @click="onSubmit()" :loading="state.loading">确 定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script setup lang="ts" name="systemAddDataAuth">
+import { reactive, ref, onMounted } from 'vue';
+import { ElMessage } from 'element-plus';
+import { useRoute } from 'vue-router';
+import { throttle } from '/@/utils/tools';
+
+import { dataAuthList, addDataAuth } from '/@/api/system/roles';
+
+// 定义子组件向父组件传值/事件
+const emit = defineEmits(['updateList']);
+// 定义变量内容
+const state = reactive<any>({
+	isShowDialog: false,
+	ruleForm: {
+		roleId: '', // 手机号
+		roleCode: 0, //性别
+		authorityType: '',
+		tableId: '',
+	},
+	tableData: [],
+	loading: false,
+	options: [
+		{
+			label: '全部可见',
+			value: 0,
+		},
+		{
+			label: '本部',
+			value: 1,
+		},
+		{
+			label: '本部及以下',
+			value: 2,
+		},
+		{
+			label: '创建人',
+			value: 3,
+		},
+	], //可用组织
+});
+const route = useRoute();
+// 打开弹窗
+const ruleFormRef = ref();
+const openDialog = async () => {
+	ruleFormRef.value?.clearValidate();
+	ruleFormRef.value?.resetFields();
+	const res: any = await dataAuthList();
+	state.tableData = res.result ?? [];
+	state.isShowDialog = true;
+};
+// 关闭弹窗
+const closeDialog = () => {
+	state.isShowDialog = false;
+};
+// 取消
+const onCancel = () => {
+	closeDialog();
+};
+// 新增
+const onSubmit = throttle(() => {
+	ruleFormRef.value.validate((valid: boolean) => {
+		if (valid) {
+			state.loading = true;
+			addDataAuth(state.ruleForm)
+				.then(() => {
+					ElMessage({
+						message: '新增成功',
+						type: 'success',
+					});
+					state.loading = false;
+					closeDialog();
+					emit('updateList');
+				})
+				.catch(() => {
+					// 新增失败
+					state.loading = false;
+					closeDialog();
+				});
+		} else {
+			return false;
+		}
+	});
+}, 1000);
+onMounted(() => {
+	state.ruleForm.roleId = route.query.id;
+	state.ruleForm.roleCode = route.query.code;
+});
+// 暴露变量
+defineExpose({
+	openDialog,
+	closeDialog,
+});
+</script>
+<style lang="scss" scoped></style>

+ 124 - 0
src/views/system/dataAuth/component/EditAuth.vue

@@ -0,0 +1,124 @@
+<template>
+	<div class="system-add-user-container">
+		<el-dialog v-model="state.isShowDialog" width="700px" draggable title="修改数据权限" ref="dialogRef">
+			<el-form :model="state.ruleForm" label-width="90px" ref="ruleFormRef">
+				<el-row :gutter="10">
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="数据表" prop="tableId" :rules="[{ required: true, message: '请选择数据表', trigger: 'change' }]">
+							<el-select v-model="state.ruleForm.tableId" placeholder="请选择数据表" class="w100">
+								<el-option v-for="item in state.tableData" :key="item.id" :label="item.displayName" :value="item.id" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="权限方式" prop="authorityType" :rules="[{ required: true, message: '请选择权限方式', trigger: 'change' }]">
+							<el-select v-model="state.ruleForm.authorityType" placeholder="请选择权限方式" class="w100">
+								<el-option v-for="item in state.options" :key="item.value" :label="item.label" :value="item.value" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="onCancel" class="default-button">取 消</el-button>
+					<el-button type="primary" @click="onSubmit()" :loading="state.loading">确 定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script setup lang="ts" name="systemEditDataAuth">
+import { reactive, ref, onMounted } from 'vue';
+import { ElMessage } from 'element-plus';
+import { useRoute } from 'vue-router';
+import { throttle } from '/@/utils/tools';
+
+import { dataAuthList, editDataAuth } from '/@/api/system/roles';
+
+// 定义子组件向父组件传值/事件
+const emit = defineEmits(['updateList']);
+// 定义变量内容
+const state = reactive<any>({
+	isShowDialog: false,
+	ruleForm: {
+		roleId: '', // 手机号
+		roleCode: 0, //性别
+		authorityType: '',
+		tableId: '',
+	},
+	tableData: [],
+	loading: false,
+	options: [
+		{
+			label: '全部可见',
+			value: 0,
+		},
+		{
+			label: '本部',
+			value: 1,
+		},
+		{
+			label: '本部及以下',
+			value: 2,
+		},
+		{
+			label: '创建人',
+			value: 3,
+		},
+	], //可用组织
+});
+const route = useRoute();
+// 打开弹窗
+const ruleFormRef = ref();
+const openDialog = async (row: any) => {
+	state.ruleForm = row;
+	const res: any = await dataAuthList();
+	state.tableData = res.result ?? [];
+	state.isShowDialog = true;
+};
+// 关闭弹窗
+const closeDialog = () => {
+	state.isShowDialog = false;
+};
+// 取消
+const onCancel = () => {
+	closeDialog();
+};
+// 新增
+const onSubmit = throttle(() => {
+	ruleFormRef.value.validate((valid: boolean) => {
+		if (valid) {
+			state.loading = true;
+			editDataAuth(state.ruleForm)
+				.then(() => {
+					ElMessage({
+						message: '新增成功',
+						type: 'success',
+					});
+					state.loading = false;
+					closeDialog();
+					emit('updateList');
+				})
+				.catch(() => {
+					// 新增失败
+					state.loading = false;
+					closeDialog();
+				});
+		} else {
+			return false;
+		}
+	});
+}, 1000);
+onMounted(() => {
+	state.ruleForm.roleId = route.query.id;
+	state.ruleForm.roleCode = route.query.code;
+});
+// 暴露变量
+defineExpose({
+	openDialog,
+	closeDialog,
+});
+</script>
+<style lang="scss" scoped></style>

+ 180 - 0
src/views/system/dataAuth/index.vue

@@ -0,0 +1,180 @@
+<template>
+	<div class="system-dataAuth-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<!-- 正常 -->
+			<template v-if="state.queryParams.roleid">
+				<div class="flex-center-between mb20">
+					<p class="table-title">信息列表</p>
+					<div>
+						<el-button type="primary" @click="onAddAuth" v-waves> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
+						<el-button type="primary" v-waves @click="onImportTable" :disabled="!state.multipleSelection.length">
+							<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
+						</el-button>
+					</div>
+				</div>
+				<el-table :data="state.tableData" v-loading="state.loading" row-key="id" @selection-change="handleSelectionChange">
+					<el-table-column type="selection" width="55" :reserve-selection="true" />
+					<el-table-column type="index" width="60" label="序号" />
+					<el-table-column prop="role.displayName" label="角色名称" show-overflow-tooltip></el-table-column>
+					<el-table-column prop="role.name" label="角色编码" show-overflow-tooltip></el-table-column>
+					<el-table-column prop="role.description" label="角色说明" show-overflow-tooltip width="400"></el-table-column>
+					<el-table-column prop="table.displayName" label="数据表" show-overflow-tooltip width="100"> </el-table-column>
+					<el-table-column prop="authorityType" label="权限方式" show-overflow-tooltip width="100">
+						<template #default="scope">
+							{{ state.options[scope.row.authorityType].label }}
+						</template>
+					</el-table-column>
+					<el-table-column label="操作" width="130" fixed="right" align="center">
+						<template #default="scope">
+							<el-button text type="primary" @click="onEditAuth(scope.row)" v-auth="'100203'" title="修改">
+								<SvgIcon name="ele-Edit" size="var(--hotline-table-icon-font-size)" />
+							</el-button>
+							<el-button text type="danger" @click="onRowDel(scope.row)" v-auth="'100202'" title="删除">
+								<SvgIcon name="ele-Delete" size="var(--hotline-table-icon-font-size)" />
+							</el-button>
+						</template>
+					</el-table-column>
+					<template #empty>
+						<Empty />
+					</template>
+				</el-table>
+			</template>
+			<template v-else>
+				<Empty description="参数不正确,请关闭重新打开页面" />
+			</template>
+		</div>
+
+		<AddAuth ref="addAuthRef" @updateList="handleQuery" />
+		<EditAuth ref="editAuthRef" @updateList="handleQuery" />
+	</div>
+</template>
+
+<script lang="ts" setup name="systemDataAuth">
+import { defineAsyncComponent, ref, reactive, onMounted } from 'vue';
+import { ElMessageBox, ElMessage } from 'element-plus';
+import { useRoute } from 'vue-router';
+import table2excel from 'js-table2excel';
+import { formatDate } from '/@/utils/formatTime';
+import { throttle } from '/@/utils/tools';
+import { getdataauthoritybyrole, deleteDataAuth } from '/@/api/system/roles';
+
+// 引入组件
+const AddAuth = defineAsyncComponent(() => import('/@/views/system/dataAuth/component/AddAuth.vue'));
+const EditAuth = defineAsyncComponent(() => import('/@/views/system/dataAuth/component/EditAuth.vue'));
+
+// 定义接口来定义对象的类型
+interface QueryState {
+	queryParams: {
+		roleid: string | any[];
+	};
+	tableData: Array<any>;
+	loading: boolean;
+	multipleSelection: Array<any>;
+	options: Array<any>;
+}
+
+// 定义变量内容
+const state = reactive<QueryState>({
+	queryParams: {
+		roleid: '',
+	},
+	tableData: [],
+	loading: false,
+	multipleSelection: [],
+	options: [
+		{
+			label: '全部可见',
+			value: 0,
+		},
+		{
+			label: '本部',
+			value: 1,
+		},
+		{
+			label: '本部及以下',
+			value: 2,
+		},
+		{
+			label: '创建人',
+			value: 3,
+		},
+	], //可用组织
+});
+const addAuthRef = ref(); //新增数据权限
+const editAuthRef = ref(); //修改数据权限
+const route = useRoute();
+/** 搜索按钮操作 节流操作 */
+const handleQuery = throttle(() => {
+	getList();
+}, 1000);
+/** 获取用户列表 */
+const getList = () => {
+	state.loading = true;
+	getdataauthoritybyrole(state.queryParams)
+		.then((response: any) => {
+			state.tableData = response?.result ?? [];
+			state.loading = false;
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
+
+// 新增数据权限
+const onAddAuth = () => {
+	addAuthRef.value.openDialog();
+};
+// 表格多选
+const handleSelectionChange = (val: any) => {
+	state.multipleSelection = val;
+};
+
+// 打开修改数据权限弹窗
+const onEditAuth = (row: any) => {
+	editAuthRef.value.openDialog(row);
+};
+// 删除数据权限
+const onRowDel = (row: any) => {
+	ElMessageBox.confirm(`确定要删除本条数据,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		type: 'warning',
+	})
+		.then(() => {
+			deleteDataAuth(row.id).then(() => {
+				ElMessage.success('删除成功');
+				handleQuery();
+			});
+		})
+		.catch(() => {});
+};
+// 导出表格
+const onImportTable = () => {
+	const tabeHeader = [
+		{ key: 'name', colWidth: '', title: '姓名', type: 'text', isCheck: true },
+		{ key: 'userName', colWidth: '', title: '账号', type: 'text', isCheck: true },
+		{ key: 'orgName', colWidth: '', title: '所属部门', type: 'text', isCheck: true },
+		{ key: 'roles', colWidth: '', title: '角色', type: 'text', isCheck: true },
+		{ key: 'phoneNo', colWidth: '', title: '电话号码', type: 'text', isCheck: true },
+		{ key: 'staffNo', colWidth: '', title: '工号', type: 'text', isCheck: true },
+		{ key: 'defaultTelNo', colWidth: '', title: '默认分机', type: 'text', isCheck: true },
+		{ key: 'creationTime', colWidth: '', title: '更新时间', type: 'text', isCheck: true },
+	];
+	table2excel(tabeHeader, state.multipleSelection, `用户信息 ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
+};
+onMounted(() => {
+	if (route.query.id) {
+		state.queryParams.roleid = route.query.id;
+		getList();
+	}
+});
+</script>
+<style lang="scss" scoped>
+.system-dataAuth-container {
+	.el-table {
+		flex: 1;
+	}
+}
+</style>

+ 1 - 1
src/views/system/menu/component/addMenu.vue

@@ -75,7 +75,7 @@
               <template #label>
                 <p class="flex-center-align">入口图片
                   <el-tooltip content="首页快捷入口图标" placement="top-start" trigger="click">
-                    <svgIcon name="ele-QuestionFilled" class="cursor-help"></svgIcon>
+                    <SvgIcon name="ele-QuestionFilled" class="cursor-help"></SvgIcon>
                   </el-tooltip>
                 </p>
               </template>

+ 1 - 1
src/views/system/menu/component/editMenu.vue

@@ -75,7 +75,7 @@
               <template #label>
                 <p class="flex-center-align">入口图片
                   <el-tooltip content="首页快捷入口图标" placement="top-start" trigger="click">
-                    <svgIcon name="ele-QuestionFilled" class="cursor-help"></svgIcon>
+                    <SvgIcon name="ele-QuestionFilled" class="cursor-help"></SvgIcon>
                   </el-tooltip>
                 </p>
               </template>

+ 201 - 46
src/views/system/menu/index.vue

@@ -4,17 +4,36 @@
 			<div class="flex-center-between mb20">
 				<p class="table-title">信息列表</p>
 				<div>
-					<el-button type="primary" @click="changeOpen" v-waves> {{ state.isExpansion ? '全部收起' : '全部展开' }}
-					</el-button>
-					<el-button type="primary" @click="onOpenAddMenu" v-waves v-auth="'100401'">
-						<SvgIcon name="ele-Plus" class="mr5" />新增
-					</el-button>
+					<el-button type="primary" @click="onOpenAddMenu" v-waves v-auth="'100401'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
 				</div>
 			</div>
-			<el-table :data="menuTableData" v-loading="loading" row-key="id" ref="tableRef"
-				:default-expand-all="state.isExpansion"
-				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
-				<!--  索引表头重写-->
+			<!-- 表格 -->
+			<el-auto-resizer class="table">
+				<template #default="{ height, width }">
+					<el-table-v2
+						v-model:expanded-row-keys="expandedRowKeys"
+						:columns="state.columns"
+						:data="state.menuTableData"
+						expand-column-key="pageName"
+						fixed
+						:width="width"
+						:height="height"
+					>
+						<template #overlay v-if="state.loading">
+							<div class="el-loading-mask" style="display: flex; align-items: center; justify-content: center">
+								<SvgIcon name="ele-Loading" class="is-loading" size="28px" color="var(--el-color-primary)"></SvgIcon>
+							</div>
+						</template>
+					</el-table-v2>
+				</template>
+			</el-auto-resizer>
+			<!-- <el-table
+				:data="state.menuTableData"
+				v-loading="state.loading"
+				row-key="id"
+				ref="tableRef"
+				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+			>
 				<el-table-column label="菜单名称" show-overflow-tooltip width="200">
 					<template #default="scope">
 						<SvgIcon :name="scope.row.icon" />
@@ -80,7 +99,7 @@
 				<template #empty>
 					<Empty />
 				</template>
-			</el-table>
+			</el-table> -->
 		</div>
 
 		<AddMenu ref="addMenuRef" @updateList="getMenuListApi" />
@@ -89,25 +108,171 @@
 </template>
 
 <script lang="ts" setup name="systemmenu">
-import { defineAsyncComponent, ref, toRefs, reactive, onMounted } from 'vue';
+import { defineAsyncComponent, ref, h, reactive, onMounted } from 'vue';
 import { RouteRecordRaw } from 'vue-router';
-import { ElMessageBox, ElMessage } from 'element-plus';
-import { getMenuList, removeMenu } from "/@/api/system/menu";
+import { ElMessageBox, ElMessage, ElButton, ElTag } from 'element-plus';
+import { storeToRefs } from 'pinia';
+import { useUserInfo } from '/@/stores/userInfo';
+import { getMenuList, removeMenu } from '/@/api/system/menu';
+import SvgIcon from '/@/components/SvgIcon/index.vue';
 
 // 引入组件
-const AddMenu = defineAsyncComponent(() => import('/@/views/system/menu/component/addMenu.vue'))
-const EditMenu = defineAsyncComponent(() => import('/@/views/system/menu/component/editMenu.vue'))
+const AddMenu = defineAsyncComponent(() => import('/@/views/system/menu/component/addMenu.vue'));
+const EditMenu = defineAsyncComponent(() => import('/@/views/system/menu/component/editMenu.vue'));
 
 // 定义变量内容
+const storesUserInfo = useUserInfo();
+const { userInfos } = storeToRefs(storesUserInfo);
 const addMenuRef = ref();
 const editMenuRef = ref();
-const tableRef = ref();
 const state = reactive({
 	menuTableData: <any>[], // 获取所有菜单
 	loading: false,
-	isExpansion: false
+	columns: [
+		{
+			key: 'pageName',
+			dataKey: 'pageName',
+			title: '菜单名称',
+			width: 300,
+			cellRenderer: (data: any) => {
+				return h('p', { style: { justifyContent: 'flex-end' } }, [
+					h(SvgIcon, { name: data.rowData.icon }, ''),
+					h('span', { class: 'pl5' }, { default: () => data.rowData.pageName }),
+				]);
+			},
+		},
+		{
+			key: 'path',
+			dataKey: 'path',
+			title: '路由路径',
+			width: 400,
+		},
+		{
+			key: 'component',
+			dataKey: 'component',
+			title: '组件路径',
+			width: 400,
+		},
+		{
+			key: 'permissionCode',
+			dataKey: 'permissionCode',
+			title: '权限编码',
+			width: 100,
+		},
+		{
+			key: 'isFast',
+			dataKey: 'isFast',
+			title: '快捷入口',
+			width: 100,
+			cellRenderer: (data: any) => {
+				return h(ElTag, { type: data.rowData.isFast ? 'success' : 'info' }, { default: () => (data.rowData.isFast ? '是' : '否') });
+			},
+		},
+		{
+			key: 'isHide',
+			dataKey: 'isHide',
+			title: '是否隐藏',
+			width: 100,
+			cellRenderer: (data: any) => {
+				return h(ElTag, { type: data.rowData.isHide ? 'success' : 'info' }, { default: () => (data.rowData.isHide ? '是' : '否') });
+			},
+		},
+		{
+			key: 'isKeepAlive',
+			dataKey: 'isKeepAlive',
+			title: '是否缓存',
+			width: 100,
+			cellRenderer: (data: any) => {
+				return h(ElTag, { type: data.rowData.isKeepAlive ? 'success' : 'info' }, { default: () => (data.rowData.isKeepAlive ? '是' : '否') });
+			},
+		},
+		{
+			key: 'isAffix',
+			dataKey: 'isAffix',
+			title: '是否固定',
+			width: 100,
+			cellRenderer: (data: any) => {
+				return h(ElTag, { type: data.rowData.isAffix ? 'success' : 'info' }, { default: () => (data.rowData.isAffix ? '是' : '否') });
+			},
+		},
+		{
+			key: 'isLink',
+			dataKey: 'isLink',
+			title: '是否外链',
+			width: 100,
+			cellRenderer: (data: any) => {
+				return h(ElTag, { type: data.rowData.isLink ? 'success' : 'info' }, { default: () => (data.rowData.isLink ? '是' : '否') });
+			},
+		},
+		{
+			key: 'displayOrder',
+			dataKey: 'displayOrder',
+			title: '排序',
+			width: 80,
+		},
+		{
+			key: 'handle',
+			title: '操作',
+			width: 100,
+			fixed: 'right',
+			align: 'center',
+			cellRenderer: (data: any) => {
+				if (userInfos.value.authBtnList.includes('100402') && userInfos.value.authBtnList.includes('100403')) {
+					// 权限判断
+					return h('span', { class: 'flex' }, [
+						h(
+							ElButton,
+							{
+								onClick: () => onOpenEditMenu(data.rowData),
+								type: 'primary',
+								icon: h(SvgIcon, { name: 'ele-Edit', size: '16px' }, {}),
+								link: true,
+								title: '修改',
+							},
+							{ default: () => '' }
+						),
+						h(
+							ElButton,
+							{
+								onClick: () => onTabelRowDel(data.rowData),
+								type: 'danger',
+								icon: h(SvgIcon, { name: 'ele-Delete', size: '16px' }, {}),
+								link: true,
+								title: '删除',
+							},
+							{ default: () => '' }
+						),
+					]);
+				} else if (userInfos.value.authBtnList.includes('100402')) {
+					return h(
+						ElButton,
+						{
+							onClick: () => onOpenEditMenu(data.rowData),
+							type: 'primary',
+							icon: h(SvgIcon, { name: 'ele-Edit', size: '16px' }, {}),
+							link: true,
+							title: '修改',
+						},
+						{ default: () => '' }
+					);
+				} else if (userInfos.value.authBtnList.includes('100403')) {
+					h(
+						ElButton,
+						{
+							onClick: () => onTabelRowDel(data.rowData),
+							type: 'danger',
+							icon: h(SvgIcon, { name: 'ele-Delete', size: '16px' }, {}),
+							link: true,
+							title: '删除',
+						},
+						{ default: () => '' }
+					);
+				}
+			},
+		},
+	],
 });
-const { menuTableData, loading } = toRefs(state);
+const expandedRowKeys = ref<string[]>([]);
 // 打开新增菜单弹窗
 const onOpenAddMenu = () => {
 	addMenuRef.value.openDialog();
@@ -123,46 +288,36 @@ const onTabelRowDel = (row: any) => {
 		cancelButtonText: '取消',
 		type: 'warning',
 		draggable: true,
-		cancelButtonClass: 'default-button'
-	}).then(() => {
-		removeMenu(row.id).then(() => {
-			ElMessage.success('删除成功');
-			getMenuListApi();
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			removeMenu(row.id).then(() => {
+				ElMessage.success('删除成功');
+				getMenuListApi();
+			});
 		})
-	}).catch(() => { });
+		.catch(() => {});
 };
 // 获取所有菜单
 const getMenuListApi = () => {
 	state.loading = true;
-	getMenuList().then((res: any) => {
-		state.menuTableData = res?.result ?? [];
-		state.loading = false;
-	}).catch(() => {
-		state.loading = false;
-	});
-}
-// 切换展开和收起
-const changeOpen = () => {
-	state.isExpansion = !state.isExpansion;
-	toggleRowExpansionAll(state.menuTableData, state.isExpansion);
-}
-const toggleRowExpansionAll = (data: Array<any>, isExpansion: boolean) => {
-	data.forEach((item: any) => {
-		tableRef.value.toggleRowExpansion(item, isExpansion);
-		if (item.children !== undefined && item.children !== null) {
-			toggleRowExpansionAll(item.children, isExpansion);
-		}
-	});
-}
+	getMenuList()
+		.then((res: any) => {
+			state.menuTableData = res?.result ?? [];
+			state.loading = false;
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
 // 页面加载时
 onMounted(() => {
 	getMenuListApi();
 });
-
 </script>
 <style lang="scss" scoped>
 .system-menu-container {
-	.el-table {
+	.table {
 		flex: 1;
 	}
 }

+ 89 - 42
src/views/system/organizational/index.vue

@@ -4,18 +4,18 @@
 			<div class="flex-center-between mb20">
 				<p class="table-title">信息列表</p>
 				<div>
-					<el-button type="primary" @click="changeOpen" v-waves>
-						{{ state.isExpansion ? '全部收起' : '全部展开' }}
-					</el-button>
-					<el-button type="primary" @click="onOpenAddOrg" v-waves v-auth="'100501'">
-						<SvgIcon name="ele-Plus" class="mr5" />新增
-					</el-button>
+					<el-button type="primary" @click="onOpenAddOrg" v-waves v-auth="'100501'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
 				</div>
 			</div>
 			<!-- 表格 -->
-			<el-table :data="orgTableData" v-loading="loading" ref="tableRef" row-key="id"
+			<!-- <el-table
+				:data="orgTableData"
+				v-loading="loading"
+				ref="tableRef"
+				row-key="id"
 				:default-expand-all="state.isExpansion"
-				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
+				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+			>
 				<el-table-column label="部门名称" show-overflow-tooltip>
 					<template #default="scope">
 						<SvgIcon :name="scope.row.icon" />
@@ -45,39 +45,99 @@
 				<template #empty>
 					<Empty />
 				</template>
-			</el-table>
+			</el-table> -->
+
+			<!-- 表格 -->
+			<el-auto-resizer class="table">
+				<template #default="{ height, width }">
+					<el-table-v2
+						v-model:expanded-row-keys="expandedRowKeys"
+						:columns="state.columns"
+						:data="state.orgTableData"
+						expand-column-key="orgName"
+						fixed
+						:width="width"
+						:height="height"
+					>
+						<template #overlay v-if="state.loading">
+							<div class="el-loading-mask" style="display: flex; align-items: center; justify-content: center">
+								<SvgIcon name="ele-Loading" class="is-loading" size="28px" color="var(--el-color-primary)"></SvgIcon>
+							</div>
+						</template>
+					</el-table-v2>
+				</template>
+			</el-auto-resizer>
 		</div>
 		<AddOrg ref="addOrgRef" @updateList="getOrgListApi" />
 		<EditOrg ref="editOrgRef" @updateList="getOrgListApi" />
 	</div>
 </template>
 <script lang="ts" setup name="organizational">
-import { defineAsyncComponent, ref, toRefs, reactive, onMounted } from 'vue';
-import { RouteRecordRaw } from 'vue-router';
-import { getOrgList } from "/@/api/system/organizational";
+import { defineAsyncComponent, ref, h, reactive, onMounted } from 'vue';
+import { ElButton } from 'element-plus';
+import { getOrgList } from '/@/api/system/organizational';
 import { formatDate } from '/@/utils/formatTime';
+import SvgIcon from '/@/components/SvgIcon/index.vue';
 
 // 引入组件
-const AddOrg = defineAsyncComponent(() => import('/@/views/system/organizational/component/addOrg.vue'))
-const EditOrg = defineAsyncComponent(() => import('/@/views/system/organizational/component/editOrg.vue'))
+const AddOrg = defineAsyncComponent(() => import('/@/views/system/organizational/component/addOrg.vue'));
+const EditOrg = defineAsyncComponent(() => import('/@/views/system/organizational/component/editOrg.vue'));
 
 // 定义变量内容
 const addOrgRef = ref();
 const editOrgRef = ref();
-const tableRef = ref();
 const state = reactive({
 	orgTableData: <any>[], // 获取所有菜单
 	loading: false,
-	isExpansion: false
+	columns: [
+		{
+			key: 'orgName',
+			dataKey: 'orgName', //需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填name
+			title: '部门名称',
+			width: 400,
+		},
+		{
+			key: 'parentName',
+			dataKey: 'parentName', //需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填name
+			title: '上级部门',
+			width: 400,
+		},
+		{
+			key: 'orgCode',
+			dataKey: 'orgCode', //需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填name
+			title: '部门编码',
+			width: 200,
+		},
+		{
+			key: 'creationTime',
+			dataKey: 'creationTime',
+			title: '更新时间',
+			width: 200,
+			cellRenderer: (data: any) => h('span', {}, { default: () => formatDate(new Date(data.rowData.creationTime), 'YYYY-mm-dd HH-MM') }),
+		},
+		{
+			key: 'handle',
+			title: '操作',
+			width: 80,
+			fixed: 'right',
+			align: 'center',
+			cellRenderer: (data: any) =>
+				h(
+					ElButton,
+					{ onClick: () => onOpenEditOrg(data), type: 'primary',title:'修改', icon: h(SvgIcon, { name: 'ele-Edit', size: '16px' }, {}), link: true },
+					{ default: () => '修改' }
+				),
+		},
+	],
 });
-const { orgTableData, loading } = toRefs(state);
+const expandedRowKeys = ref<string[]>([]);
 // 打开新增菜单弹窗
 const onOpenAddOrg = () => {
 	addOrgRef.value.openDialog();
 };
 // 打开编辑菜单弹窗
-const onOpenEditOrg = (row: RouteRecordRaw) => {
-	editOrgRef.value.openDialog(row);
+const onOpenEditOrg = (row: any) => {
+	editOrgRef.value.openDialog(row.rowData);
 };
 // 删除当前行
 // const onTabelRowDel = (row: any) => {
@@ -95,37 +155,24 @@ const onOpenEditOrg = (row: RouteRecordRaw) => {
 // 获取所有部门结构
 const getOrgListApi = () => {
 	state.loading = true;
-	getOrgList().then((res: any) => {
-		state.orgTableData = res?.result ?? [];
-		state.loading = false;
-	}).catch(() => {
-		state.loading = false;
-	});
-}
-// 切换展开和收起
-const changeOpen = () => {
-	state.isExpansion = !state.isExpansion;
-	toggleRowExpansionAll(state.orgTableData, state.isExpansion);
-}
-const toggleRowExpansionAll = (data: Array<any>, isExpansion: boolean) => {
-	data.forEach((item: any) => {
-		tableRef.value.toggleRowExpansion(item, isExpansion);
-		if (item.children !== undefined && item.children !== null) {
-			toggleRowExpansionAll(item.children, isExpansion);
-		}
-	});
-}
+	getOrgList()
+		.then((res: any) => {
+			state.orgTableData = res?.result ?? [];
+			state.loading = false;
+		})
+		.catch(() => {
+			state.loading = false;
+		});
+};
 // 页面加载时
 onMounted(() => {
 	getOrgListApi();
 });
-
 </script>
 <style lang="scss" scoped>
 .system-organizational-container {
-	.el-table {
+	.table {
 		flex: 1;
 	}
 }
 </style>
-

+ 18 - 4
src/views/system/roles/index.vue

@@ -39,7 +39,7 @@
 					</template>
 				</el-table-column>
 				<el-table-column prop="state" label="状态" show-overflow-tooltip width="80"> </el-table-column>
-				<el-table-column label="操作" width="100" fixed="right" align="center">
+				<el-table-column label="操作" width="130" fixed="right" align="center">
 					<template #default="scope">
 						<el-button text type="primary" @click="onOpenEditRole(scope.row)" v-auth="'100203'" title="修改">
 							<SvgIcon name="ele-Edit" size="var(--hotline-table-icon-font-size)" />
@@ -47,6 +47,9 @@
 						<el-button text type="success" @click="onPermissions(scope.row)" v-auth="'100204'" title="配置权限">
 							<SvgIcon name="iconfont icon-quanxian" size="var(--hotline-table-icon-font-size)" />
 						</el-button>
+						<el-button text type="info" @click="onDataAuth(scope.row)" v-auth="'100204'" title="数据权限">
+							<SvgIcon name="ele-MessageBox" size="var(--hotline-table-icon-font-size)" />
+						</el-button>
 						<el-button text type="danger" @click="onRowDel(scope.row)" v-auth="'100202'" title="删除">
 							<SvgIcon name="ele-Delete" size="var(--hotline-table-icon-font-size)" />
 						</el-button>
@@ -70,6 +73,7 @@
 import { defineAsyncComponent, toRefs, reactive, onMounted, ref } from 'vue';
 import { ElMessageBox, ElMessage } from 'element-plus';
 import type { FormInstance } from 'element-plus';
+import { useRouter } from 'vue-router';
 import { throttle } from '/@/utils/tools';
 import { formatDate } from '/@/utils/formatTime';
 import { getRoleListPaged, delRole } from '/@/api/system/roles';
@@ -133,6 +137,7 @@ const data = reactive<QueryState>({
 });
 const { queryParams } = toRefs(data);
 const { tableData, loading } = toRefs(state);
+const router = useRouter();
 /** 搜索按钮操作 节流操作 */
 const handleQuery = throttle(() => {
 	data.queryParams.PageIndex = 1;
@@ -151,9 +156,7 @@ const getList = () => {
 		.then((response: any) => {
 			state.tableData.data = response?.result.items ?? [];
 			state.tableData.total = response?.result.total ?? 0;
-			setTimeout(() => {
-				state.loading = false;
-			}, 300);
+			state.loading = false;
 		})
 		.catch(() => {
 			state.loading = false;
@@ -175,6 +178,17 @@ const onPermissions = (row: Object) => {
 const showUserList = (row: Object) => {
 	UserListRef.value.openDialog(row);
 };
+// 打开数据权限
+const onDataAuth = (row: any) => {
+	router.push({
+		path:'/system/roles/dataAuth',
+		query:{
+			id:row.id,
+			code:row.name,
+			tagsViewName:'数据权限 '+row.displayName
+		}
+	})
+}
 // 表格多选
 const handleSelectionChange = (val: any) => {
 	state.multipleSelection = val;

+ 2 - 4
src/views/system/systemParameter/index.vue

@@ -222,9 +222,7 @@ const getSetList = () => {
 					}
 				}
 			}
-			setTimeout(() => {
-				loading.value = false;
-			}, 300);
+			loading.value = false;
 		})
 		.catch(() => {
 			loading.value = false;
@@ -291,7 +289,7 @@ const uploadImgList = (file, list, id) => {
 	fileList.value = list;
 };
 // 删除图片(多张)
-const handleRemove = (uploadFile:any) => {
+const handleRemove = (uploadFile: any) => {
 	uploadListRef.value[0].handleRemove(uploadFile.file);
 };
 // 预览图片 多张

+ 1 - 1
src/views/system/user/component/addUser.vue

@@ -88,7 +88,7 @@ import { reactive, ref } from 'vue';
 import { ElMessage } from 'element-plus';
 import { throttle } from '/@/utils/tools';
 import { addUser, getcanuseorg, getBaseData } from '/@/api/system/user';
-import { getTelsList } from '/@/api/deviceManagement/tels';
+import { getTelsList } from '/@/api/device/tels';
 // 定义接口来定义对象的类型
 interface UserState {
 	isShowDialog: boolean;

+ 1 - 1
src/views/system/user/component/editUser.vue

@@ -90,7 +90,7 @@ import type { FormInstance } from 'element-plus';
 import { ElMessage } from 'element-plus';
 import { throttle } from '/@/utils/tools';
 import { updateUser, getcanuseorg, getBaseData } from '/@/api/system/user';
-import { getTelsList } from '/@/api/deviceManagement/tels';
+import { getTelsList } from '/@/api/device/tels';
 // 定义接口来定义对象的类型
 interface UserState {
 	isShowDialog: boolean;

+ 2 - 4
src/views/system/user/index.vue

@@ -193,9 +193,7 @@ const getList = () => {
 			state.tableData = response?.result.items ?? [];
 			state.total = response?.result.total;
 			rightScrollRef.value.setScrollTop(0); //滚动倒顶部
-			setTimeout(() => {
-				state.loading = false;
-			}, 300);
+			state.loading = false;
 		})
 		.catch(() => {
 			state.loading = false;
@@ -321,7 +319,7 @@ onMounted(() => {
 		.flex-column {
 			display: flex;
 			flex-direction: column;
-      height:100%;
+			height: 100%;
 			.el-table {
 				flex: 1;
 			}

+ 1 - 1
src/views/telsManage/blacklist/component/addBlacklist.vue → src/views/tels/blacklist/component/addBlacklist.vue

@@ -71,7 +71,7 @@
 <script lang="ts" setup name="addBlacklist">
 import { ref, reactive} from 'vue';
 import { ElMessage } from 'element-plus';
-import { addBlacklist } from '/@/api/telsManage/blacklist';
+import { addBlacklist } from '/@/api/tels/blacklist';
 
 // 定义接口来定义对象的类型
 interface StateBacklist {

+ 0 - 0
src/views/telsManage/blacklist/component/operationRecord.vue → src/views/tels/blacklist/component/operationRecord.vue


+ 62 - 66
src/views/telsManage/blacklist/index.vue → src/views/tels/blacklist/index.vue

@@ -5,18 +5,15 @@
 			<el-form :model="queryParams" ref="ruleFormRef" :inline="true" @submit.native.prevent class="mt15">
 				<el-form-item label="级别" prop="level">
 					<el-select v-model="queryParams.level" placeholder="请选择呼叫方向" class="w100">
-						<el-option v-for="item in levelList" :key="item.value" :label="item.label"
-							:value="item.value" />
+						<el-option v-for="item in levelList" :key="item.value" :label="item.label" :value="item.value" />
 					</el-select>
 				</el-form-item>
 				<el-form-item label="电话号码" prop="PhoneNum">
-					<el-input v-model="queryParams.PhoneNum" placeholder="请输入电话号码" clearable
-						@keyup.enter="handleQuery" />
+					<el-input v-model="queryParams.PhoneNum" placeholder="请输入电话号码" clearable @keyup.enter="handleQuery" />
 				</el-form-item>
 				<el-form-item label="状态" prop="status">
 					<el-select v-model="queryParams.status" placeholder="请选择呼叫方向" class="w100">
-						<el-option v-for="item in statusList" :key="item.value" :label="item.label"
-							:value="item.value" />
+						<el-option v-for="item in statusList" :key="item.value" :label="item.label" :value="item.value" />
 					</el-select>
 				</el-form-item>
 				<el-form-item label="时间" prop="time">
@@ -31,12 +28,8 @@
 					/>
 				</el-form-item>
 				<el-form-item>
-					<el-button type="primary" @click="handleQuery" :loading="loading" v-waves>
-						<SvgIcon name="ele-Search" class="mr5" />查询
-					</el-button>
-					<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button">
-						<SvgIcon name="ele-Refresh" class="mr5" />重置
-					</el-button>
+					<el-button type="primary" @click="handleQuery" :loading="loading" v-waves> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+					<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
 				</el-form-item>
 			</el-form>
 		</el-card>
@@ -44,14 +37,12 @@
 			<div class="flex-center-between mb20">
 				<p class="table-title">信息列表</p>
 				<div>
-					<el-button type="primary" @click="onAddBacklist" v-waves v-auth="'200201'">
-						<SvgIcon name="ele-Plus" class="mr5" />新增
-					</el-button>
+					<el-button type="primary" @click="onAddBacklist" v-waves v-auth="'200201'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
 					<el-button type="primary" @click="onRemove" v-waves v-auth="'200202'" :disabled="!state.multipleSelection.length">
-						<SvgIcon name="ele-Delete" class="mr5"/>解除
+						<SvgIcon name="ele-Delete" class="mr5" />解除
 					</el-button>
 					<el-button type="primary" v-waves @click="onImportTable" :disabled="!state.multipleSelection.length">
-						<SvgIcon name="iconfont icon-daochu" class="mr5"/>导出
+						<SvgIcon name="iconfont icon-daochu" class="mr5" />导出
 					</el-button>
 				</div>
 			</div>
@@ -62,10 +53,11 @@
 				<el-table-column prop="phoneNo" label="电话号码" show-overflow-tooltip></el-table-column>
 				<el-table-column label="级别" show-overflow-tooltip width="170">
 					<template #header>
-						<p class="flex-center-align">级别
+						<p class="flex-center-align">
+							级别
 							<el-popover placement="top-start" :width="500" trigger="hover">
 								<template #reference>
-									<SvgIcon name="ele-QuestionFilled"  color="var(--el-color-info)" class="ml5"/>
+									<SvgIcon name="ele-QuestionFilled" color="var(--el-color-info)" class="ml5" />
 								</template>
 								<div>
 									<p>呼入限制:接通后直接挂断</p>
@@ -107,8 +99,7 @@
 				</template>
 			</el-table>
 			<!-- 分页 -->
-			<pagination :total="total" v-model:page="queryParams.PageIndex" v-model:limit="queryParams.PageSize"
-				@pagination="getList" />
+			<pagination :total="total" v-model:page="queryParams.PageIndex" v-model:limit="queryParams.PageSize" @pagination="getList" />
 		</el-card>
 
 		<AddBlacklist ref="addBlacklistRef" @updateList="handleQuery" />
@@ -121,12 +112,12 @@ import { defineAsyncComponent, ref, reactive, toRefs, onMounted } from 'vue';
 import { ElMessageBox, ElMessage } from 'element-plus';
 import type { FormInstance } from 'element-plus';
 import { formatDate } from '/@/utils/formatTime';
-import { blacklistPaged, balcklistDelete } from '/@/api/telsManage/blacklist';
+import { blacklistPaged, balcklistDelete } from '/@/api/tels/blacklist';
 import { throttle } from '/@/utils/tools';
 import table2excel from 'js-table2excel';
 // 引入组件
-const AddBlacklist = defineAsyncComponent(() => import('/@/views/telsManage/blacklist/component/addBlacklist.vue'))
-const OperationRecord = defineAsyncComponent(() => import('/@/views/telsManage/blacklist/component/operationRecord.vue'))
+const AddBlacklist = defineAsyncComponent(() => import('/@/views/tels/blacklist/component/addBlacklist.vue'));
+const OperationRecord = defineAsyncComponent(() => import('/@/views/tels/blacklist/component/operationRecord.vue'));
 
 // 定义接口来定义对象的类型
 interface QueryState {
@@ -136,8 +127,8 @@ interface QueryState {
 		PhoneNum?: string;
 		level: string; //级别
 		status: string; //状态
-		time:Array<any>;
-	}
+		time: Array<any>;
+	};
 	loading: boolean;
 	total: number;
 	tableData: Array<any>;
@@ -154,7 +145,7 @@ const state = reactive<QueryState>({
 		PhoneNum: '',
 		level: '',
 		status: '',
-		time:[]
+		time: [],
 	},
 	loading: false,
 	total: 0,
@@ -163,32 +154,33 @@ const state = reactive<QueryState>({
 	levelList: [
 		{
 			label: '全部',
-			value: ''
+			value: '',
 		},
 		{
 			label: '呼入限制',
-			value: 0
+			value: 0,
 		},
 		{
 			label: '坐席限制',
-			value: 1
-		},{
+			value: 1,
+		},
+		{
 			label: '友情提示',
-			value: 1
+			value: 1,
 		},
 	],
 	statusList: [
 		{
 			label: '全部',
-			value: ''
+			value: '',
 		},
 		{
 			label: '正常',
-			value: 0
+			value: 0,
 		},
 		{
 			label: '解除',
-			value: 1
+			value: 1,
 		},
 	],
 });
@@ -204,20 +196,20 @@ const handleQuery = throttle(() => {
 /** 获取用户列表 */
 const getList = () => {
 	state.loading = true;
-	blacklistPaged(state.queryParams).then((response: any) => {
-		state.tableData = response?.result.items;
-		state.total = response?.result.total;
-		setTimeout(() => {
+	blacklistPaged(state.queryParams)
+		.then((response: any) => {
+			state.tableData = response?.result.items;
+			state.total = response?.result.total;
 			state.loading = false;
-		}, 300);
-	}).catch(() => {
-		state.loading = false;
-	});
+		})
+		.catch(() => {
+			state.loading = false;
+		});
 };
 // 表格多选
 const handleSelectionChange = (val: any) => {
 	state.multipleSelection = val;
-}
+};
 /** 重置按钮操作 */
 const resetQuery = throttle((formEl: FormInstance | undefined) => {
 	if (!formEl) return;
@@ -227,16 +219,16 @@ const resetQuery = throttle((formEl: FormInstance | undefined) => {
 // 打开新增黑名单弹窗
 const onAddBacklist = () => {
 	addBlacklistRef.value.openDialog();
-}
+};
 // 导出表格
 const onImportTable = () => {
 	const tabeHeader = [
 		{ key: 'phoneNo', colWidth: '', title: '电话号码', type: 'text', isCheck: true },
 		{ key: 'duration', colWidth: '', title: '黑名单时长(秒)', type: 'text', isCheck: true },
 		{ key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
-	]
+	];
 	table2excel(tabeHeader, state.multipleSelection, `${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
-}
+};
 // 删除黑名单
 const onRowDel = (row: any) => {
 	ElMessageBox.confirm(`此操作将永久删除:“${row.phoneNo}”,是否继续?`, '提示', {
@@ -245,34 +237,38 @@ const onRowDel = (row: any) => {
 		type: 'warning',
 		draggable: true,
 		cancelButtonClass: 'default-button',
-		autofocus: false
-	}).then(() => {
-		balcklistDelete(row.phoneNo).then(() => {
-			ElMessage.success('删除成功');
-			handleQuery();
-		});
-	}).catch(() => { });
-}
+		autofocus: false,
+	})
+		.then(() => {
+			balcklistDelete(row.phoneNo).then(() => {
+				ElMessage.success('删除成功');
+				handleQuery();
+			});
+		})
+		.catch(() => {});
+};
 // 解除黑名单
-const onRemove = ()=>{
+const onRemove = () => {
 	ElMessageBox.confirm(`此操作将解除:“”,是否继续?`, '提示', {
 		confirmButtonText: '确认',
 		cancelButtonText: '取消',
 		type: 'warning',
 		draggable: true,
 		cancelButtonClass: 'default-button',
-		autofocus: false
-	}).then(() => {
-		// balcklistDelete(row.phoneNo).then(() => {
-		// 	ElMessage.success('解除成功');
-		// 	handleQuery();
-		// });
-	}).catch(() => { });
-}
+		autofocus: false,
+	})
+		.then(() => {
+			// balcklistDelete(row.phoneNo).then(() => {
+			// 	ElMessage.success('解除成功');
+			// 	handleQuery();
+			// });
+		})
+		.catch(() => {});
+};
 // 查看操作记录
-const onViewRecord = (row:any)=>{
+const onViewRecord = (row: any) => {
 	operationRecordRef.value.openDialog(row);
-}
+};
 onMounted(() => {
 	getList();
 });

+ 0 - 0
src/views/telsManage/callRecord/component/PlayRecording.vue → src/views/tels/callRecord/component/PlayRecording.vue


+ 62 - 83
src/views/telsManage/callRecord/index.vue → src/views/tels/callRecord/index.vue

@@ -8,35 +8,28 @@
 				<el-form :model="queryParams" ref="ruleFormRef" :inline="true" @submit.native.prevent class="mt15">
 					<el-form-item label="呼叫方向" prop="Direction" v-if="activeName === 'missed'">
 						<el-select v-model="queryParams.Direction" placeholder="请选择呼叫方向" class="w100">
-							<el-option v-for="item in directionList" :key="item.value" :label="item.label"
-								:value="item.value" />
+							<el-option v-for="item in directionList" :key="item.value" :label="item.label" :value="item.value" />
 						</el-select>
 					</el-form-item>
 					<el-form-item label="接通状态" prop="CallState" v-else>
 						<el-select v-model="queryParams.CallState" placeholder="请选择接通状态" class="w100">
-							<el-option v-for="item in stateList" :key="item.value" :label="item.label"
-								:value="item.value" />
+							<el-option v-for="item in stateList" :key="item.value" :label="item.label" :value="item.value" />
 						</el-select>
 					</el-form-item>
 					<el-form-item label="被叫号码" prop="PhoneNum">
-						<el-input v-model="queryParams.PhoneNum" placeholder="请输入被叫号码" clearable
-							@keyup.enter="getList(activeName)" />
+						<el-input v-model="queryParams.PhoneNum" placeholder="请输入被叫号码" clearable @keyup.enter="getList(activeName)" />
 					</el-form-item>
 					<el-form-item label="主叫号码" prop="ToNum">
-						<el-input v-model="queryParams.ToNum" placeholder="请输入主叫号码" clearable
-							@keyup.enter="getList(activeName)" />
+						<el-input v-model="queryParams.ToNum" placeholder="请输入主叫号码" clearable @keyup.enter="getList(activeName)" />
 					</el-form-item>
 					<el-form-item label="坐席" prop="UserName">
-						<el-input v-model="queryParams.UserName" placeholder="请输入坐席姓名或工号" clearable
-							@keyup.enter="getList(activeName)" />
+						<el-input v-model="queryParams.UserName" placeholder="请输入坐席姓名或工号" clearable @keyup.enter="getList(activeName)" />
 					</el-form-item>
 					<el-form-item>
 						<el-button type="primary" @click="getList(activeName)" :loading="loading" v-waves>
 							<SvgIcon name="ele-Search" class="mr5" />查询
 						</el-button>
-						<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button">
-							<SvgIcon name="ele-Refresh" class="mr5" />重置
-						</el-button>
+						<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
 					</el-form-item>
 				</el-form>
 			</el-tabs>
@@ -80,16 +73,13 @@
 					<el-table-column prop="ringOffTypeText" label="挂断原因" show-overflow-tooltip></el-table-column>
 					<el-table-column label="操作" width="120" fixed="right" align="center">
 						<template #default="scope">
-							<el-button text type="primary" @click="onPalySoundRecording(scope.row)" v-auth="'200202'"
-								title="播放录音">
+							<el-button text type="primary" @click="onPalySoundRecording(scope.row)" v-auth="'200202'" title="播放录音">
 								<SvgIcon name="ele-VideoPlay" size="var(--hotline-table-icon-font-size)" />
 							</el-button>
-							<el-button text type="success" @click="onDownload(scope.row)" v-auth="'200202'"
-								title="下载录音">
+							<el-button text type="success" @click="onDownload(scope.row)" v-auth="'200202'" title="下载录音">
 								<SvgIcon name="ele-Download" size="var(--hotline-table-icon-font-size)" />
 							</el-button>
-							<el-button text type="warning" @click="onRelationWorkOrder(scope.row)" v-auth="'200202'"
-								title="关联工单">
+							<el-button text type="warning" @click="onRelationWorkOrder(scope.row)" v-auth="'200202'" title="关联工单">
 								<SvgIcon name="ele-Connection" size="var(--hotline-table-icon-font-size)" />
 							</el-button>
 						</template>
@@ -112,16 +102,13 @@
 					<el-table-column prop="toNo" label="通话保持时长" show-overflow-tooltip></el-table-column>
 					<el-table-column label="操作" width="120" fixed="right" align="center">
 						<template #default="scope">
-							<el-button text type="primary" @click="onPalySoundRecording(scope.row)"
-								title="播放录音">
+							<el-button text type="primary" @click="onPalySoundRecording(scope.row)" title="播放录音">
 								<SvgIcon name="ele-VideoPlay" size="var(--hotline-table-icon-font-size)" />
 							</el-button>
-							<el-button text type="success" @click="onDownload(scope.row)"
-								title="下载录音">
+							<el-button text type="success" @click="onDownload(scope.row)" title="下载录音">
 								<SvgIcon name="ele-Download" size="var(--hotline-table-icon-font-size)" />
 							</el-button>
-							<el-button text type="warning" @click="onRelationWorkOrder(scope.row)"
-								title="关联工单">
+							<el-button text type="warning" @click="onRelationWorkOrder(scope.row)" title="关联工单">
 								<SvgIcon name="ele-Connection" size="var(--hotline-table-icon-font-size)" />
 							</el-button>
 						</template>
@@ -135,8 +122,7 @@
 					<el-table-column prop="toNo" label="等待时长" show-overflow-tooltip></el-table-column>
 					<el-table-column prop="toNo" label="坐席" show-overflow-tooltip></el-table-column>
 					<el-table-column prop="toNo" label="挂断方" show-overflow-tooltip></el-table-column>
-					<el-table-column prop="ringOffTypeText" label="未接原因" show-overflow-tooltip fixed="right"
-						align="center"></el-table-column>
+					<el-table-column prop="ringOffTypeText" label="未接原因" show-overflow-tooltip fixed="right" align="center"></el-table-column>
 				</template>
 
 				<!-- <el-table-column prop="callTypeText" label="通话类型" show-overflow-tooltip></el-table-column>
@@ -152,10 +138,9 @@
 				</template>
 			</el-table>
 			<!-- 分页 -->
-			<pagination :total="total" v-model:page="queryParams.PageIndex" v-model:limit="queryParams.PageSize"
-				@pagination="getList(activeName)" />
+			<pagination :total="total" v-model:page="queryParams.PageIndex" v-model:limit="queryParams.PageSize" @pagination="getList(activeName)" />
 		</el-card>
-		<PlayRecording ref="playRecordingRef"/>
+		<PlayRecording ref="playRecordingRef" />
 	</div>
 </template>
 
@@ -169,18 +154,18 @@ import { storeToRefs } from 'pinia';
 import { useThemeConfig } from '/@/stores/themeConfig';
 // 引入节流
 import { throttle } from '/@/utils/tools';
-import { callPaged, callPagedMissed } from '/@/api/telsManage/callRecord';
+import { callPaged, callPagedMissed } from '/@/api/tels/callRecord';
 
 // 引入组件
-const PlayRecording = defineAsyncComponent(() => import('/@/views/telsManage/callRecord/component/PlayRecording.vue'))
+const PlayRecording = defineAsyncComponent(() => import('/@/views/tels/callRecord/component/PlayRecording.vue'));
 
 // 定义接口来定义对象的类型
 interface QueryState {
 	activeName: string;
 	queryParams: {
-		Direction: string;//呼叫方向
-		CallState: string;//接通状态
-		PhoneNum?: string;// 被叫号码
+		Direction: string; //呼叫方向
+		CallState: string; //接通状态
+		PhoneNum?: string; // 被叫号码
 		ToNum: string; // 主叫号码
 		PageIndex: number;
 		PageSize: number;
@@ -196,7 +181,7 @@ interface QueryState {
 
 // 定义变量内容
 const state = reactive(<QueryState>{
-	activeName: "incoming",
+	activeName: 'incoming',
 	queryParams: {
 		PageIndex: 1,
 		PageSize: 10,
@@ -204,7 +189,7 @@ const state = reactive(<QueryState>{
 		Direction: '',
 		ToNum: '',
 		CallState: '',
-		UserName: ''
+		UserName: '',
 	},
 	tableList: [],
 	loading: false,
@@ -213,32 +198,32 @@ const state = reactive(<QueryState>{
 	stateList: [
 		{
 			label: '全部',
-			value: ''
+			value: '',
 		},
 		{
 			label: '已接通',
-			value: 0
+			value: 0,
 		},
 		{
 			label: '未接通',
-			value: 1
+			value: 1,
 		},
 	],
 	directionList: [
 		{
 			label: '全部',
-			value: ''
+			value: '',
 		},
 		{
 			label: '呼入',
-			value: 0
+			value: 0,
 		},
 		{
 			label: '呼出',
-			value: 1
+			value: 1,
 		},
-	]
-})
+	],
+});
 const storesThemeConfig = useThemeConfig();
 const { themeConfig } = storeToRefs(storesThemeConfig);
 const { queryParams, tableList, loading, total, activeName, directionList, stateList } = toRefs(state);
@@ -250,37 +235,37 @@ const getList = (val: string) => {
 	state.loading = true;
 	switch (val) {
 		case 'incoming':
-			callPaged(queryParams.value).then((response: any) => {
-				state.tableList = response?.result.items ?? [];
-				state.total = response?.result.total;
-				setTimeout(() => {
+			callPaged(queryParams.value)
+				.then((response: any) => {
+					state.tableList = response?.result.items ?? [];
+					state.total = response?.result.total;
 					state.loading = false;
-				}, 300);
-			}).catch(() => {
-				state.loading = false;
-			});
+				})
+				.catch(() => {
+					state.loading = false;
+				});
 			break;
 		case 'exhale':
-			callPaged(queryParams.value).then((response: any) => {
-				state.tableList = response?.result.items ?? [];
-				state.total = response?.result.total;
-				setTimeout(() => {
+			callPaged(queryParams.value)
+				.then((response: any) => {
+					state.tableList = response?.result.items ?? [];
+					state.total = response?.result.total;
+					state.loading = false;
+				})
+				.catch(() => {
 					state.loading = false;
-				}, 300);
-			}).catch(() => {
-				state.loading = false;
-			});
+				});
 			break;
 		case 'missed':
-			callPagedMissed(queryParams.value).then((response: any) => {
-				state.tableList = response?.result.items ?? [];
-				state.total = response?.result.total;
-				setTimeout(() => {
+			callPagedMissed(queryParams.value)
+				.then((response: any) => {
+					state.tableList = response?.result.items ?? [];
+					state.total = response?.result.total;
 					state.loading = false;
-				}, 300);
-			}).catch(() => {
-				state.loading = false;
-			});
+				})
+				.catch(() => {
+					state.loading = false;
+				});
 			break;
 
 		default:
@@ -290,7 +275,7 @@ const getList = (val: string) => {
 // 多选表格
 const handleSelectionChange = (val: any) => {
 	state.multipleSelection = val;
-}
+};
 /** 重置按钮操作 */
 const resetQuery = throttle((formEl: FormInstance | undefined) => {
 	if (!formEl) return;
@@ -300,7 +285,7 @@ const resetQuery = throttle((formEl: FormInstance | undefined) => {
 // 切换tab 查询列表
 const handleClick = (val: string) => {
 	getList(val);
-}
+};
 // 导出表格
 const onImportTable = () => {
 	const tabeHeader = [
@@ -316,25 +301,19 @@ const onImportTable = () => {
 		{ key: 'attribution', colWidth: '', title: '归属地', type: 'text', isCheck: true },
 		// { key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
 		// { key: 'image', colWidth: '', width: '70', height: '40', title: '图片描述', type: 'image', isCheck: true },
-	]
+	];
 	table2excel(tabeHeader, state.multipleSelection, `${themeConfig.value.globalTitle} ${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
-}
+};
 // 播放录音
 const onPalySoundRecording = (val: any) => {
 	playRecordingRef.value.openDialog(val);
-}
+};
 // 下载录音
-const onDownload = (val: any) => {
-
-}
+const onDownload = (val: any) => {};
 // 关联工单
-const onRelationWorkOrder = (val: any) => {
-
-}
+const onRelationWorkOrder = (val: any) => {};
 onMounted(() => {
 	getList(state.activeName);
 });
-
 </script>
-<style lang="scss" scoped>
-</style>
+<style lang="scss" scoped></style>

+ 0 - 0
src/views/telsManage/telsLog/component/detail.vue → src/views/tels/telsLog/component/detail.vue


+ 20 - 24
src/views/telsManage/telsLog/index.vue → src/views/tels/telsLog/index.vue

@@ -15,12 +15,8 @@
 					/>
 				</el-form-item>
 				<el-form-item>
-					<el-button type="primary" @click="handleQuery" :loading="loading" v-waves>
-						<SvgIcon name="ele-Search" class="mr5" />查询
-					</el-button>
-					<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button">
-						<SvgIcon name="ele-Refresh" class="mr5" />重置
-					</el-button>
+					<el-button type="primary" @click="handleQuery" :loading="loading" v-waves> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+					<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
 				</el-form-item>
 			</el-form>
 		</el-card>
@@ -66,19 +62,19 @@ import { defineAsyncComponent, ref, reactive, toRefs, onMounted } from 'vue';
 import { ElMessage } from 'element-plus';
 import type { FormInstance } from 'element-plus';
 import { formatDate } from '/@/utils/formatTime';
-import { blacklistPaged } from '/@/api/telsManage/blacklist';
+import { blacklistPaged } from '/@/api/tels/blacklist';
 import { throttle } from '/@/utils/tools';
 import table2excel from 'js-table2excel';
 // 引入组件
-const Detail = defineAsyncComponent(() => import('/@/views/telsManage/telsLog/component/detail.vue'))
+const Detail = defineAsyncComponent(() => import('/@/views/tels/telsLog/component/detail.vue'));
 
 // 定义接口来定义对象的类型
 interface QueryState {
 	queryParams: {
 		PageIndex: number;
 		PageSize: number;
-		time:Array<any>;
-	}
+		time: Array<any>;
+	};
 	loading: boolean;
 	total: number;
 	tableData: Array<any>;
@@ -90,7 +86,7 @@ const state = reactive<QueryState>({
 	queryParams: {
 		PageIndex: 1,
 		PageSize: 10,
-		time:[]
+		time: [],
 	},
 	loading: false,
 	total: 0,
@@ -108,20 +104,20 @@ const handleQuery = throttle(() => {
 /** 获取用户列表 */
 const getList = () => {
 	state.loading = true;
-	blacklistPaged(state.queryParams).then((response: any) => {
-		state.tableData = response?.result.items;
-		state.total = response?.result.total;
-		setTimeout(() => {
+	blacklistPaged(state.queryParams)
+		.then((response: any) => {
+			state.tableData = response?.result.items;
+			state.total = response?.result.total;
+			state.loading = false;
+		})
+		.catch(() => {
 			state.loading = false;
-		}, 300);
-	}).catch(() => {
-		state.loading = false;
-	});
+		});
 };
 // 表格多选
 const handleSelectionChange = (val: any) => {
 	state.multipleSelection = val;
-}
+};
 /** 重置按钮操作 */
 const resetQuery = throttle((formEl: FormInstance | undefined) => {
 	if (!formEl) return;
@@ -134,13 +130,13 @@ const onImportTable = () => {
 		{ key: 'phoneNo', colWidth: '', title: '电话号码', type: 'text', isCheck: true },
 		{ key: 'duration', colWidth: '', title: '黑名单时长(秒)', type: 'text', isCheck: true },
 		{ key: 'creationTime', colWidth: '', title: '创建时间', type: 'text', isCheck: true },
-	]
+	];
 	table2excel(tabeHeader, state.multipleSelection, `${formatDate(new Date(), 'YYYY-mm-dd HH-MM')}`);
-}
+};
 // 查看坐席话务明细
-const onDetail= (row:any)=>{
+const onDetail = (row: any) => {
 	DetailRef.value.openDialog(row);
-}
+};
 onMounted(() => {
 	getList();
 });

部分文件因文件數量過多而無法顯示