feat: 优化差旅报销预审流程与个人工作台 UI 体系

- 完善 user_agent_application 申请差旅报销预审槽位与消息组装
- 增强预算助理报告与风险建议卡片交互
- 重构登录页视觉样式与移动端响应式适配
- 优化个人工作台、文档中心、政策中心、员工管理等页面布局
- 拆分 travelRequestDetailPreReviewModel 为 advice/submit 模型
- 补充报销草稿、风险复核、Item Sync 与模板执行器测试覆盖
This commit is contained in:
caoxiaozhu
2026-06-02 14:01:51 +08:00
parent 92444e7eae
commit ca691f3ee0
107 changed files with 5663 additions and 1542 deletions

View File

@@ -196,20 +196,20 @@
</thead>
<tbody>
<tr v-for="row in visibleRows" :key="row.documentKey" @click="openDocument(row)">
<td>
<td data-label="单号">
<span v-if="row.isNewDocument" class="new-document-badge">NEW</span>
<strong class="doc-id">{{ row.documentNo }}</strong>
</td>
<td>{{ row.createdAtDisplay }}</td>
<td v-if="showStayTimeColumn">{{ row.stayTimeDisplay }}</td>
<td><span class="doc-kind-tag" :class="row.documentTypeCode">{{ row.documentTypeLabel }}</span></td>
<td><span class="type-tag" :class="row.typeTone">{{ row.typeLabel }}</span></td>
<td>{{ row.initiatorName }}</td>
<td>{{ row.reason }}</td>
<td>{{ row.amountDisplay }}</td>
<td>{{ row.node }}</td>
<td><span class="status-tag" :class="row.statusTone">{{ row.statusLabel }}</span></td>
<td>{{ row.updatedAtDisplay }}</td>
<td data-label="创建时间">{{ row.createdAtDisplay }}</td>
<td v-if="showStayTimeColumn" data-label="停留时间">{{ row.stayTimeDisplay }}</td>
<td data-label="单据类型"><span class="doc-kind-tag" :class="row.documentTypeCode">{{ row.documentTypeLabel }}</span></td>
<td data-label="费用场景"><span class="type-tag" :class="row.typeTone">{{ row.typeLabel }}</span></td>
<td data-label="发起人">{{ row.initiatorName }}</td>
<td data-label="事项">{{ row.reason }}</td>
<td data-label="金额">{{ row.amountDisplay }}</td>
<td data-label="当前环节">{{ row.node }}</td>
<td data-label="状态"><span class="status-tag" :class="row.statusTone">{{ row.statusLabel }}</span></td>
<td data-label="更新时间">{{ row.updatedAtDisplay }}</td>
</tr>
</tbody>
</table>
@@ -587,7 +587,9 @@ function buildDocumentRow(request, options = {}) {
archived,
createdAtDisplay: formatDocumentListTime(createdAtSource),
stayTimeDisplay: resolveDocumentStayTimeDisplay(normalized),
isNewDocument: isNewDocument({ ...normalized, source: options.source || 'owned', claimId, documentNo }, viewedDocumentKeys.value),
isNewDocument: archived
? false
: isNewDocument({ ...normalized, source: options.source || 'owned', claimId, documentNo }, viewedDocumentKeys.value),
updatedAtDisplay: formatDocumentListTime(updatedAtSource),
sortTime: resolveDocumentSortTime(updatedAtSource)
}