feat(web): 更新侧边栏组件和个人工作台组件,增强导航和业务展示功能
This commit is contained in:
@@ -59,11 +59,11 @@
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div class="workbench-grid">
|
||||
<div class="workbench-grid" :class="{ 'finance-grid': isFinanceUser }">
|
||||
<article class="panel list-panel">
|
||||
<div class="section-head">
|
||||
<div class="title-with-badge">
|
||||
<h3>今日待办</h3>
|
||||
<h3>报销待办</h3>
|
||||
<span class="alert-badge">{{ todoAlertCount }}</span>
|
||||
</div>
|
||||
<button type="button" class="link-action">查看全部 <i class="mdi mdi-chevron-right"></i></button>
|
||||
@@ -113,6 +113,58 @@
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article v-if="isFinanceUser" class="panel list-panel">
|
||||
<div class="section-head">
|
||||
<div class="title-with-badge">
|
||||
<h3>应收管理</h3>
|
||||
<span class="alert-badge">{{ receivableAlertCount }}</span>
|
||||
</div>
|
||||
<button type="button" class="link-action">查看全部 <i class="mdi mdi-chevron-right"></i></button>
|
||||
</div>
|
||||
|
||||
<div class="list-body">
|
||||
<div v-for="item in receivableItems" :key="item.id" class="progress-row">
|
||||
<div class="todo-icon" :style="{ '--icon-color': item.color }">
|
||||
<i :class="item.icon"></i>
|
||||
</div>
|
||||
|
||||
<div class="todo-copy progress-copy">
|
||||
<strong>{{ item.title }}</strong>
|
||||
<p>{{ item.date }}</p>
|
||||
</div>
|
||||
|
||||
<strong class="progress-amount">{{ item.amount }}</strong>
|
||||
<span class="progress-status" :class="item.tone">{{ item.status }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article v-if="isFinanceUser" class="panel list-panel">
|
||||
<div class="section-head">
|
||||
<div class="title-with-badge">
|
||||
<h3>应付管理</h3>
|
||||
<span class="alert-badge">{{ payableAlertCount }}</span>
|
||||
</div>
|
||||
<button type="button" class="link-action">查看全部 <i class="mdi mdi-chevron-right"></i></button>
|
||||
</div>
|
||||
|
||||
<div class="list-body">
|
||||
<div v-for="item in payableItems" :key="item.id" class="progress-row">
|
||||
<div class="todo-icon" :style="{ '--icon-color': item.color }">
|
||||
<i :class="item.icon"></i>
|
||||
</div>
|
||||
|
||||
<div class="todo-copy progress-copy">
|
||||
<strong>{{ item.title }}</strong>
|
||||
<p>{{ item.date }}</p>
|
||||
</div>
|
||||
|
||||
<strong class="progress-amount">{{ item.amount }}</strong>
|
||||
<span class="progress-status" :class="item.tone">{{ item.status }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<article class="panel policy-panel">
|
||||
@@ -154,6 +206,13 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['openAssistant'])
|
||||
const { currentUser } = useSystemState()
|
||||
|
||||
// 判断是否为财务人员
|
||||
const isFinanceUser = computed(() => {
|
||||
const user = currentUser.value || {}
|
||||
const roleCodes = Array.isArray(user.roleCodes) ? user.roleCodes : []
|
||||
return roleCodes.includes('finance') || roleCodes.includes('accountant') || user.isAdmin
|
||||
})
|
||||
const { toast } = useToast()
|
||||
const assistantDraft = ref('')
|
||||
const fileInputRef = ref(null)
|
||||
@@ -233,7 +292,9 @@ function emitAssistant(payload) {
|
||||
}
|
||||
|
||||
async function loadLatestConversation() {
|
||||
const payload = await fetchLatestConversation(resolveCurrentUserId(), SESSION_TYPE_EXPENSE)
|
||||
const payload = await fetchLatestConversation(resolveCurrentUserId(), SESSION_TYPE_EXPENSE, {
|
||||
preferRecoverable: true
|
||||
})
|
||||
return payload?.found ? payload.conversation || null : null
|
||||
}
|
||||
|
||||
@@ -361,6 +422,76 @@ const progressItems = [
|
||||
|
||||
const progressAlertCount = progressItems.filter((item) => item.status !== '已到账').length
|
||||
|
||||
const receivableItems = [
|
||||
{
|
||||
id: 'receivable-1',
|
||||
title: '客户服务费收入',
|
||||
amount: '¥15,800',
|
||||
date: '2026-05-10',
|
||||
status: '待收款',
|
||||
tone: 'info',
|
||||
icon: 'mdi mdi-account-cash-outline',
|
||||
color: '#f59e0b'
|
||||
},
|
||||
{
|
||||
id: 'receivable-2',
|
||||
title: '项目进度款',
|
||||
amount: '¥42,600',
|
||||
date: '2026-05-08',
|
||||
status: '部分收款',
|
||||
tone: 'success',
|
||||
icon: 'mdi mdi-cash-multiple',
|
||||
color: '#10b981'
|
||||
},
|
||||
{
|
||||
id: 'receivable-3',
|
||||
title: '咨询服务费',
|
||||
amount: '¥8,900',
|
||||
date: '2026-05-05',
|
||||
status: '逾期提醒',
|
||||
tone: 'info',
|
||||
icon: 'mdi mdi-bell-alert',
|
||||
color: '#ef4444'
|
||||
}
|
||||
]
|
||||
|
||||
const receivableAlertCount = receivableItems.filter((item) => item.status === '逾期提醒' || item.status === '待收款').length
|
||||
|
||||
const payableItems = [
|
||||
{
|
||||
id: 'payable-1',
|
||||
title: '供应商采购款',
|
||||
amount: '¥28,500',
|
||||
date: '2026-05-12',
|
||||
status: '待付款',
|
||||
tone: 'info',
|
||||
icon: 'mdi mdi-truck-outline',
|
||||
color: '#3b82f6'
|
||||
},
|
||||
{
|
||||
id: 'payable-2',
|
||||
title: '房租物业费',
|
||||
amount: '¥12,800',
|
||||
date: '2026-05-15',
|
||||
status: '待审批',
|
||||
tone: 'success',
|
||||
icon: 'mdi mdi-office-building',
|
||||
color: '#6366f1'
|
||||
},
|
||||
{
|
||||
id: 'payable-3',
|
||||
title: '软件服务费',
|
||||
amount: '¥3,600',
|
||||
date: '2026-05-01',
|
||||
status: '已付款',
|
||||
tone: 'mint',
|
||||
icon: 'mdi mdi-server',
|
||||
color: '#10b981'
|
||||
}
|
||||
]
|
||||
|
||||
const payableAlertCount = payableItems.filter((item) => item.status === '待付款' || item.status === '待审批').length
|
||||
|
||||
const policyItems = [
|
||||
{
|
||||
name: '差旅报销管理办法(2026版)',
|
||||
@@ -725,6 +856,11 @@ watch(
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.workbench-grid.finance-grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.list-panel,
|
||||
.policy-panel {
|
||||
padding: 20px 22px;
|
||||
@@ -974,6 +1110,11 @@ watch(
|
||||
.policy-row {
|
||||
grid-template-columns: 1.8fr 1.8fr 1fr;
|
||||
}
|
||||
|
||||
.workbench-grid.finance-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1440px) {
|
||||
@@ -1040,7 +1181,8 @@ watch(
|
||||
width: 176px;
|
||||
}
|
||||
|
||||
.workbench-grid {
|
||||
.workbench-grid,
|
||||
.workbench-grid.finance-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
@@ -1107,6 +1249,14 @@ watch(
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.workbench-grid.finance-grid {
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.workbench-grid.finance-grid .list-panel {
|
||||
padding: 16px 18px;
|
||||
}
|
||||
|
||||
.policy-table {
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
@@ -1129,5 +1279,4 @@ watch(
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
</svg>
|
||||
</div>
|
||||
<strong class="brand-name">{{ displayCompanyName }}</strong>
|
||||
<button class="brand-toggle" type="button" aria-label="打开 AI 助手" @click="emit('openChat')">
|
||||
<i class="mdi mdi-chevron-double-left"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<nav class="rail-nav" aria-label="功能导航">
|
||||
@@ -115,10 +112,10 @@ const displayCompanyName = computed(() => props.companyName || 'X-Financial')
|
||||
|
||||
.rail-brand {
|
||||
min-height: 86px;
|
||||
display: grid;
|
||||
grid-template-columns: 32px minmax(0, 1fr) 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
padding: 22px 20px 18px;
|
||||
}
|
||||
|
||||
@@ -137,31 +134,11 @@ const displayCompanyName = computed(() => props.companyName || 'X-Financial')
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
min-width: 0;
|
||||
color: #0f172a;
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.brand-toggle {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
border: 0;
|
||||
border-radius: 7px;
|
||||
background: transparent;
|
||||
color: #718096;
|
||||
transition: background 180ms var(--ease), color 180ms var(--ease);
|
||||
}
|
||||
|
||||
.brand-toggle:hover {
|
||||
background: #eef7f4;
|
||||
color: #07936f;
|
||||
}
|
||||
|
||||
.rail-nav {
|
||||
|
||||
Reference in New Issue
Block a user