From a241730633bd04615b555bef95eb2d35363bb4dd Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 3 Jan 2026 11:53:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=A5=E5=8D=95=E9=83=A8=E9=97=A8?= =?UTF-8?q?=E8=B4=9F=E8=B4=A3=E4=BA=BA=E5=AE=A1=E6=A0=B8=E6=97=B6=E5=8F=AF?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E4=BB=BB=E5=8A=A1=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增功能: 1. 审核弹窗增加任务类型编辑区域 - 显示当前所有任务类型 - 每个类型可调整数量 - 可删除任务类型 - 可添加新的任务类型 - 自动从下拉列表选择(防重复) 2. 编辑界面优化 - 灰色背景区域突出显示 - 每个任务类型独立卡片 - 数量输入框(最小值1) - 红色删除按钮 - 绿色添加按钮 3. 数据提交 - 审核时携带taskUpdates参数 - 包含修改后的任务类型列表 - 后端自动重新计算总积分 - 支持流水线任务和普通任务 4. 后端支持(已有) - TaskApprovalService.applyTaskUpdates() - 自动更新taskTypeIds字段 - 重新计算totalScore - 记录审核日志 使用场景: - 接单部门负责人审核任务时 - 发现任务类型需要调整 - 直接在审核弹窗中编辑 - 编辑后再选择指派设计师或发布到大厅 --- frontend/src/views/TaskHall.vue | 119 +++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) 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)