Files
X-Financial/web/src/views/ArchiveCenterView.vue
caoxiaozhu 88ff04bef8 feat: 新增归档中心页面并完善知识库与报销查询能力
新增前端归档中心视图及相关工具函数,扩充知识库文档分类和
提取器支持多种格式,增强编排器报销查询的多维度检索,优
化本体规则和用户代理审核消息,前端完善报销创建和审批详
情交互细节,补充单元测试覆盖。
2026-05-22 16:00:19 +08:00

142 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<section class="approval-page archive-page">
<TravelRequestDetailView
v-if="selectedRow"
:request="selectedRow"
back-label="返回归档列表"
@back-to-requests="closeSelectedDetail"
@request-updated="reload"
@request-deleted="reload"
/>
<article v-else class="approval-list panel">
<nav class="status-tabs" aria-label="归档分类">
<button
v-for="tab in tabs"
:key="tab"
type="button"
:class="{ active: activeTab === tab }"
@click="activeTab = tab"
>
{{ tab }}
</button>
</nav>
<div class="list-toolbar">
<div class="filter-set">
<div class="list-search">
<i class="mdi mdi-magnify"></i>
<input v-model="listKeyword" type="search" placeholder="搜索单号、申请人、部门、报销类型..." />
</div>
<div
v-for="dropdown in filterDropdowns"
:key="dropdown.key"
class="archive-dropdown-filter"
:class="{ open: openFilterKey === dropdown.key }"
>
<button class="filter-btn" type="button" @click="toggleFilterDropdown(dropdown.key)">
<span>{{ dropdown.label }}</span>
<i class="mdi mdi-chevron-down"></i>
</button>
<div
v-if="openFilterKey === dropdown.key"
class="archive-dropdown-menu"
role="menu"
:aria-label="`${dropdown.label}筛选`"
>
<button
v-for="option in dropdown.options"
:key="`${dropdown.key}-${option.value}`"
type="button"
class="archive-dropdown-option"
:class="{ active: dropdown.activeValue === option.value }"
role="menuitem"
@click="selectFilterValue(dropdown.key, option.value)"
>
{{ option.label }}
</button>
</div>
</div>
</div>
</div>
<p class="hint"><i class="mdi mdi-information-outline"></i> 归档中心保存公司已归档入账的报销数据点击单据行查看详情</p>
<div class="table-wrap" :class="{ 'is-empty': showEmpty }">
<div v-if="loading" class="table-state">
<TableLoadingState
title="归档数据同步中"
message="正在加载公司已归档的报销单据"
icon="mdi mdi-archive-check-outline"
/>
</div>
<div v-else-if="error" class="table-state error">
<i class="mdi mdi-alert-circle-outline"></i>
<strong>归档列表加载失败</strong>
<p>{{ error }}</p>
<button class="state-action" type="button" @click="reload">重新加载</button>
</div>
<TableEmptyState
v-else-if="showEmpty"
:eyebrow="archiveEmptyState.eyebrow"
:title="archiveEmptyState.title"
:description="archiveEmptyState.desc"
:icon="archiveEmptyState.icon"
:action-label="archiveEmptyState.actionLabel"
:action-icon="archiveEmptyState.actionIcon"
:tone="archiveEmptyState.tone"
:art-label="archiveEmptyState.artLabel"
:tips="archiveEmptyState.tips"
@action="handleEmptyAction"
/>
<table v-else>
<colgroup>
<col><col><col><col><col><col><col><col><col>
</colgroup>
<thead>
<tr>
<th>单号</th>
<th>申请人</th>
<th>申请部门</th>
<th>报销类型</th>
<th>金额</th>
<th>提交时间 <i class="mdi mdi-sort"></i></th>
<th>归档节点</th>
<th>风险</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr v-for="row in visibleRows" :key="row.id" @click="selectedRow = row">
<td><strong class="doc-id">{{ row.id }}</strong></td>
<td>
<span class="person">
<span class="avatar">{{ row.avatar }}</span>
{{ row.applicant }}
</span>
</td>
<td>{{ row.department }}</td>
<td>{{ row.type }}</td>
<td>{{ row.amount }}</td>
<td>{{ row.time }}</td>
<td>{{ row.node }}</td>
<td><span class="risk-tag" :class="row.riskTone">{{ row.risk }}</span></td>
<td><span class="status-tag archived">{{ row.status }}</span></td>
</tr>
</tbody>
</table>
</div>
</article>
</section>
</template>
<script src="./scripts/ArchiveCenterView.js"></script>
<style scoped src="../assets/styles/views/approval-center-view.css"></style>
<style scoped src="../assets/styles/views/approval-center-view-part2.css"></style>
<style scoped src="../assets/styles/views/archive-center-view.css"></style>