diff --git a/frontend/src/views/TaskHall.vue b/frontend/src/views/TaskHall.vue index b5da372..f5b31d9 100644 --- a/frontend/src/views/TaskHall.vue +++ b/frontend/src/views/TaskHall.vue @@ -2559,8 +2559,112 @@ const showAssignDesignerModal = async (task: Task) => { let assignType = 'auto' // 'auto' 或 'manual' let selectedDesignerId: number | null = null + + // 解析任务类型 + const taskTypeIdsStr = task.taskTypeIds || task.taskTypeId?.toString() || '' + const taskTypeIdArray = taskTypeIdsStr.split(',').filter(id => id.trim()) + + // 初始化任务类型列表(带数量) + let editableTaskTypes = taskTypeIdArray.map(id => ({ + typeId: parseInt(id.trim()), + quantity: task.quantity || 1 + })) const modalContent = h('div', { style: 'padding: 10px 0;' }, [ + // 任务类型编辑区域 + h('div', { style: 'marginBottom: 24px; padding: 16px; background: #f5f5f5; borderRadius: 8px;' }, [ + h('h4', { style: 'marginBottom: 12px; fontSize: 14px; fontWeight: 600;' }, '📝 编辑任务类型'), + h('div', { style: 'marginBottom: 12px;' }, [ + ...editableTaskTypes.map((item, index) => + h('div', { + key: index, + style: { + display: 'flex', + alignItems: 'center', + marginBottom: '8px', + padding: '8px', + background: 'white', + borderRadius: '4px', + border: '1px solid #d9d9d9' + } + }, [ + h('span', { style: { flex: 1, fontSize: 13 } }, + getTaskTypeName(item.typeId) + ), + h('span', { style: { marginRight: 8, fontSize: 12, color: '#666' } }, '数量:'), + h('input', { + type: 'number', + value: item.quantity, + min: 1, + style: { + width: '60px', + padding: '4px 8px', + border: '1px solid #d9d9d9', + borderRadius: '4px', + marginRight: '8px' + }, + onInput: (e: any) => { + item.quantity = parseInt(e.target.value) || 1 + } + }), + h('button', { + style: { + padding: '4px 12px', + background: '#ff4d4f', + color: 'white', + border: 'none', + borderRadius: '4px', + cursor: 'pointer', + fontSize: 12 + }, + onClick: () => { + editableTaskTypes.splice(index, 1) + } + }, '删除') + ]) + ) + ]), + h('div', { style: 'display: flex; gap: 8px;' }, [ + h('select', { + id: 'newTaskTypeSelect', + style: { + flex: 1, + padding: '6px 12px', + border: '1px solid #d9d9d9', + borderRadius: '4px', + fontSize: 13 + } + }, [ + h('option', { value: '' }, '-- 选择要添加的任务类型 --'), + ...demandTypes.value.map((type: any) => + h('option', { value: type.id }, type.name) + ) + ]), + h('button', { + style: { + padding: '6px 16px', + background: '#52c41a', + color: 'white', + border: 'none', + borderRadius: '4px', + cursor: 'pointer', + fontSize: 13 + }, + onClick: () => { + const selectEl = document.getElementById('newTaskTypeSelect') as HTMLSelectElement + const typeId = parseInt(selectEl.value) + if (typeId && !editableTaskTypes.find(t => t.typeId === typeId)) { + editableTaskTypes.push({ typeId, quantity: 1 }) + } else if (typeId) { + message.warning('该任务类型已添加') + } + } + }, '+ 添加类型') + ]) + ]), + + // 选择接单方式 + h('p', { style: 'margin-bottom: 16px; color: #666;' }, h('p', { style: 'margin-bottom: 16px; color: #666;' }, '选择任务接单方式:' ), @@ -2636,10 +2740,23 @@ const showAssignDesignerModal = async (task: Task) => { return Promise.reject() } + // 检查任务类型是否为空 + if (editableTaskTypes.length === 0) { + message.error('至少需要一个任务类型') + return Promise.reject() + } + + // 准备任务类型更新数据 const approvalData: TaskApprovalDTO = { comment: assignType === 'manual' ? `指定设计师接单` : '审核通过,发布到任务大厅', - assignedReceiverId: assignType === 'manual' && selectedDesignerId ? selectedDesignerId : undefined + assignedReceiverId: assignType === 'manual' && selectedDesignerId ? selectedDesignerId : undefined, + taskUpdates: { + taskTypes: editableTaskTypes.map(t => ({ + taskTypeId: t.typeId, + quantity: t.quantity + })) + } } await taskApi.approveReceivingLevel(task.id!, approvalData)