From c3454123db8b9f8fdec58d819c57102164ee1019 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 3 Jan 2026 12:27:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=8C=87=E6=B4=BE?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=B8=88=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=B9?= =?UTF-8?q?=E7=94=A8Select=E4=B8=8B=E6=8B=89=E6=A1=86=E5=B9=B6=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=B7=A5=E4=BD=9C=E9=87=8F=E5=92=8C=E9=A2=84=E8=AE=A1?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题修复: ✅ 修复指派设计师按钮点击无效的问题 ✅ 将Radio组改为Select下拉框,体验更好 功能优化: 1. 后端增强 (UserService.java) ✅ 新增返回设计师最早预计完成时间 (earliestDeadline) ✅ 查询该设计师进行中任务的最早deadline ✅ 便于负责人评估设计师工作量 2. 前端界面优化 (TaskHall.vue) ✅ 将RadioGroup改为Select下拉框 ✅ 下拉框尺寸改为large,更易操作 ✅ 显示设计师姓名 ✅ 显示进行中任务数量 ✅ 显示预计最早完成时间(相对时间) ✅ 根据工作量显示不同颜色: - 0个任务:绿色 "空闲" - 1-3个:绿色 "进行中: X个" - 4-5个:橙色 "进行中: X个" - 6+个:红色 "进行中: X个" 3. 时间显示格式 ✅ 相对时间显示(例如:2天8小时后) ✅ 24小时内显示小时数 ✅ 已逾期显示为"已逾期" 4. 下拉框选项样式 ✅ 双栏布局:左侧姓名,右侧工作信息 ✅ 工作量和完成时间用 | 分隔 ✅ 信息一目了然 使用示例: - 选择"指定设计师接单" - 点击下拉框 - 看到:张三 | 进行中: 2个 | 最早完成: 1天5小时后 - 方便评估后选择最合适的设计师 --- .../com/designhub/service/UserService.java | 17 ++++ frontend/src/api/user.ts | 1 + frontend/src/views/TaskHall.vue | 84 +++++++++++++------ 3 files changed, 77 insertions(+), 25 deletions(-) diff --git a/backend/src/main/java/com/designhub/service/UserService.java b/backend/src/main/java/com/designhub/service/UserService.java index 98a5e59..1fc05fd 100644 --- a/backend/src/main/java/com/designhub/service/UserService.java +++ b/backend/src/main/java/com/designhub/service/UserService.java @@ -1256,6 +1256,23 @@ public class UserService { } } + // 获取最早预计完成时间(查询该设计师进行中任务的最早deadline) + if (taskMapper != null && inProgressCount > 0) { + // 查询普通任务的最早deadline + LambdaQueryWrapper taskQuery = new LambdaQueryWrapper<>(); + taskQuery.eq(com.designhub.entity.Task::getReceiverId, user.getId()) + .eq(com.designhub.entity.Task::getStatus, "in_progress") + .eq(com.designhub.entity.Task::getDeleted, 0) + .isNotNull(com.designhub.entity.Task::getDeadline) + .orderByAsc(com.designhub.entity.Task::getDeadline) + .last("LIMIT 1"); + + com.designhub.entity.Task earliestTask = taskMapper.selectOne(taskQuery); + if (earliestTask != null && earliestTask.getDeadline() != null) { + designerInfo.put("earliestDeadline", earliestTask.getDeadline()); + } + } + result.add(designerInfo); } diff --git a/frontend/src/api/user.ts b/frontend/src/api/user.ts index 0fd4334..da60e78 100644 --- a/frontend/src/api/user.ts +++ b/frontend/src/api/user.ts @@ -150,6 +150,7 @@ export interface DesignerWithWorkload { deptId?: number; deptName?: string; inProgressCount: number; // 进行中的任务数量 + earliestDeadline?: string; // 最早预计完成时间 } /** diff --git a/frontend/src/views/TaskHall.vue b/frontend/src/views/TaskHall.vue index dd2b550..b57b4d2 100644 --- a/frontend/src/views/TaskHall.vue +++ b/frontend/src/views/TaskHall.vue @@ -2753,33 +2753,67 @@ const showAssignDesignerModal = async (task: Task) => { color: '#262626' } }, '选择设计师'), - h(RadioGroup, { + h(Select, { value: selectedDesignerId, - onChange: (e: any) => { - selectedDesignerId = e.target.value + placeholder: '请选择要指派的设计师', + style: { width: '100%' }, + size: 'large', + onChange: (val: number) => { + selectedDesignerId = val }, - style: { width: '100%' } - }, designers.map(designer => - h(Radio, { - value: designer.id, - style: { - display: 'flex', - alignItems: 'center', - marginBottom: '10px', - padding: '12px', - border: '1px solid #e8e8e8', - borderRadius: '6px', - background: selectedDesignerId === designer.id ? '#e6f7ff' : 'white', - transition: 'all 0.3s' - } - }, [ - h('span', { style: { flex: 1, fontSize: '14px', fontWeight: 500 } }, designer.realName), - h(Tag, { - color: designer.inProgressCount > 5 ? 'error' : - designer.inProgressCount > 3 ? 'warning' : 'success' - }, `进行中: ${designer.inProgressCount}`) - ]) - )) + options: designers.map(designer => { + const formatDeadline = (deadline: string) => { + if (!deadline) return '' + try { + const date = new Date(deadline) + const now = new Date() + const diff = date.getTime() - now.getTime() + const days = Math.floor(diff / (1000 * 60 * 60 * 24)) + const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) + + if (diff < 0) return '已逾期' + if (days === 0) return `${hours}小时后` + return `${days}天${hours}小时后` + } catch { + return '' + } + } + + const workloadColor = designer.inProgressCount > 5 ? '#ff4d4f' : + designer.inProgressCount > 3 ? '#faad14' : '#52c41a' + const workloadText = designer.inProgressCount === 0 ? '空闲' : + `进行中: ${designer.inProgressCount}个` + const deadlineText = designer.earliestDeadline ? + ` | 最早完成: ${formatDeadline(designer.earliestDeadline)}` : '' + + return { + value: designer.id, + label: h('div', { + style: { + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + padding: '4px 0' + } + }, [ + h('span', { + style: { + fontSize: '14px', + fontWeight: 500, + flex: 1 + } + }, designer.realName), + h('span', { + style: { + fontSize: '12px', + color: workloadColor, + marginLeft: '12px' + } + }, `${workloadText}${deadlineText}`) + ]) + } + }) + }) ]) ])