feat: 统一部门负责人和部门成员的任务卡片显示,确保都包含完整的子任务信息

This commit is contained in:
Your Name 2026-01-13 16:20:35 +08:00
parent 744ac08a91
commit c01d915539
2 changed files with 85 additions and 52 deletions

View File

@ -612,6 +612,8 @@ public class TaskService {
// 填充关联信息
for (Task task : result.getRecords()) {
fillTaskRelatedInfo(task);
// 填充子任务统计信息(与getMyPublishedTasks保持一致)
fillSubTaskStats(task);
}
return result;

View File

@ -902,27 +902,35 @@
<div
v-for="task in inProgressTaskList"
:key="task.id"
class="task-card chart-card in-progress"
class="task-card chart-card"
:class="[`status-${task.status}`]"
@click="handleTaskClick(task)"
style="cursor: pointer;"
>
<!-- 任务标题 -->
<div class="task-header">
<h3 class="task-title">{{ task.title }}</h3>
<div class="task-badges">
<span v-if="task.isSubTask" class="badge badge-subtask">
<Icon name="layers" size="sm" color="#31f08b" style="margin-right: 4px; vertical-align: middle;" />
子任务
<span :class="['badge', getTaskStatusClass(task)]">
{{ getTaskStatusText(task.status, task) }}
</span>
<span v-if="task.releaseType === 'assigned'" class="badge badge-assigned">
<Icon name="target" size="sm" color="#31f08b" style="margin-right: 4px; vertical-align: middle;" />
指定
</span>
<span class="badge badge-in-progress">
<Icon name="clock" size="sm" color="#31f08b" style="margin-right: 4px; vertical-align: middle;" />
进行中
<span v-if="task.isUrgent" class="badge badge-urgent">
<Icon name="fire" size="sm" color="#ff4d4f" style="margin-right: 4px; vertical-align: middle;" />
紧急
</span>
</div>
</div>
<!-- 驳回原因显示 -->
<div v-if="task.approvalStatus?.includes('rejected') && task.rejectReason" class="reject-info">
<span class="reject-label">驳回原因:</span>
<span class="reject-reason">{{ task.rejectReason }}</span>
</div>
<!-- 流程阶段 -->
<div v-if="getProcessStage(task)" class="process-stage">
<span class="stage-icon">
@ -939,8 +947,8 @@
<span class="value">{{ getTaskTypeName(task.taskTypeId, task.taskTypeName, task.taskSubType) }}</span>
</div>
<div class="info-item">
<span class="label">预估积分</span>
<span class="value text-brand">{{ task.totalScore || task.score }} 分</span>
<span class="label">积分</span>
<span class="value text-brand">{{ task.score }} 分</span>
</div>
<div class="info-item">
<span class="label">数量</span>
@ -956,13 +964,28 @@
</div>
</div>
<!-- 任务类型明细 -->
<div v-if="parseTypeDetails(task.typeDetails).length > 0" class="type-details-section">
<div class="type-details-title">任务类型明细</div>
<div class="type-details-list">
<div v-for="(detail, idx) in parseTypeDetails(task.typeDetails)" :key="idx" class="type-detail-item">
<span class="type-name">└ {{ detail.typeName }}</span>
<span class="type-score">x{{ detail.quantity }} = {{ detail.totalScore }}分</span>
<!-- 子任务进度时间线(流水线任务)- 横向拉满 -->
<div v-if="task.isPipeline === 1 && task.subTaskTotal" class="subtask-timeline-wrapper full-width">
<div class="subtask-timeline">
<div
v-for="(subTask, index) in (task.subTasks || []).slice(0, 5)"
:key="subTask.id || index"
class="timeline-node"
:class="getSubTaskStatusClass(subTask.status)"
>
<div class="node-dot"></div>
<div class="node-label">{{ getSubTaskLabel(subTask, index) }}</div>
<div class="node-status">{{ getSubTaskStatusText(subTask.status) }}</div>
</div>
<!-- 显示更多子任务提示 -->
<div v-if="(task.subTasks || []).length > 5" class="timeline-node more">
<div class="node-dot"></div>
<div class="node-label">+{{ (task.subTasks || []).length - 5 }}</div>
</div>
<!-- 完结节点 -->
<div class="timeline-node final" :class="{ completed: task.status === 'completed' }">
<div class="node-dot"></div>
<div class="node-label">完结</div>
</div>
</div>
</div>
@ -973,13 +996,27 @@
<span class="icon">
<Icon name="user" size="sm" color="#31f08b" />
</span>
<span>发起人: {{ task.publisherName || '--' }}</span>
</div>
<div class="detail-item">
<span class="icon">
<Icon name="user" size="sm" color="#31f08b" />
<span>
处理人: {{ task.receiverName || '待接单' }}
<span
v-if="task.isPipeline === 1 && task.subTasks && task.subTasks.length > 0 && task.id"
class="expand-subtasks"
@click.stop="toggleTaskSubtasks(task.id!)"
>
<Icon :name="expandedTaskSubtasks[task.id!] ? 'arrowUp' : 'arrowDown'" size="xs" style="margin-left: 4px; cursor: pointer;" />
</span>
</span>
<span>接单人: {{ task.receiverName || '--' }}</span>
</div>
<!-- 流水线任务子任务详细信息(可展开) -->
<div v-if="task.isPipeline === 1 && task.subTasks && task.subTasks.length > 0 && task.id && expandedTaskSubtasks[task.id]"
class="subtasks-detail">
<div v-for="(subTask, index) in task.subTasks" :key="subTask.id || index" class="subtask-item">
<span class="subtask-label">{{ getSubTaskLabel(subTask, index) }}:</span>
<span class="subtask-receiver">{{ subTask.receiverName || '待接单' }}</span>
<span :class="['subtask-status', getSubTaskStatusClass(subTask.status)]">
{{ getSubTaskStatusText(subTask.status) }}
</span>
</div>
</div>
<div v-if="task.brandName" class="detail-item">
<span class="icon">
@ -1030,8 +1067,8 @@
</div>
</div>
<!-- 进度条 -->
<div class="task-progress">
<!-- 进度条(进行中和已完成的任务显示) -->
<div v-if="task.status === 'in_progress' || task.status === 'completed'" class="task-progress">
<div class="progress-label">
<span>任务进度</span>
<span>{{ task.progress || 0 }}%</span>
@ -1043,9 +1080,26 @@
/>
</div>
<!-- 操作按钮 -->
<div class="task-actions">
<a-button size="small" @click="handleViewTaskDetail(task)">查看详情</a-button>
<!-- 时间信息 -->
<div class="task-footer">
<div class="footer-item">
<Icon name="calendar" size="sm" color="#31f08b" />
<span style="color: #ffffff;">发布: {{ formatTime(task.createTime) }}</span>
</div>
<div class="footer-item" v-if="task.estimatedHours">
<Icon name="clock" size="sm" color="#31f08b" />
<span style="color: #ffffff;">时效要求: {{ formatEstimatedTime(task.estimatedHours) }}</span>
</div>
<!-- 驳回时间 -->
<div class="footer-item" v-if="task.approvalStatus?.includes('rejected') && task.updateTime">
<Icon name="x-circle" size="sm" color="#f5222d" />
<span style="color: #f5222d;">驳回: {{ formatTime(task.updateTime) }}</span>
</div>
</div>
<!-- 操作按钮(进行中任务特有) -->
<div class="task-actions" style="margin-top: 16px; padding-top: 16px; border-top: 1px solid rgba(49, 240, 139, 0.2);">
<a-button size="small" @click.stop="handleViewTaskDetail(task)">查看详情</a-button>
<!-- 上一环节素材下载(流水线任务) -->
<a-button
v-if="task.prevDownloadUrl"
@ -1057,36 +1111,13 @@
<Icon name="download" size="sm" style="margin-right: 4px;" />
上一环节素材
</a-button>
<a-button v-if="canUpdateProgress(task)" type="primary" size="small" @click="handleUpdateProgress(task)">
<a-button v-if="canUpdateProgress(task)" type="primary" size="small" @click.stop="handleUpdateProgress(task)">
更新进度
</a-button>
<a-button v-if="canCompleteTask(task)" type="primary" size="small" @click="handleCompleteTask(task)">
<a-button v-if="canCompleteTask(task)" type="primary" size="small" @click.stop="handleCompleteTask(task)">
完结任务
</a-button>
</div>
<!-- 时间信息和任务编号 -->
<div class="task-footer">
<div class="footer-item task-no-item">
<Icon name="hash" size="sm" color="#31f08b" />
<span style="color: #ffffff;">编号: {{ task.isSubTask ? task.itemNo : task.taskNo }}</span>
<Icon
name="copy"
size="xs"
class="copy-icon"
@click.stop="handleCopyTaskNo(task.isSubTask ? task.itemNo : task.taskNo)"
title="复制任务编号"
/>
</div>
<div class="footer-item">
<Icon name="calendar" size="sm" color="#31f08b" />
<span style="color: #ffffff;">发布: {{ formatDate(task.createTime) }}</span>
</div>
<div class="footer-item" v-if="task.estimatedHours">
<Icon name="clock" size="sm" color="#31f08b" />
<span style="color: #ffffff;">时效要求: {{ formatEstimatedTime(task.estimatedHours) }}</span>
</div>
</div>
</div>
</div>