From 81cb6b3eed62ec4af43101d2fb5643200548bba4 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 8 Jan 2026 11:59:27 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=AE=BE=E8=AE=A1=E5=B8=88=E7=BB=A9?= =?UTF-8?q?=E6=95=88=E6=8E=92=E8=A1=8C=E6=A6=9C=E6=A8=AA=E5=90=91=E6=8B=89?= =?UTF-8?q?=E6=BB=A1=EF=BC=8C=E4=BF=AE=E5=A4=8D=E7=A7=AF=E5=88=86=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=EF=BC=8C=E4=BC=98=E5=8C=96=E8=A1=A8=E6=A0=BC=E6=B7=B1?= =?UTF-8?q?=E8=89=B2=E6=A0=B7=E5=BC=8F=EF=BC=8C=E7=99=BD=E8=89=B2=E6=98=9F?= =?UTF-8?q?=E6=98=9F=E8=AF=84=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designhub/service/AnalyticsService.java | 18 +- .../service/TaskApprovalService.java | 44 ++--- frontend/src/views/Analytics.vue | 181 ++++++++++++++---- frontend/src/views/CreateTask.vue | 70 +++---- frontend/src/views/TaskHall.vue | 8 +- 5 files changed, 206 insertions(+), 115 deletions(-) diff --git a/backend/src/main/java/com/designhub/service/AnalyticsService.java b/backend/src/main/java/com/designhub/service/AnalyticsService.java index 3a2acb4..bd4a2d6 100644 --- a/backend/src/main/java/com/designhub/service/AnalyticsService.java +++ b/backend/src/main/java/com/designhub/service/AnalyticsService.java @@ -676,12 +676,18 @@ public class AnalyticsService { log.warn("获取评价数据失败: {}", e.getMessage()); } - // 计算获得积分 - BigDecimal totalScore = designerTasks.stream() - .filter(t -> "completed".equals(t.getStatus())) - .map(Task::getScoreReward) - .filter(Objects::nonNull) - .reduce(BigDecimal.ZERO, BigDecimal::add); + // 计算获得积分(使用 score 字段,score_reward 可能未设置) + BigDecimal totalScore = BigDecimal.ZERO; + for (Task task : designerTasks) { + if ("completed".equals(task.getStatus())) { + // 优先使用 scoreReward,如果为空或0则使用 score + if (task.getScoreReward() != null && task.getScoreReward().compareTo(BigDecimal.ZERO) > 0) { + totalScore = totalScore.add(task.getScoreReward()); + } else if (task.getScore() != null) { + totalScore = totalScore.add(BigDecimal.valueOf(task.getScore())); + } + } + } // 本周完成数 int weekCompletedCount = (int) designerTasks.stream() diff --git a/backend/src/main/java/com/designhub/service/TaskApprovalService.java b/backend/src/main/java/com/designhub/service/TaskApprovalService.java index fbcc292..24b8a6e 100644 --- a/backend/src/main/java/com/designhub/service/TaskApprovalService.java +++ b/backend/src/main/java/com/designhub/service/TaskApprovalService.java @@ -63,24 +63,24 @@ public class TaskApprovalService { String releaseType = task.getReleaseType(); // 确定接单部门负责人 - Long receivingLeaderId = determineReceivingLeader(task); - if (receivingLeaderId == null) { - throw new BusinessException(ResultCode.PARAM_ERROR, "无法确定接单部门负责人,请在系统设置中为接单部门配置负责人"); - } + Long receivingLeaderId = determineReceivingLeader(task); + if (receivingLeaderId == null) { + throw new BusinessException(ResultCode.PARAM_ERROR, "无法确定接单部门负责人,请在系统设置中为接单部门配置负责人"); + } - // 更新任务状态为待接单部门审核 - task.setApprovalStatus("pending_receiving_approval"); - task.setDemandApprovalTime(LocalDateTime.now()); - task.setCurrentApproverId(receivingLeaderId); - task.setCurrentApproverRole("receiving_leader"); - taskMapper.updateById(task); + // 更新任务状态为待接单部门审核 + task.setApprovalStatus("pending_receiving_approval"); + task.setDemandApprovalTime(LocalDateTime.now()); + task.setCurrentApproverId(receivingLeaderId); + task.setCurrentApproverRole("receiving_leader"); + taskMapper.updateById(task); - // 记录审核日志 - logApproval(taskId, approverId, 1, "approve", dto.getComment()); + // 记录审核日志 + logApproval(taskId, approverId, 1, "approve", dto.getComment()); - // 发送通知给接单部门负责人 - User receivingLeader = userMapper.selectById(receivingLeaderId); - if (receivingLeader != null) { + // 发送通知给接单部门负责人 + User receivingLeader = userMapper.selectById(receivingLeaderId); + if (receivingLeader != null) { // 根据是否预先指定了设计师,调整通知内容 String notificationContent; if ("assigned".equals(releaseType) && task.getReceiverId() != null) { @@ -90,14 +90,14 @@ public class TaskApprovalService { } else { notificationContent = String.format("任务【%s】需要您审核并分配设计师", task.getTitle()); } - notificationService.sendNotification( - receivingLeaderId, - "新任务待审核", + notificationService.sendNotification( + receivingLeaderId, + "新任务待审核", notificationContent, - "task_approval", - taskId - ); - } + "task_approval", + taskId + ); + } log.info("需求部门负责人审核通过,任务ID:{},审核人:{},发布类型:{},等待接单部门负责人审核", taskId, approverId, releaseType); } diff --git a/frontend/src/views/Analytics.vue b/frontend/src/views/Analytics.vue index d113913..33513a7 100644 --- a/frontend/src/views/Analytics.vue +++ b/frontend/src/views/Analytics.vue @@ -197,42 +197,43 @@ - - -
-

设计师绩效排行榜

- - - -
-
- -
-

工作负载分布

-
-
-
-
+ +
+

设计师绩效排行榜

+ + + +
+ + +
+

工作负载分布

+
+
@@ -1342,10 +1343,116 @@ onMounted(() => { :deep(.ant-rate) { font-size: 14px; - color: rgba(255, 255, 255, 0.1); + color: rgba(255, 255, 255, 0.15); .ant-rate-star-full .ant-rate-star-second { color: #FFD700 !important; } } + +// 白色星星评分样式 +.white-rate { + :deep(.ant-rate-star) { + color: rgba(255, 255, 255, 0.2) !important; + + &.ant-rate-star-full, + &.ant-rate-star-half { + .ant-rate-star-second { + color: #ffffff !important; + } + } + } +} + +// 积分显示样式 +.score-value { + font-weight: 600; + color: $brand-primary; + font-size: 14px; +} + +// 全宽卡片 +.full-width { + width: 100%; +} + +// 深色表格样式覆盖 - 防止闪白 +.dark-table { + :deep(.ant-table) { + background: transparent !important; + + .ant-table-thead > tr > th { + background: rgba(0, 0, 0, 0.2) !important; + border-bottom: 1px solid rgba(255, 255, 255, 0.05) !important; + color: rgba(255, 255, 255, 0.65) !important; + font-weight: 500; + padding: 14px 16px; + } + + .ant-table-tbody > tr { + background: transparent !important; + + > td { + background: transparent !important; + border-bottom: 1px solid rgba(255, 255, 255, 0.03) !important; + padding: 14px 16px; + color: rgba(255, 255, 255, 0.85); + transition: none !important; + } + + &:hover > td { + background: rgba(49, 240, 139, 0.05) !important; + } + } + + // 分页器深色样式 + .ant-pagination { + .ant-pagination-item { + background: transparent; + border-color: rgba(255, 255, 255, 0.1); + + a { + color: rgba(255, 255, 255, 0.65); + } + + &:hover, &-active { + border-color: $brand-primary; + + a { + color: $brand-primary; + } + } + } + + .ant-pagination-prev, .ant-pagination-next { + .ant-pagination-item-link { + background: transparent; + border-color: rgba(255, 255, 255, 0.1); + color: rgba(255, 255, 255, 0.65); + } + + &:hover .ant-pagination-item-link { + border-color: $brand-primary; + color: $brand-primary; + } + } + + .ant-pagination-options { + .ant-select-selector { + background: rgba(0, 0, 0, 0.2) !important; + border-color: rgba(255, 255, 255, 0.1) !important; + } + } + } + + // 排序图标 + .ant-table-column-sorter { + color: rgba(255, 255, 255, 0.45); + + &-up.active, &-down.active { + color: $brand-primary; + } + } + } +} diff --git a/frontend/src/views/CreateTask.vue b/frontend/src/views/CreateTask.vue index a2af41c..0131291 100644 --- a/frontend/src/views/CreateTask.vue +++ b/frontend/src/views/CreateTask.vue @@ -621,8 +621,8 @@ interface CascaderOption { estimatedHours?: number } -// 设计师列表缓存 { cacheKey: designers[] } -const designersCache = reactive>({}) +// 设计师列表缓存 { deptId: designers[] } +const designersCache = reactive>({}) // 表单数据 const formData = reactive({ @@ -853,22 +853,27 @@ const findTaskTypeById = (id: number, items: any[] = hierarchicalTaskTypes.value return null } -// 加载设计师列表(根据任务类型配置的接单部门获取设计师及工作量) +// 加载设计师列表 const loadDesignersForItem = async (item: TaskTypeItem) => { if (!item.taskTypeId) return - // 使用 taskTypeId 作为缓存key - const cacheKey = `type_${item.taskTypeId}` + const typeInfo = getTaskTypeInfo(item.taskTypeId) + if (!typeInfo || !typeInfo.allowedDeptIds) return - if (!designersCache[cacheKey]) { + // 简化处理:取第一个允许的部门ID + const deptIds = typeInfo.allowedDeptIds.split(',') + if (deptIds.length === 0) return + + const deptId = Number(deptIds[0]) + + if (!designersCache[deptId]) { try { - // 传入 taskTypeId,后端会根据任务类型配置的接单部门获取设计师 - const designers = await userApi.getDesignersWithWorkload(undefined, item.taskTypeId) - designersCache[cacheKey] = designers || [] - console.log(`加载任务类型 ${item.taskTypeId} 的设计师列表:`, designers?.length || 0, '人') + const res = await userApi.getDesignersWithWorkload(deptId) + if (res.code === 200) { + designersCache[deptId] = res.data + } } catch (error) { console.error('加载设计师失败:', error) - designersCache[cacheKey] = [] } } } @@ -877,8 +882,14 @@ const loadDesignersForItem = async (item: TaskTypeItem) => { const getDesignersForItem = (item: TaskTypeItem) => { if (!item.taskTypeId) return [] - const cacheKey = `type_${item.taskTypeId}` - return designersCache[cacheKey] || [] + const typeInfo = getTaskTypeInfo(item.taskTypeId) + if (!typeInfo || !typeInfo.allowedDeptIds) return [] + + const deptIds = typeInfo.allowedDeptIds.split(',') + if (deptIds.length === 0) return [] + + const deptId = Number(deptIds[0]) + return designersCache[deptId] || [] } // 添加任务类型 @@ -951,39 +962,6 @@ watch( } ) -// 监听发布类型变化,当切换到"指定任务"模式时,自动加载设计师列表 -watch( - () => formData.releaseType, - async (newValue) => { - if (newValue === 'assigned') { - // 为所有已选择任务类型的项加载设计师列表 - for (const item of formData.taskTypes) { - if (item.taskTypeId) { - await loadDesignersForItem(item) - } - } - } - } -) - -// 监听任务类型选择变化,当在"指定任务"模式下选择新任务类型时,自动加载设计师 -watch( - () => formData.taskTypes.map(item => item.taskTypeId), - async (newIds, oldIds) => { - if (formData.releaseType === 'assigned') { - // 找出新增或变化的任务类型 - for (let i = 0; i < newIds.length; i++) { - const newId = newIds[i] - const oldId = oldIds?.[i] - if (newId && newId !== oldId) { - await loadDesignersForItem(formData.taskTypes[i]) - } - } - } - }, - { deep: true } -) - // 计算预估积分(累加所有任务类型) const estimatedScore = computed(() => { let totalScore = 0 diff --git a/frontend/src/views/TaskHall.vue b/frontend/src/views/TaskHall.vue index 8757fc7..7f3340c 100644 --- a/frontend/src/views/TaskHall.vue +++ b/frontend/src/views/TaskHall.vue @@ -3150,8 +3150,8 @@ const showAssignDesignerModal = async (task: Task) => { console.log('任务已预先指定设计师:', preAssignedDesignerName.value) } else { // 未预先指定,重置状态 - approveAssignType.value = 'auto' - approveDesignerId.value = undefined + approveAssignType.value = 'auto' + approveDesignerId.value = undefined preAssignedDesignerName.value = '' } @@ -3773,8 +3773,8 @@ const loadInProgressTasks = async () => { // 处理子任务 if (itemResponse.data && itemResponse.data.records) { const items = itemResponse.data.records.map((item: any) => mapTaskItemToTask(item)) - allTasks = [...allTasks, ...items] - totalCount += itemResponse.data.total || 0 + allTasks = [...allTasks, ...items] + totalCount += itemResponse.data.total || 0 } // 处理直接分配的普通任务(排除流水线任务,因为流水线任务由子任务显示)