feat: refactor monolithic App.vue into modular Vue component architecture
- Extract 711-line App.vue into 15+ focused files across 5 directories - Add data layer (icons, metrics, policies, auditTrail, requests) - Add composables (useNavigation, useRequests, useChat, useToast) - Add layout components (SidebarRail, TopBar, FilterBar) - Add shared components (PanelHead, InfoRow, ToastNotification) - Add business component (RequestTable) and 5 view components - Extract global CSS to assets/styles/global.css - Add start.sh with WSL/Windows cross-platform support - Add .gitignore for node_modules, dist, and IDE dirs
This commit is contained in:
63
src/components/business/RequestTable.vue
Normal file
63
src/components/business/RequestTable.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<article class="panel queue-panel" :class="{ expanded }">
|
||||
<PanelHead eyebrow="Approval queue" title="待处理报销申请" note="可直接通过、退回,或把当前单据带入合规对话继续追问。" />
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="col in columns" :key="col">{{ col }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="request in requests" :key="request.id">
|
||||
<td>
|
||||
<strong>{{ request.person }}</strong>
|
||||
<p>{{ request.dept }}</p>
|
||||
</td>
|
||||
<td>
|
||||
<strong>{{ request.category }} · {{ request.amount }}</strong>
|
||||
<p>{{ request.id }}</p>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge" :class="request.status">{{ request.verdict }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge" :class="request.sla.includes('51') ? 'danger' : ''">{{ request.sla }}</span>
|
||||
</td>
|
||||
<td>{{ request.risk }}</td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<button class="mini-btn" @click="emit('approve', request)">通过</button>
|
||||
<button class="mini-btn" @click="emit('ask', request)">询问 AI</button>
|
||||
<button class="mini-btn" @click="emit('reject', request)">退回</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import PanelHead from '../shared/PanelHead.vue'
|
||||
|
||||
defineProps({
|
||||
requests: { type: Array, required: true },
|
||||
expanded: Boolean
|
||||
})
|
||||
|
||||
const emit = defineEmits(['ask', 'approve', 'reject'])
|
||||
const columns = ['申请人', '费用与金额', 'AI 结论', 'SLA', '关键风险', '操作']
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.queue-panel { padding: 20px; }
|
||||
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }
|
||||
table { width: 100%; min-width: 860px; border-collapse: collapse; }
|
||||
th, td { padding: 14px 16px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: middle; }
|
||||
th { background: var(--surface-soft); color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .06em; }
|
||||
td strong { color: var(--ink); }
|
||||
td p { margin-top: 4px; color: var(--muted); font-size: 12px; }
|
||||
.row-actions { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user