feat: enhance layout components, data layer and global styles
- SidebarRail, TopBar, FilterBar: improved navigation and filtering UX - metrics.js, requests.js: expanded data with multi-range trend series - composables: enhanced useChat, useNavigation, useRequests - global.css: refined design tokens and utility classes - Add DocFilterBar component and LoginView page Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -10,12 +10,21 @@ export function useChat(activeView) {
|
||||
|
||||
function agentReply(text) {
|
||||
const c = activeCase.value
|
||||
if (!c) return '建议先核对政策阈值和附件完整性,再决定通过、退回补件或转人工复核。'
|
||||
if (text.includes('审批')) return `${c.id} 建议审批意见:发票验真通过,费用归属与预算中心匹配;${c.risk} 已触发规则提示,建议保留业务说明后通过。`
|
||||
if (text.includes('补件')) return '补件优先级:业务目的说明、行程或客户名单、直属经理确认记录。'
|
||||
if (text.includes('拦截')) return `拦截原因是 ${c.risk},该风险需要财务复核并留下制度依据。`
|
||||
if (text.includes('审计')) return `审计摘要:${c.person} 提交 ${c.amount} 报销,命中 ${c.risk},系统已保留 AI 判断。`
|
||||
return '建议先核对政策阈值和附件完整性,再决定通过、退回补件或转人工复核。'
|
||||
if (text.includes('出差申请') || text.includes('出差'))
|
||||
return '好的,我来帮您处理出差申请。请提供以下信息:\n1. 出发城市和目的地\n2. 出差日期和天数\n3. 出差事由\n4. 预计费用预算'
|
||||
if (text.includes('机票') || text.includes('飞机'))
|
||||
return '我来帮您查询机票信息。请告诉我:\n1. 出发城市 → 目的城市\n2. 出发日期\n3. 偏好的时间段(上午/下午/晚间)\n4. 舱位要求(经济舱/商务舱)'
|
||||
if (text.includes('酒店') || text.includes('住宿'))
|
||||
return '好的,帮您查找合适的酒店。请提供:\n1. 入住城市和区域偏好\n2. 入住和退房日期\n3. 星级/价位要求\n4. 是否需要含早餐'
|
||||
if (text.includes('火车票') || text.includes('高铁'))
|
||||
return '帮您查询火车票。请告诉我:\n1. 出发站 → 到达站\n2. 出行日期\n3. 座位偏好(二等座/一等座/商务座)\n4. 偏好的出发时间段'
|
||||
if (text.includes('审批意见'))
|
||||
return c ? `${c.id} 建议审批意见:费用归属与预算中心匹配,建议保留业务说明后通过。` : '请先选择一份单据再生成审批意见。'
|
||||
if (text.includes('补件'))
|
||||
return '补件优先级:业务目的说明、行程或客户名单、直属经理确认记录。'
|
||||
if (text.includes('差旅政策') || text.includes('政策'))
|
||||
return '当前差旅政策要点:\n• 住宿标准:一线城市 600 元/晚,二线城市 400 元/晚\n• 机票:优先经济舱,3 小时以上可申请商务舱\n• 高铁:优先二等座,4 小时以上可申请一等座\n• 每日餐饮补贴:120 元'
|
||||
return '好的,我已记录您的需求。请问还需要什么帮助?我还可以帮您查询差旅政策、预订机票酒店火车票等。'
|
||||
}
|
||||
|
||||
function scrollToBottom() {
|
||||
@@ -56,8 +65,13 @@ export function useChat(activeView) {
|
||||
nextTick(() => messageList.value?.scrollTo({ top: messageList.value.scrollHeight }))
|
||||
}
|
||||
|
||||
function openNewChat() {
|
||||
activeCase.value = null
|
||||
activeView.value = 'chat'
|
||||
}
|
||||
|
||||
return {
|
||||
messages, draft, uploadedFiles, messageList, activeCase, prompts,
|
||||
sendMessage, handleUpload, openChat, scrollToBottom
|
||||
sendMessage, handleUpload, openChat, openNewChat, scrollToBottom
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,46 @@ import { computed, ref } from 'vue'
|
||||
import { icons } from '../data/icons.js'
|
||||
|
||||
export const navItems = [
|
||||
{ id: 'overview', label: '运营总览', icon: icons.dashboard, title: '企业报销智能运营台', desc: '面向财务共享中心的审批、风控、SLA 与智能体协同工作台。' },
|
||||
{ id: 'chat', label: '合规对话', icon: icons.message, title: 'AI 合规对话', desc: '上传单据、追问制度依据,并生成可留痕的审核建议。' },
|
||||
{ id: 'requests', label: '报销队列', icon: icons.list, title: '报销申请队列', desc: '按风险、补件状态和 AI 建议处理待审单据。' },
|
||||
{ id: 'policies', label: '政策规则', icon: icons.file, title: '政策规则中心', desc: '维护差旅、招待、采购和发票校验规则。' },
|
||||
{ id: 'audit', label: '审计追踪', icon: icons.audit, title: '审计追踪', desc: '查看关键审批动作、AI 建议和制度命中记录。' }
|
||||
{
|
||||
id: 'overview',
|
||||
label: '总览',
|
||||
navHint: '运营指标与趋势',
|
||||
icon: icons.dashboard,
|
||||
title: '企业报销智能运营台',
|
||||
desc: '面向财务共享中心的审批、风控、SLA与自动化运营看板'
|
||||
},
|
||||
{
|
||||
id: 'chat',
|
||||
label: '审批中心',
|
||||
navHint: 'AI 助手与单据处理',
|
||||
icon: icons.message,
|
||||
title: '单据管理中心',
|
||||
desc: '管理出差申请、报销单据,AI 辅助发起申请与智能审核。'
|
||||
},
|
||||
{
|
||||
id: 'requests',
|
||||
label: '报销单',
|
||||
navHint: '待审队列与风险处理',
|
||||
icon: icons.list,
|
||||
title: '报销申请队列',
|
||||
desc: '按风险、补件状态和 AI 建议处理待审单据。'
|
||||
},
|
||||
{
|
||||
id: 'policies',
|
||||
label: '政策规则',
|
||||
navHint: '制度与校验规则',
|
||||
icon: icons.file,
|
||||
title: '政策规则中心',
|
||||
desc: '维护差旅、招待、采购和发票校验规则。'
|
||||
},
|
||||
{
|
||||
id: 'audit',
|
||||
label: '审计追踪',
|
||||
navHint: '关键动作与日志',
|
||||
icon: icons.audit,
|
||||
title: '审计追踪',
|
||||
desc: '查看关键审批动作、AI 建议和制度命中记录。'
|
||||
}
|
||||
]
|
||||
|
||||
export function useNavigation() {
|
||||
|
||||
@@ -3,30 +3,52 @@ import { initialRequests } from '../data/requests.js'
|
||||
|
||||
export function useRequests() {
|
||||
const requests = ref(initialRequests)
|
||||
const entityMap = {
|
||||
'Northstar China Ltd.': 'Northstar China Ltd.',
|
||||
'Northstar Singapore Pte.': 'Northstar Singapore Pte.',
|
||||
'Northstar US Inc.': 'Northstar US Inc.'
|
||||
}
|
||||
const search = ref('')
|
||||
const filters = reactive({ entity: '全部主体', category: '全部费用', risk: '全部风险' })
|
||||
const ranges = ['今日', '本周', '本月']
|
||||
const activeRange = ref('今日')
|
||||
const activeRange = ref('本周')
|
||||
|
||||
const filteredRequests = computed(() => {
|
||||
const key = search.value.trim().toLowerCase()
|
||||
return requests.value.filter((item) => {
|
||||
const matchesSearch = !key || `${item.id}${item.person}${item.category}${item.risk}`.toLowerCase().includes(key)
|
||||
const matchesCategory = filters.category === '全部费用' || item.category.includes(filters.category.replace('交通', ''))
|
||||
const matchesRisk = filters.risk === '全部风险' || (filters.risk === '高风险' ? item.status === 'danger' : item.verdict.includes(filters.risk.replace('低风险', '通过')))
|
||||
return matchesSearch && matchesCategory && matchesRisk
|
||||
const matchesEntity = filters.entity === '全部主体' || item.entity === entityMap[filters.entity]
|
||||
const matchesCategory = filters.category === '全部费用' || item.category === filters.category
|
||||
const matchesRisk = filters.risk === '全部风险'
|
||||
|| (filters.risk === '高风险' && item.status === 'danger')
|
||||
|| (filters.risk === '需解释' && item.status === 'warning')
|
||||
|| (filters.risk === '低风险' && item.status === 'success')
|
||||
const matchesRange = activeRange.value === '本月'
|
||||
|| (activeRange.value === '本周' && item.range !== '本月')
|
||||
|| (activeRange.value === '今日' && item.range === '今日')
|
||||
return matchesSearch && matchesEntity && matchesCategory && matchesRisk && matchesRange
|
||||
})
|
||||
})
|
||||
|
||||
function updateRequest(requestId, updates) {
|
||||
requests.value = requests.value.map((item) => (item.id === requestId ? { ...item, ...updates } : item))
|
||||
}
|
||||
|
||||
function approveRequest(request) {
|
||||
request.verdict = '已通过'
|
||||
request.status = 'success'
|
||||
updateRequest(request.id, {
|
||||
verdict: '已通过',
|
||||
status: 'success',
|
||||
risk: '已完成人工确认'
|
||||
})
|
||||
return `${request.id} 已标记为通过,审计日志已更新。`
|
||||
}
|
||||
|
||||
function rejectRequest(request) {
|
||||
request.verdict = '已退回补件'
|
||||
request.status = 'danger'
|
||||
updateRequest(request.id, {
|
||||
verdict: '已退回补件',
|
||||
status: 'danger',
|
||||
risk: '待申请人补充差旅行程与票据'
|
||||
})
|
||||
return `${request.id} 已退回,系统将通知申请人补充材料。`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user