| | |
| | | <script lang="ts" setup> |
| | | import type { PendingTask } from '../../../types'; |
| | | |
| | | import { Descriptions, Progress, Tag } from 'ant-design-vue'; |
| | | import { Descriptions, Progress, Tag, Timeline, TimelineItem } from 'ant-design-vue'; |
| | | |
| | | defineOptions({ name: 'WorkbenchTaskDetailTab' }); |
| | | |
| | |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="备注" :span="2">{{ task.remark ?? '—' }}</Descriptions.Item> |
| | | </Descriptions> |
| | | |
| | | <!-- 停工记录 --> |
| | | <div v-if="task.pauseRecords && task.pauseRecords.length > 0" class="detail-pause-records"> |
| | | <div class="detail-pause-records__title">停工历史记录</div> |
| | | <Timeline class="pause-timeline"> |
| | | <TimelineItem |
| | | v-for="record in task.pauseRecords" |
| | | :key="record.id" |
| | | :color="record.resumeTime ? 'green' : 'red'" |
| | | > |
| | | <div class="pause-timeline-item"> |
| | | <div class="pause-timeline-time"> |
| | | <span class="time-label">{{ record.pauseTime }}</span> |
| | | <span class="time-separator">至</span> |
| | | <span class="time-label" :class="{ 'is-ongoing': !record.resumeTime }"> |
| | | {{ record.resumeTime || '正在停工' }} |
| | | </span> |
| | | </div> |
| | | <div class="pause-timeline-content"> |
| | | <div class="pause-info-row"> |
| | | <span class="info-label">操作人员:</span> |
| | | <span class="info-value"> |
| | | {{ record.pauseUserName }} (停工) |
| | | <template v-if="record.resumeTime"> |
| | | <span style="margin: 0 4px; color: #d9d9d9">|</span> |
| | | {{ record.resumeUserName }} (复工) |
| | | </template> |
| | | </span> |
| | | </div> |
| | | <div class="pause-info-row"> |
| | | <span class="info-label">停工原因:</span> |
| | | <span class="info-value">{{ record.reason }}</span> |
| | | </div> |
| | | <div class="pause-info-row" v-if="record.remark"> |
| | | <span class="info-label">备注:</span> |
| | | <span class="info-value">{{ record.remark }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </TimelineItem> |
| | | </Timeline> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | </template> |
| | |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | |
| | | .detail-pause-records { |
| | | margin-top: 24px; |
| | | } |
| | | |
| | | .detail-pause-records__title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #1a1a1a; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .pause-timeline { |
| | | padding-top: 6px; |
| | | padding-left: 4px; |
| | | } |
| | | |
| | | .pause-timeline-item { |
| | | background: #fafafa; |
| | | border: 1px solid #f0f0f0; |
| | | border-radius: 8px; |
| | | padding: 14px 18px; |
| | | margin-top: -6px; |
| | | box-shadow: 0 1px 2px rgb(0 0 0 / 2%); |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | box-shadow: 0 4px 12px rgb(0 0 0 / 5%); |
| | | border-color: #e6d8d8; |
| | | } |
| | | } |
| | | |
| | | .pause-timeline-time { |
| | | font-size: 13px; |
| | | color: #595959; |
| | | font-weight: 500; |
| | | margin-bottom: 10px; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .time-label { |
| | | background: #e6f7ff; |
| | | color: #1890ff; |
| | | padding: 2px 8px; |
| | | border-radius: 4px; |
| | | font-variant-numeric: tabular-nums; |
| | | } |
| | | |
| | | .time-label.is-ongoing { |
| | | background: #fff1f0; |
| | | color: #f5222d; |
| | | } |
| | | |
| | | .time-separator { |
| | | color: #bfbfbf; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .pause-timeline-content { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 6px; |
| | | } |
| | | |
| | | .pause-info-row { |
| | | font-size: 13px; |
| | | display: flex; |
| | | line-height: 1.5; |
| | | } |
| | | |
| | | .pause-info-row .info-label { |
| | | color: #8c8c8c; |
| | | width: 70px; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .pause-info-row .info-value { |
| | | color: #262626; |
| | | flex: 1; |
| | | } |
| | | </style> |