From d04ecbb2aa47d93e05d28bb551e7bad83d97d60f Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Wed, 03 Jun 2026 18:38:55 +0800
Subject: [PATCH] feat: 类型多选改造

---
 applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/FormDiaLog.vue |   62 ++++++++----
 applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue             |   20 +--
 applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue            |   15 +-
 applications/task-work-order/src/views/orderView/orderManage/taskTypeOptions.js               |  105 +++++++++++++++++++++
 applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue      |   15 +-
 applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue |   27 ++--
 applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue       |   29 +++--
 7 files changed, 197 insertions(+), 76 deletions(-)

diff --git a/applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue b/applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue
index 4808ea5..2261862 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue
@@ -13,21 +13,16 @@
 			</el-form-item>
 
 			<el-form-item label="巡查任务类型" prop="patrolTaskType">
-				<el-select
+				<el-cascader
 					class="gd-select gray"
 					popper-class="gd-select-popper"
 					v-model="searchParams.patrolTaskType"
+					:options="workOrderTypeXT"
+					:props="taskTypeFilterCascaderProps"
 					placeholder="请选择"
 					clearable
 					@change="handleSearch"
-				>
-					<el-option
-						v-for="item in workOrderTypeXT"
-						:key="item.dictValue"
-						:label="item.dictLabel"
-						:value="item.dictValue"
-					/>
-				</el-select>
+				/>
 			</el-form-item>
 
 			<!-- <el-form-item label="任务状态" prop="taskStatus">
@@ -76,7 +71,7 @@
 					<el-table-column prop="taskNo" show-overflow-tooltip label="巡查任务编号" />
 					<el-table-column prop="patrolTaskType" show-overflow-tooltip label="巡查任务类型">
 						<template v-slot="{ row }">
-							{{ getDictLabelXT(row.patrolTaskType, workOrderTypeXT) }}
+							{{ getTaskTypeLabel(row.patrolTaskType, workOrderTypeXT) }}
 						</template>
 					</el-table-column>
 					<el-table-column prop="taskStatus" show-overflow-tooltip label="巡查任务状态">
@@ -117,12 +112,13 @@
 import { Search, RefreshRight } from '@element-plus/icons-vue'
 import { computed, onMounted, ref } from 'vue'
 import { getDictionaryByCode } from '@/api/system/dictbiz'
-import { dateRangeFormat, getDictLabel, getDictLabelXT } from '@ztzf/utils'
+import { dateRangeFormat, getDictLabel } from '@ztzf/utils'
 import { getDictListApi } from '@/api/zkxt'
 import { gdPatrolTaskPageApi } from '../inspectionRequest/inspectionRequestApi'
 import { getDeptTree } from '@/api/system/dept'
 import ViewDiaLog from './ViewDiaLog.vue'
 import { useStore } from 'vuex'
+import { getTaskTypeLabel, normalizeTaskTypeOptions, taskTypeFilterCascaderProps } from '../taskTypeOptions'
 
 // 初始化查询参数
 const initSearchParams = () => ({
@@ -204,7 +200,7 @@
 		dictObj.value = res.data.data
 	})
 	getDictListApi('task_inspection_type').then(res => {
-		workOrderTypeXT.value = res.data.data || []
+		workOrderTypeXT.value = normalizeTaskTypeOptions(res.data.data || [])
 	})
 }
 
diff --git a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/FormDiaLog.vue
index 24f51c2..ad0e5d6 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/FormDiaLog.vue
@@ -33,7 +33,7 @@
 						<div class="info-item">
 							<span class="label">工单类型</span>
 							<span class="val" v-if="selectedWorkOrder">
-								{{ getDictLabelXT(selectedWorkOrder.workOrderType, workOrderTypeXT) }}
+								{{ getTaskTypeLabel(selectedWorkOrder.workOrderType, workOrderTypeXT) }}
 							</span>
 							<span class="val grayText" v-else>选择工单后自动带出</span>
 						</div>
@@ -98,20 +98,15 @@
 								巡查任务类型
 							</template>
 							<template v-slot="{ row, $index }">
-								<el-select
+								<el-cascader
 									class="gd-select"
 									popper-class="gd-select-popper"
 									v-model="row.patrolTaskType"
+									:options="workOrderTypeXT"
+									:props="taskTypeCascaderProps"
 									placeholder="请选择"
 									@change="handlePatrolTaskTypeChange($index, $event)"
-								>
-									<el-option
-										v-for="item in workOrderTypeXT"
-										:key="item.dictValue"
-										:label="item.dictLabel"
-										:value="item.dictValue"
-									/>
-								</el-select>
+								/>
 							</template>
 						</el-table-column>
 						<el-table-column prop="executeTime" width="200">
@@ -165,7 +160,7 @@
 									v-model="row.deviceFlyerId"
 									placeholder="请选择"
 									filterable
-									:disabled="dialogReadonly || !taskList[$index].patrolTaskType"
+									:disabled="dialogReadonly || !hasTaskTypeValue(taskList[$index].patrolTaskType)"
 
 								>
 									<el-option
@@ -268,18 +263,25 @@
 import { computed, ref, onMounted, inject } from 'vue'
 import { ElMessage } from 'element-plus'
 import { Plus, Delete } from '@element-plus/icons-vue'
-import { geomAnalysis, getDictLabel, getDictLabelXT } from '@ztzf/utils'
+import { geomAnalysis, getDictLabel } from '@ztzf/utils'
 
 import { gdPatrolTaskSaveApi, gdFlyerPageApi, gdPatrolTaskAuditApi } from './inspectionRequestApi'
 import { gdWorkOrderPageApi } from '../orderManage/orderManageApi'
 import { gdManageDeviceListApi } from '../orderManage/gdManageDeviceApi'
 import { pxToRem } from '@/utils/rem'
 import { airlineListApi, algorithmGroupedApi } from '@/api/zkxt'
+import {
+	getTaskTypeLabel,
+	getTaskTypeLeafValues,
+	taskTypeCascaderProps,
+	toTaskTypeCascaderValue,
+	toTaskTypeRequestValue,
+} from '../taskTypeOptions'
 
 // 初始化任务行
 const initTaskRow = () => ({
 	patrolTaskName: '',
-	patrolTaskType: '',
+	patrolTaskType: [],
 	executeTime: '',
 	patrolRouteUrl: '',
 	deviceFlyerId: '',
@@ -339,13 +341,14 @@
 		// 将工单类型赋值给所有子任务行
 		const workOrderType = selectedWorkOrder.value?.workOrderType
 		if (workOrderType) {
+			const patrolTaskType = toTaskTypeCascaderValue(workOrderType)
 			taskList.value.forEach((task, index) => {
 				taskList.value[index] = {
 					...initTaskRow(),
-					patrolTaskType: workOrderType,
+					patrolTaskType,
 				}
 				// 获取对应的飞手列表
-				getFlyerList(index, workOrderType)
+				getFlyerList(index, patrolTaskType)
 			})
 		}
 	} else {
@@ -373,7 +376,7 @@
 	const newTask = initTaskRow()
 	// 如果已选择工单,自动填充工单类型
 	if (selectedWorkOrder.value?.workOrderType) {
-		newTask.patrolTaskType = selectedWorkOrder.value.workOrderType
+		newTask.patrolTaskType = toTaskTypeCascaderValue(selectedWorkOrder.value.workOrderType)
 	}
 	const newIndex = taskList.value.length
 	taskList.value.push(newTask)
@@ -437,11 +440,16 @@
 
 // 获取飞手列表
 async function getFlyerList(index, skilledTaskType) {
+	const leafValues = getTaskTypeLeafValues(skilledTaskType)
+	if (!leafValues.length) {
+		flyerListMap.value[index] = []
+		return
+	}
 	const obj = getPolygonCenter(geomAnalysis(selectedWorkOrder.value.geom))
 	const res = await gdFlyerPageApi({
 		size: 999,
 		current: 1,
-		skilledTaskType,
+		skilledTaskType: leafValues.join(','),
 		// longitude: obj.longitude || '',
 		// latitude: obj.latitude || '',
 	})
@@ -466,7 +474,18 @@
 
 // 判断一行是否已填写(至少填写了任务名称)
 function isTaskRowFilled(task) {
-	return !!(task.patrolTaskName || task.executeTime || task.patrolRouteUrl || task.deviceFlyerId || task.deviceId)
+	return !!(
+		task.patrolTaskName ||
+		hasTaskTypeValue(task.patrolTaskType) ||
+		task.executeTime ||
+		task.patrolRouteUrl ||
+		task.deviceFlyerId ||
+		task.deviceId
+	)
+}
+
+function hasTaskTypeValue(value) {
+	return !!toTaskTypeRequestValue(value).length
 }
 
 // 提交新增
@@ -491,7 +510,7 @@
 			ElMessage.warning(`第${i + 1}行: 请输入巡查任务名称`)
 			return
 		}
-		if (!task.patrolTaskType) {
+		if (!hasTaskTypeValue(task.patrolTaskType)) {
 			ElMessage.warning(`第${i + 1}行: 请选择巡查任务类型`)
 			return
 		}
@@ -518,6 +537,7 @@
 		// 只提交已填写的任务行
 		const dataList = filledTasks.map(item => ({
 			...item,
+			patrolTaskType: toTaskTypeRequestValue(item.patrolTaskType),
 			workOrderId: selectedWorkOrderId.value,
 			id: undefined,
 		}))
@@ -546,11 +566,11 @@
 		// 编辑/查看模式 - 加载已有数据
 		selectedWorkOrderId.value = row?.workOrderId
 		handleWorkOrderChange(row?.workOrderId)
-		taskList.value = [{ ...row }]
+		taskList.value = [{ ...row, patrolTaskType: toTaskTypeCascaderValue(row?.patrolTaskType) }]
 		flyerListMap.value = {}
 		// 如果有巡查类型,加载对应的飞手列表
 		if (row?.patrolTaskType) {
-			getFlyerList(0, row.patrolTaskType)
+			getFlyerList(0, taskList.value[0].patrolTaskType)
 		}
 	}
 }
diff --git a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
index ec7a7b3..9e20e41 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
@@ -42,7 +42,7 @@
 						</el-col>
 						<el-col :span="12">
 							<div class="label">巡查任务类型</div>
-							<div class="val">{{ getDictLabelXT(formData.patrolTaskType, workOrderTypeXT) }}</div>
+							<div class="val">{{ getTaskTypeLabel(formData.patrolTaskType, workOrderTypeXT) }}</div>
 						</el-col>
 						<el-col :span="12">
 							<div class="label">任务执行时间</div>
@@ -111,20 +111,15 @@
 						</el-col>
 						<el-col :span="12">
 							<el-form-item label="巡查任务类型" prop="patrolTaskType">
-								<el-select
+								<el-cascader
 									class="gd-select"
 									popper-class="gd-select-popper"
 									v-model="formData.patrolTaskType"
+									:options="workOrderTypeXT"
+									:props="taskTypeCascaderProps"
 									placeholder="请选择"
 									clearable
-								>
-									<el-option
-										v-for="item in workOrderTypeXT"
-										:key="item.dictValue"
-										:label="item.dictLabel"
-										:value="item.dictValue"
-									/>
-								</el-select>
+								/>
 							</el-form-item>
 						</el-col>
 						<el-col :span="12">
@@ -286,7 +281,7 @@
 <script setup>
 import { computed, ref, onMounted, inject } from 'vue'
 import { ElMessage } from 'element-plus'
-import { fieldRules, flyVisual, getDictLabel, getDictLabelXT, geomAnalysis } from '@ztzf/utils'
+import { fieldRules, flyVisual, getDictLabel, geomAnalysis } from '@ztzf/utils'
 import {
 	gdPatrolTaskRepublish,
 	gdFlyerPageApi,
@@ -303,12 +298,13 @@
 import { queryAirById, airlineListApi, algorithmGroupedApi } from '@/api/zkxt'
 import * as Cesium from 'cesium'
 import { useStore } from 'vuex'
+import { getTaskTypeLabel, taskTypeCascaderProps, toTaskTypeCascaderValue, toTaskTypeRequestValue } from '../taskTypeOptions'
 
 // 初始化表单数据
 const initForm = () => ({
 	id: null,
 	patrolTaskName: '',
-	patrolTaskType: '',
+	patrolTaskType: [],
 	executeTime: '',
 	patrolRouteUrl: '',
 	deviceFlyerId: null,
@@ -493,7 +489,11 @@
 	if (!isValid) return
 	submitting.value = true
 	try {
-		await gdPatrolTaskRepublish(formData.value)
+		const payload = {
+			...formData.value,
+			patrolTaskType: toTaskTypeRequestValue(formData.value.patrolTaskType),
+		}
+		await gdPatrolTaskRepublish(payload)
 		ElMessage.success('更新成功')
 		visible.value = false
 		emit('success')
@@ -584,6 +584,7 @@
 
 	const res = await gdPatrolTaskDetailApi({ id: row.id })
 	formData.value = { ...initForm(), ...res.data.data }
+	formData.value.patrolTaskType = toTaskTypeCascaderValue(formData.value.patrolTaskType)
 	// 确保 algorithmIds 是数组
 	if (formData.value.algorithmIds && typeof formData.value.algorithmIds === 'string') {
 		formData.value.algorithmIds = formData.value.algorithmIds.split(',').filter(Boolean)
diff --git a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue
index 4f0e1c6..255489e 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue
@@ -11,11 +11,9 @@
 			</el-form-item>
 
 			<el-form-item label="任务类型" prop="patrolTaskType">
-				<el-select class="gd-select gray" popper-class="gd-select-popper" v-model="searchParams.patrolTaskType"
-					placeholder="请选择" clearable @change="handleSearch">
-					<el-option v-for="item in workOrderTypeXT" :key="item.dictValue" :label="item.dictLabel"
-						:value="item.dictValue" />
-				</el-select>
+				<el-cascader class="gd-select gray" popper-class="gd-select-popper" v-model="searchParams.patrolTaskType"
+					:options="workOrderTypeXT" :props="taskTypeFilterCascaderProps" placeholder="请选择" clearable
+					@change="handleSearch" />
 			</el-form-item>
 
 			<el-form-item label="任务状态" prop="taskStatus">
@@ -55,7 +53,7 @@
 					<el-table-column prop="taskNo" show-overflow-tooltip label="巡查任务编号" />
 					<el-table-column prop="patrolTaskType" show-overflow-tooltip label="巡查任务类型">
 						<template v-slot="{ row }">
-							{{ getDictLabelXT(row.patrolTaskType, workOrderTypeXT) }}
+							{{ getTaskTypeLabel(row.patrolTaskType, workOrderTypeXT) }}
 						</template>
 					</el-table-column>
 					<el-table-column prop="taskStatus" show-overflow-tooltip label="巡查任务状态">
@@ -93,12 +91,13 @@
 import { onMounted, ref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { getDictionaryByCode } from '@/api/system/dictbiz'
-import { dateRangeFormat, getDictLabel, getDictLabelXT } from '@ztzf/utils'
+import { dateRangeFormat, getDictLabel } from '@ztzf/utils'
 import { getDictListApi } from '@/api/zkxt'
 import FormDiaLog from './FormDiaLog.vue'
 import { gdPatrolTaskPageApi, gdPatrolTaskRemoveApi } from './inspectionRequestApi'
 import ViewDiaLog from '@/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue'
 import { useStore } from 'vuex'
+import { getTaskTypeLabel, normalizeTaskTypeOptions, taskTypeFilterCascaderProps } from '../taskTypeOptions'
 
 const store = useStore()
 const permission = computed(() => store.state.user.permission)
@@ -217,7 +216,7 @@
 		dictObj.value = res.data.data
 	})
 	getDictListApi('task_inspection_type').then(res => {
-		workOrderTypeXT.value = res.data.data || []
+		workOrderTypeXT.value = normalizeTaskTypeOptions(res.data.data || [])
 	})
 }
 
diff --git a/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
index 6abe86f..75afa99 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
@@ -31,7 +31,7 @@
 						</el-col>
 						<el-col :span="12">
 							<div class="label">工单类型</div>
-							<div class="val">{{ getDictLabelXT(formData.workOrderType, workOrderTypeXT) }}</div>
+							<div class="val">{{ getTaskTypeLabel(formData.workOrderType, workOrderTypeXT) }}</div>
 						</el-col>
 						<el-col :span="12">
 							<div class="label">执行时间范围</div>
@@ -62,7 +62,7 @@
 							<el-table-column prop="patrolTaskName" show-overflow-tooltip label="巡查任务名称" />
 							<el-table-column prop="patrolTaskType" show-overflow-tooltip label="巡查任务类型">
 								<template v-slot="{ row }">
-									{{ getDictLabelXT(row.patrolTaskType, workOrderTypeXT) }}
+									{{ getTaskTypeLabel(row.patrolTaskType, workOrderTypeXT) }}
 								</template>
 							</el-table-column>
 							<el-table-column prop="taskStatus" show-overflow-tooltip label="任务状态">
@@ -94,20 +94,15 @@
 						</el-col>
 						<el-col :span="12">
 							<el-form-item label="工单类型" prop="workOrderType">
-								<el-select
+								<el-cascader
 									class="gd-select"
 									popper-class="gd-select-popper"
 									v-model="formData.workOrderType"
+									:options="workOrderTypeXT"
+									:props="taskTypeCascaderProps"
 									placeholder="请选择"
 									clearable
-								>
-									<el-option
-										v-for="item in workOrderTypeXT"
-										:key="item.dictValue"
-										:label="item.dictLabel"
-										:value="item.dictValue"
-									/>
-								</el-select>
+								/>
 							</el-form-item>
 						</el-col>
 						<el-col :span="12">
@@ -264,7 +259,7 @@
 <script setup>
 import { computed, ref, nextTick, inject } from 'vue'
 import { ElMessage } from 'element-plus'
-import { dateRangeFormat, fieldRules, flyVisual, geomAnalysis, getDictLabel, getDictLabelXT } from '@ztzf/utils'
+import { dateRangeFormat, fieldRules, flyVisual, geomAnalysis, getDictLabel } from '@ztzf/utils'
 import {
 	gdWorkOrderDetailApi,
 	gdWorkOrderFlowListApi,
@@ -287,6 +282,7 @@
 import OrderStepBar from '@/views/orderView/orderManage/orderManage/OrderStepBar.vue'
 import OutcomeData from './outcomeData.vue'
 import { getDictListApi } from '@/api/zkxt'
+import { getTaskTypeLabel, taskTypeCascaderProps, toTaskTypeCascaderValue, toTaskTypeRequestValue } from '../taskTypeOptions'
 const store = useStore()
 const permission = computed(() => store.state.user.permission)
 const activeName = ref('basic')
@@ -294,7 +290,7 @@
 // 初始化表单数据
 const initForm = () => ({
 	workOrderName: '',
-	workOrderType: '',
+	workOrderType: [],
 	executeStartTime: '',
 	executeEndTime: '',
 	deviceLoadDemand: '',
@@ -457,7 +453,11 @@
 		if (!formData.value.id) {
 			formData.value.workOrderStatus = '10'
 		}
-		await gdWorkOrderSaveApi(formData.value)
+		const payload = {
+			...formData.value,
+			workOrderType: toTaskTypeRequestValue(formData.value.workOrderType),
+		}
+		await gdWorkOrderSaveApi(payload)
 		ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
 		visible.value = false
 		emit('success')
@@ -479,6 +479,7 @@
 	loadList()
 	const res = await gdWorkOrderDetailApi({ id: formData.value.id })
 	formData.value = res?.data?.data ?? {}
+	formData.value.workOrderType = toTaskTypeCascaderValue(formData.value.workOrderType)
 	dateRange.value = [formData.value.executeStartTime, formData.value.executeEndTime]
 }
 
diff --git a/applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue b/applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue
index 8138358..6d6277f 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue
@@ -11,11 +11,9 @@
 			</el-form-item>
 
 			<el-form-item label="工单类型" prop="workOrderType">
-				<el-select class="gd-select gray" popper-class="gd-select-popper" v-model="searchParams.workOrderType"
-					placeholder="请选择" clearable @change="handleSearch">
-					<el-option v-for="item in workOrderTypeXT" :key="item.dictValue" :label="item.dictLabel"
-						:value="item.dictValue" />
-				</el-select>
+				<el-cascader class="gd-select gray" popper-class="gd-select-popper" v-model="searchParams.workOrderType"
+					:options="workOrderTypeXT" :props="taskTypeFilterCascaderProps" placeholder="请选择" clearable
+					@change="handleSearch" />
 			</el-form-item>
 
 			<el-form-item label="工单状态" prop="workOrderStatus">
@@ -53,7 +51,7 @@
 					<el-table-column prop="workOrderCode" show-overflow-tooltip label="工单编号" />
 					<el-table-column prop="workOrderType" show-overflow-tooltip label="工单类型">
 						<template v-slot="{ row }">
-							{{ getDictLabelXT(row.workOrderType, workOrderTypeXT) }}
+							{{ getTaskTypeLabel(row.workOrderType, workOrderTypeXT) }}
 						</template>
 					</el-table-column>
 					<el-table-column prop="status" show-overflow-tooltip label="阶段状态">
@@ -102,7 +100,7 @@
 import { onMounted, ref } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { getDictionaryByCode } from '@/api/system/dictbiz'
-import { dateRangeFormat, getDictLabel, getDictLabelXT } from '@ztzf/utils'
+import { dateRangeFormat, getDictLabel } from '@ztzf/utils'
 import { getDictListApi } from '@/api/zkxt'
 import FormDiaLog from './FormDiaLog.vue'
 import { gdWorkOrderPageApi, gdWorkOrderRemoveApi } from './orderManageApi'
@@ -111,6 +109,7 @@
 import testDock from '@/assets/docx/testDocx.docx'
 import testPdf from '@/assets/pdf/testPdf.pdf'
 import { useStore } from 'vuex'
+import { getTaskTypeLabel, normalizeTaskTypeOptions, taskTypeFilterCascaderProps } from '../taskTypeOptions'
 
 const store = useStore()
 const activeName = ref('all')
@@ -250,7 +249,7 @@
 		dictObj.value = res.data.data
 	})
 	getDictListApi('task_inspection_type').then(res => {
-		workOrderTypeXT.value = res.data.data || []
+		workOrderTypeXT.value = normalizeTaskTypeOptions(res.data.data || [])
 	})
 }
 
diff --git a/applications/task-work-order/src/views/orderView/orderManage/taskTypeOptions.js b/applications/task-work-order/src/views/orderView/orderManage/taskTypeOptions.js
new file mode 100644
index 0000000..0e5f917
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/orderManage/taskTypeOptions.js
@@ -0,0 +1,105 @@
+function parseRemarkOptions(remark) {
+	if (Array.isArray(remark)) return remark
+	if (!remark || typeof remark !== 'string') return []
+	try {
+		const options = JSON.parse(remark)
+		return Array.isArray(options) ? options : []
+	} catch (error) {
+		return []
+	}
+}
+
+export function normalizeTaskTypeOptions(list = []) {
+	return list.map(item => {
+		const remarkOptions = parseRemarkOptions(item.remark)
+			.map(option => ({
+				...option,
+				dictLabel: option.label,
+				dictValue: option.value,
+			}))
+			.sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0))
+
+		return {
+			...item,
+			remarkOptions,
+			children: remarkOptions,
+		}
+	})
+}
+
+function isValidPath(value) {
+	return (
+		Array.isArray(value) &&
+		value.length === 2 &&
+		value.every(item => item !== undefined && item !== null && item !== '' && !Array.isArray(item) && typeof item !== 'object')
+	)
+}
+
+function parseTaskTypeValue(value) {
+	if (typeof value !== 'string') return value
+	try {
+		const result = JSON.parse(value)
+		return Array.isArray(result) ? result : value
+	} catch (error) {
+		return value
+	}
+}
+
+export function toTaskTypeCascaderValue(value) {
+	value = parseTaskTypeValue(value)
+	if (!value) return []
+	if (typeof value === 'string') return []
+	if (!Array.isArray(value)) return []
+	if (isValidPath(value)) return [value]
+	if (value.length === 1 && Array.isArray(value[0]) && !isValidPath(value[0])) {
+		value = value[0]
+	}
+	return value.filter(isValidPath)
+}
+
+export function toTaskTypeRequestValue(value) {
+	return toTaskTypeCascaderValue(value).map(item => [item[0], item[1]])
+}
+
+export function getTaskTypeLeafValues(value) {
+	return toTaskTypeRequestValue(value).map(item => item[1])
+}
+
+export function getTaskTypeLabel(value, options = []) {
+	const paths = toTaskTypeCascaderValue(value)
+	if (paths.length) {
+		return paths
+			.map(path => {
+				const parent = options.find(item => item.dictValue === path[0])
+				const child = (parent?.children || []).find(item => item.dictValue === path[1])
+				return child?.dictLabel || path[1]
+			})
+			.join('、')
+	}
+
+	if (!value) return ''
+	for (const item of options) {
+		if (item.dictValue === value) return item.dictLabel
+		const child = (item.children || []).find(option => option.dictValue === value)
+		if (child) return child.dictLabel
+	}
+
+	return value
+}
+
+export const taskTypeCascaderProps = {
+	label: 'dictLabel',
+	value: 'dictValue',
+	children: 'children',
+	multiple: true,
+	emitPath: true,
+	checkStrictly: false,
+}
+
+export const taskTypeFilterCascaderProps = {
+	label: 'dictLabel',
+	value: 'dictValue',
+	children: 'children',
+	emitPath: false,
+	checkStrictly: false,
+}

--
Gitblit v1.9.3