Explorar o código

feat(tasks): 首页任务超期显示——有执行时间的任务过 latestEnd 后显示已超期徽章

- 后端 TaskService.getTodayTasks:过滤 latestEnd 已过期且 status=pending 的任务,避免幽灵任务
- 前端 index-home:pending 任务若 latestEnd 已过期则打 _isOverdue 标记,模板展示已超期徽章(替代完成按钮)
Sisyphus Agent hai 4 días
pai
achega
875d750b63

+ 3 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/TaskService.java

@@ -379,6 +379,9 @@ public List<Task> getTodayTasks(Long memberId, String dimensionCode) {
 
         SortUtil.applySort(wrapper);
         List<Task> all = taskMapper.selectList(wrapper);
+        // 过滤掉 latestEnd 已过期的任务(有执行时间窗口的任务:过了结束时间不再显示为待完成)
+        Date now = new Date();
+        all.removeIf(t -> t.getLatestEnd() != null && t.getLatestEnd().before(now) && "pending".equals(t.getStatus()));
         fillProgress(all, memberId);
         return filterLockedChildren(all);
     }

+ 34 - 3
cfc-frontend/pages/index-home/index.vue

@@ -152,12 +152,15 @@
           v-for="task in pendingTasks"
           :key="task.id"
           class="task-quick-item"
+          :class="{ 'task-quick-item--overdue': task._isOverdue }"
         >
           <view class="task-quick-info">
             <text class="task-quick-title line-clamp-1">{{ task.title }}</text>
-            <text class="task-quick-meta">+{{ task.points }}CF</text>
+            <text class="task-quick-meta" v-if="!task._isOverdue">+{{ task.points }}CF</text>
+            <text class="task-quick-meta task-quick-meta--overdue" v-else>已超期</text>
           </view>
-          <button class="btn-quick-complete" @click="quickCompleteTask(task)">完成</button>
+          <button v-if="!task._isOverdue" class="btn-quick-complete" @click="quickCompleteTask(task)">完成</button>
+          <view v-else class="status-badge-overdue">⏰ 已超期</view>
         </view>
       </view>
     </view>
@@ -1108,7 +1111,15 @@ title: '添加家庭成员',
       getTodayTasks().then(function(res) {
         if (res.code === 200 && Array.isArray(res.data)) {
           self.pendingTasks = res.data.filter(function(t) {
-            return t.status === 'pending'
+            if (t.status !== 'pending') return false
+            // 有 latestEnd 的任务:latestEnd 已过后前端标记为超期,不再显示「完成」按钮
+            if (t.latestEnd) {
+              var d = self.parseDate(t.latestEnd)
+              if (d && d < new Date()) {
+                t._isOverdue = true
+              }
+            }
+            return true
           })
         }
       }).catch(function() {
@@ -2925,6 +2936,26 @@ $c-warm-tint:     #FFF3E7;
   border: none;
 }
 
+/* ===== 超期任务样式 ===== */
+.task-quick-item--overdue .task-quick-meta--overdue {
+  color: #ff4d4f;
+  font-weight: bold;
+}
+.status-badge-overdue {
+  margin-left: 16rpx;
+  padding: 8rpx 20rpx;
+  background: rgba(255,77,79,0.1);
+  color: #ff4d4f;
+  font-size: 24rpx;
+  font-weight: bold;
+  border-radius: 20rpx;
+  flex-shrink: 0;
+  line-height: 1;
+  height: 44rpx;
+  display: flex;
+  align-items: center;
+}
+
 /* ===== 家庭挑战空态 ===== */
 .challenge-empty {
   display: flex;