fix: 修复接单部门审核弹窗的任务类型和数量显示问题
1. 添加层级任务类型数据加载,支持递归查找三级分类 2. 修复任务类型显示为'未知类型'的问题(支持从层级数据中递归查找) 3. 修复任务数量全部显示为1的问题(从typeDetails中获取实际数量) 4. 将添加任务类型改为级联选择器(树形结构)
This commit is contained in:
parent
48afa392fc
commit
c7fbcb2b56
@ -1991,27 +1991,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加类型 -->
|
||||
<!-- 添加类型(使用级联选择器) -->
|
||||
<div class="add-type-row" style="margin-top: 12px; display: flex; gap: 8px;">
|
||||
<a-select
|
||||
v-model:value="newTaskTypeId"
|
||||
<a-cascader
|
||||
v-model:value="newTaskTypePath"
|
||||
:options="taskTypeCascaderOptions"
|
||||
placeholder="选择要添加的任务类型"
|
||||
style="flex: 1"
|
||||
allow-clear
|
||||
change-on-select
|
||||
:show-search="{ filter: cascaderFilter }"
|
||||
:dropdown-style="{ background: '#262626' }"
|
||||
>
|
||||
<a-select-option v-for="type in demandTypes" :key="type.id" :value="type.id">
|
||||
{{ type.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-button type="primary" ghost style="border-color: #31f08b; color: #31f08b;" @click="() => {
|
||||
if (newTaskTypeId && !approveTaskTypes.find(t => t.typeId === newTaskTypeId)) {
|
||||
approveTaskTypes.push({ typeId: newTaskTypeId, quantity: 1 })
|
||||
newTaskTypeId = undefined
|
||||
} else if (newTaskTypeId) {
|
||||
message.warning('该任务类型已添加')
|
||||
}
|
||||
}">
|
||||
/>
|
||||
<a-button type="primary" ghost style="border-color: #31f08b; color: #31f08b;" @click="handleAddApproveTaskType">
|
||||
<Icon name="plus" size="sm" style="margin-right: 4px" /> 添加
|
||||
</a-button>
|
||||
</div>
|
||||
@ -2364,6 +2356,7 @@ import DefaultLayout from '@/layouts/DefaultLayout.vue'
|
||||
import Icon from '@/components/Icon.vue'
|
||||
import * as taskApi from '@/api/task'
|
||||
import * as userApi from '@/api/user'
|
||||
import * as configApi from '@/api/config'
|
||||
import type { Task, TaskApprovalDTO, TaskProduct } from '@/api/task'
|
||||
import type { DesignerWithWorkload } from '@/api/user'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
@ -2485,6 +2478,38 @@ const brands = computed(() => configStore.brands)
|
||||
const platforms = computed(() => configStore.platforms)
|
||||
const categories = computed(() => configStore.categories)
|
||||
|
||||
// 层级任务类型数据(用于级联选择器)
|
||||
const hierarchicalTaskTypes = ref<any[]>([])
|
||||
|
||||
// 递归查找任务类型(从层级数据中查找,支持三级分类)
|
||||
const findTaskTypeById = (id: number, items: any[] = hierarchicalTaskTypes.value): any => {
|
||||
for (const item of items) {
|
||||
if (item.id === id) return item
|
||||
if (item.children) {
|
||||
const found = findTaskTypeById(id, item.children)
|
||||
if (found) return found
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// 构建级联选择器选项
|
||||
const taskTypeCascaderOptions = computed(() => {
|
||||
const buildOptions = (items: any[]): any[] => {
|
||||
return items.map(item => {
|
||||
const option: any = {
|
||||
value: item.id,
|
||||
label: item.name
|
||||
}
|
||||
if (item.children && item.children.length > 0) {
|
||||
option.children = buildOptions(item.children)
|
||||
}
|
||||
return option
|
||||
})
|
||||
}
|
||||
return buildOptions(hierarchicalTaskTypes.value)
|
||||
})
|
||||
|
||||
// 筛选条件
|
||||
const filters = reactive({
|
||||
taskTypeId: undefined as number | undefined,
|
||||
@ -2573,7 +2598,10 @@ const getTaskTypeName = (typeId: number, taskTypeName?: string, taskSubType?: st
|
||||
if (taskSubType) return taskSubType
|
||||
// 如果有直接传入的类型名称,使用它
|
||||
if (taskTypeName) return taskTypeName
|
||||
// 从需求类型列表中查找
|
||||
// 从层级数据中递归查找(支持三级分类)
|
||||
const typeInfo = findTaskTypeById(typeId)
|
||||
if (typeInfo) return typeInfo.name
|
||||
// 兼容:从平铺列表中查找
|
||||
const type = demandTypes.value.find(t => t.id === typeId)
|
||||
return type?.name || '未知类型'
|
||||
}
|
||||
@ -2592,6 +2620,10 @@ const parseTypeDetails = (typeDetails: string | TaskTypeDetail[] | undefined): T
|
||||
|
||||
// 获取任务类型单位积分
|
||||
const getTaskTypeUnitScore = (typeId: number) => {
|
||||
// 从层级数据中递归查找(支持三级分类)
|
||||
const typeInfo = findTaskTypeById(typeId)
|
||||
if (typeInfo && typeInfo.unitScore) return typeInfo.unitScore
|
||||
// 兼容:从平铺列表中查找
|
||||
const type = demandTypes.value.find(t => t.id === typeId)
|
||||
return type?.unitScore || 0
|
||||
}
|
||||
@ -2714,6 +2746,11 @@ const isHighScoreTask = (task: TaskOrSubTask) => {
|
||||
const loadConfigs = async () => {
|
||||
try {
|
||||
await configStore.loadAllConfigs()
|
||||
// 加载层级任务类型数据(用于级联选择器和递归查找)
|
||||
const response = await configApi.getDemandTypesTree()
|
||||
if (response && response.data) {
|
||||
hierarchicalTaskTypes.value = response.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载配置数据失败:', error)
|
||||
}
|
||||
@ -3024,7 +3061,30 @@ const approveAssignType = ref<'auto' | 'manual'>('auto')
|
||||
const approveTaskTypes = ref<Array<{typeId: number, quantity: number}>>([])
|
||||
const approveDesignerId = ref<number | undefined>(undefined)
|
||||
const designersList = ref<DesignerWithWorkload[]>([])
|
||||
const newTaskTypeId = ref<number | undefined>(undefined)
|
||||
const newTaskTypePath = ref<(string | number)[] | undefined>(undefined)
|
||||
|
||||
// 级联选择器搜索过滤
|
||||
const cascaderFilter = (inputValue: string, path: any[]) => {
|
||||
return path.some(option =>
|
||||
option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1
|
||||
)
|
||||
}
|
||||
|
||||
// 添加审核弹窗中的任务类型
|
||||
const handleAddApproveTaskType = () => {
|
||||
if (!newTaskTypePath.value || newTaskTypePath.value.length === 0) {
|
||||
message.warning('请选择任务类型')
|
||||
return
|
||||
}
|
||||
// 获取最后一个ID(即最深层级的类型ID)
|
||||
const typeId = newTaskTypePath.value[newTaskTypePath.value.length - 1] as number
|
||||
if (approveTaskTypes.value.find(t => t.typeId === typeId)) {
|
||||
message.warning('该任务类型已添加')
|
||||
return
|
||||
}
|
||||
approveTaskTypes.value.push({ typeId, quantity: 1 })
|
||||
newTaskTypePath.value = undefined
|
||||
}
|
||||
|
||||
// 格式化相对时间
|
||||
const formatDeadlineRelative = (deadline: string) => {
|
||||
@ -3067,17 +3127,34 @@ const showAssignDesignerModal = async (task: Task) => {
|
||||
approveTaskData.value = task
|
||||
approveAssignType.value = 'auto'
|
||||
approveDesignerId.value = undefined
|
||||
newTaskTypeId.value = undefined
|
||||
newTaskTypePath.value = undefined
|
||||
|
||||
// 解析任务类型
|
||||
const taskTypeIdsStr = task.taskTypeIds || task.taskTypeId?.toString() || ''
|
||||
const taskTypeIdArray = taskTypeIdsStr.split(',').filter(id => id.trim())
|
||||
// 解析任务类型 - 优先从 typeDetails 获取(包含每个类型的实际数量)
|
||||
let typeDetailsArray: TaskTypeDetail[] = []
|
||||
if ((task as any).typeDetails) {
|
||||
try {
|
||||
const details = (task as any).typeDetails
|
||||
typeDetailsArray = typeof details === 'string' ? JSON.parse(details) : details
|
||||
} catch (e) {
|
||||
console.warn('解析 typeDetails 失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化任务类型列表
|
||||
approveTaskTypes.value = taskTypeIdArray.map(id => ({
|
||||
typeId: parseInt(id.trim()),
|
||||
quantity: task.quantity || 1
|
||||
}))
|
||||
// 如果有 typeDetails,从中获取任务类型和数量
|
||||
if (typeDetailsArray.length > 0) {
|
||||
approveTaskTypes.value = typeDetailsArray.map(detail => ({
|
||||
typeId: detail.typeId,
|
||||
quantity: detail.quantity || 1
|
||||
}))
|
||||
} else {
|
||||
// 兼容旧数据:从 taskTypeIds 获取
|
||||
const taskTypeIdsStr = task.taskTypeIds || task.taskTypeId?.toString() || ''
|
||||
const taskTypeIdArray = taskTypeIdsStr.split(',').filter(id => id.trim())
|
||||
approveTaskTypes.value = taskTypeIdArray.map(id => ({
|
||||
typeId: parseInt(id.trim()),
|
||||
quantity: task.quantity || 1
|
||||
}))
|
||||
}
|
||||
|
||||
approveModalVisible.value = true
|
||||
} catch (error: any) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user