From 703c110bffd5cb996abeef5629e928661c8b5f37 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 15 Jan 2026 19:07:04 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=AF=8F=E6=97=A5?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E5=BC=B9=E7=AA=97=E6=97=A0=E6=B3=95=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E9=97=AE=E9=A2=98=EF=BC=8C=E6=B7=BB=E5=8A=A0=E7=A8=8D?= =?UTF-8?q?=E5=90=8E=E6=8F=90=E9=86=92=E6=8C=89=E9=92=AE=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=BF=9B=E5=BA=A6=E9=AA=8C=E8=AF=81=E9=80=BB=E8=BE=91?= =?UTF-8?q?;=20fix:=20=E8=AE=BE=E8=AE=A1=E5=B8=88=E5=87=86=E6=97=B6?= =?UTF-8?q?=E7=8E=87=E8=AE=A1=E7=AE=97=E5=8C=85=E5=90=AB=E5=AD=90=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designhub/service/AnalyticsService.java | 19 ++++++- .../src/components/DailyProgressReminder.vue | 55 ++++++++++++++++--- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/backend/src/main/java/com/designhub/service/AnalyticsService.java b/backend/src/main/java/com/designhub/service/AnalyticsService.java index 1a04981..91cc507 100644 --- a/backend/src/main/java/com/designhub/service/AnalyticsService.java +++ b/backend/src/main/java/com/designhub/service/AnalyticsService.java @@ -630,12 +630,13 @@ public class AnalyticsService { int completedCount = mainCompletedCount + subCompletedCount; int inProgressCount = mainInProgressCount + subInProgressCount; - // 计算准时完成数 + // 计算准时完成数(主任务 + 子任务) int onTimeCount = 0; int overdueCount = 0; double totalTime = 0; int timeCount = 0; + // 主任务准时率计算 for (Task task : designerTasks) { if ("completed".equals(task.getStatus()) && task.getActualEndTime() != null) { LocalDateTime start = task.getActualStartTime() != null ? task.getActualStartTime() : task.getStartTime(); @@ -658,6 +659,22 @@ public class AnalyticsService { } } + // 子任务准时率计算 + for (TaskItem item : designerTaskItems) { + if ("completed".equals(item.getStatus()) && item.getCompleteTime() != null) { + // 判断是否准时 + if (item.getDeadline() != null) { + if (!item.getCompleteTime().isAfter(item.getDeadline())) { + onTimeCount++; + } else { + overdueCount++; + } + } else { + onTimeCount++; // 没有deadline的默认准时 + } + } + } + double completionRate = receivedCount > 0 ? (double) completedCount / receivedCount * 100 : 0; double onTimeRate = completedCount > 0 ? (double) onTimeCount / completedCount * 100 : 0; double avgProcessTime = timeCount > 0 ? totalTime / timeCount : 0; diff --git a/frontend/src/components/DailyProgressReminder.vue b/frontend/src/components/DailyProgressReminder.vue index 6fcb24e..7eaf9f8 100644 --- a/frontend/src/components/DailyProgressReminder.vue +++ b/frontend/src/components/DailyProgressReminder.vue @@ -2,18 +2,22 @@ @@ -239,14 +243,21 @@ const handleNoTasksConfirm = () => { message.success('确认成功') } +// 关闭弹窗 +const handleClose = () => { + visible.value = false +} + +// 稍后提醒(跳过本次) +const handleSkip = () => { + visible.value = false + message.info('已跳过,下次登录时将再次提醒') +} + // 提交所有任务进度 const handleSubmit = async () => { - // 验证:所有任务进度必须有更新 + // 验证:新进度不能小于当前进度 const hasError = tasks.value.some(task => { - if (task.newProgress === task.progress) { - task.error = '进度未更新,请调整进度' - return true - } if (task.newProgress < (task.progress || 0)) { task.error = '新进度不能小于当前进度' return true @@ -259,17 +270,29 @@ const handleSubmit = async () => { message.warning('请检查所有任务进度') return } + + // 过滤出有更新的任务 + const updatedTasks = tasks.value.filter(task => task.newProgress !== task.progress) submitting.value = true try { - // 批量更新进度 - const updates = tasks.value.map(task => ({ + // 批量更新进度(只更新有变化的任务) + const updates = updatedTasks.map(task => ({ taskId: task.id, progress: task.newProgress, remark: task.progressRemark })) + // 如果没有任何更新,直接关闭 + if (updates.length === 0) { + const today = dayjs().format('YYYY-MM-DD') + localStorage.setItem('lastProgressUpdateDate', today) + message.success('已确认今日进度') + visible.value = false + return + } + const response = await taskApi.batchUpdateProgress(updates) if (response.code === 200) { @@ -302,6 +325,7 @@ defineExpose({ display: flex; align-items: center; gap: 10px; + width: 100%; .title-icon { font-size: 20px; @@ -311,6 +335,19 @@ defineExpose({ font-size: 18px; font-weight: 600; color: $text-primary; + flex: 1; + } + + .skip-btn { + color: $text-tertiary; + font-size: 13px; + height: auto; + padding: 4px 12px; + + &:hover { + color: $text-secondary; + background: rgba(255, 255, 255, 0.05); + } } }