2026-05-06 11:00:38 +08:00
|
|
|
|
import { computed, ref } from 'vue'
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
name: 'ApprovalCenterView' ,
|
|
|
|
|
|
setup(props, { emit }) {
|
|
|
|
|
|
const activeTab = ref('全部待审')
|
|
|
|
|
|
const selectedRow = ref(null)
|
|
|
|
|
|
const expandedExpenseId = ref(null)
|
|
|
|
|
|
const tabs = ['全部待审', '高风险', '即将超时', '已处理']
|
|
|
|
|
|
const filters = ['法人主体', '费用类型', '风险等级', '金额区间', '所属部门']
|
|
|
|
|
|
|
|
|
|
|
|
const rows = [
|
|
|
|
|
|
{ id: 'RE240712001', applicant: '李文静', avatar: '李', department: '市场部', type: '差旅报销', amount: '¥3,680', time: '07-12 09:20', risk: '中风险', riskTone: 'medium', sla: '4.2h', slaTone: 'safe', node: '财务审批', status: '待审批', statusTone: 'pending' },
|
|
|
|
|
|
{ id: 'RE240712002', applicant: '王志强', avatar: '王', department: '销售部', type: '招待费', amount: '¥1,280', time: '07-12 08:15', risk: '低风险', riskTone: 'low', sla: '8.5h', slaTone: 'safe', node: '部门负责人', status: '待审批', statusTone: 'pending' },
|
|
|
|
|
|
{ id: 'RE240711098', applicant: '刘思雨', avatar: '刘', department: '市场部', type: '差旅报销', amount: '¥6,920', time: '07-11 18:46', risk: '高风险', riskTone: 'high', sla: '0.8h', slaTone: 'danger', node: '财务审批', status: '即将超时', statusTone: 'urgent', spotlight: true },
|
|
|
|
|
|
{ id: 'RE240711087', applicant: '陈晓琳', avatar: '陈', department: '行政部', type: '办公采购', amount: '¥860', time: '07-11 17:32', risk: '低风险', riskTone: 'low', sla: '6.1h', slaTone: 'safe', node: '预算校验', status: '待审批', statusTone: 'pending' },
|
|
|
|
|
|
{ id: 'RE240711076', applicant: '赵明', avatar: '赵', department: '研发中心', type: '其他费用', amount: '¥4,250', time: '07-11 15:10', risk: '中风险', riskTone: 'medium', sla: '2.4h', slaTone: 'warning', node: '部门负责人', status: '待审批', statusTone: 'pending' },
|
|
|
|
|
|
{ id: 'RE240711065', applicant: '孙楠', avatar: '孙', department: '财务部', type: '招待费', amount: '¥560', time: '07-11 13:42', risk: '低风险', riskTone: 'low', sla: '5.7h', slaTone: 'safe', node: '财务审批', status: '待审批', statusTone: 'pending' },
|
|
|
|
|
|
{ id: 'RE240711054', applicant: '周晓彤', avatar: '周', department: '市场部', type: '办公采购', amount: '¥2,150', time: '07-11 11:28', risk: '中风险', riskTone: 'medium', sla: '1.9h', slaTone: 'warning', node: '预算校验', status: '即将超时', statusTone: 'urgent' },
|
|
|
|
|
|
{ id: 'RE240711043', applicant: '吴磊', avatar: '吴', department: '销售部', type: '其他费用', amount: '¥980', time: '07-11 09:05', risk: '低风险', riskTone: 'low', sla: '7.3h', slaTone: 'safe', node: '部门负责人', status: '待审批', statusTone: 'pending' }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const visibleRows = computed(() => {
|
|
|
|
|
|
if (activeTab.value === '全部待审') return rows
|
|
|
|
|
|
if (activeTab.value === '高风险') return rows.filter((row) => row.risk === '高风险')
|
|
|
|
|
|
if (activeTab.value === '即将超时') return rows.filter((row) => row.status === '即将超时')
|
|
|
|
|
|
return rows.slice(0, 3).map((row) => ({ ...row, status: '已处理', statusTone: 'done' }))
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const approvalSteps = [
|
|
|
|
|
|
{ index: 1, label: '提交申请', time: '07-11 08:46', done: true, active: true },
|
|
|
|
|
|
{ index: 2, label: '票据识别', time: '07-11 08:48', done: true, active: true },
|
|
|
|
|
|
{ index: 3, label: '费用归类', time: '07-11 08:49', done: true, active: true },
|
|
|
|
|
|
{ index: 4, label: '部门负责人审批', time: '07-11 11:28', done: true, active: true },
|
|
|
|
|
|
{ index: 5, label: '财务审批', time: '进行中', active: true, current: true },
|
|
|
|
|
|
{ index: 6, label: '归档入账', time: '待处理' }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const summaryItems = [
|
|
|
|
|
|
{ label: '行程', value: '北京 → 上海', icon: 'mdi mdi-map-marker-path' },
|
|
|
|
|
|
{ label: '出差区间', value: '07-10 至 07-11', icon: 'mdi mdi-clock-outline' },
|
|
|
|
|
|
{ label: '票据关联', value: '8 条明细 / 7 份材料', icon: 'mdi mdi-file-document-multiple-outline' },
|
|
|
|
|
|
{ label: '成本归属', value: '市场部 · CC-MKT-01', icon: 'mdi mdi-account-group-outline' },
|
|
|
|
|
|
{ label: '支付方式', value: '企业垫付', icon: 'mdi mdi-credit-card-outline' }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const heroSummaryItems = computed(() => [
|
|
|
|
|
|
{ label: '单号', value: selectedRow.value?.id ?? '-', icon: 'mdi mdi-pound-box-outline' },
|
|
|
|
|
|
{ label: '报销类型', value: selectedRow.value?.type ?? '-', icon: 'mdi mdi-briefcase-outline' },
|
|
|
|
|
|
...summaryItems
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
const currentProgressRingMotion = {
|
|
|
|
|
|
initial: {
|
|
|
|
|
|
scale: 1,
|
|
|
|
|
|
opacity: 0.34,
|
|
|
|
|
|
},
|
|
|
|
|
|
enter: {
|
|
|
|
|
|
scale: [1, 1.42, 1.78],
|
|
|
|
|
|
opacity: [0.34, 0.16, 0],
|
|
|
|
|
|
transition: {
|
|
|
|
|
|
duration: 3.2,
|
|
|
|
|
|
repeat: Infinity,
|
|
|
|
|
|
repeatType: 'loop',
|
|
|
|
|
|
repeatDelay: 0.85,
|
|
|
|
|
|
ease: 'easeOut',
|
|
|
|
|
|
times: [0, 0.5, 1],
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const expenseItems = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'flight-1',
|
|
|
|
|
|
time: '07-10 07:25',
|
|
|
|
|
|
dayLabel: '周三',
|
|
|
|
|
|
name: '机票',
|
|
|
|
|
|
category: '交通',
|
|
|
|
|
|
desc: '北京首都 → 上海虹桥',
|
|
|
|
|
|
detail: 'MU5103 往返经济舱,含行程单',
|
|
|
|
|
|
amount: '¥2,180',
|
|
|
|
|
|
status: '未超标',
|
|
|
|
|
|
tone: 'ok',
|
|
|
|
|
|
attachmentStatus: '已上传',
|
|
|
|
|
|
attachmentTone: 'ok',
|
|
|
|
|
|
attachmentHint: '电子行程单与机票发票齐全',
|
|
|
|
|
|
attachments: ['电子行程单.pdf', '机票发票.pdf'],
|
|
|
|
|
|
riskLabel: '低风险',
|
|
|
|
|
|
riskTone: 'low',
|
|
|
|
|
|
riskText: '票面信息与行程匹配。'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'taxi-1',
|
|
|
|
|
|
time: '07-10 10:35',
|
|
|
|
|
|
dayLabel: '周三',
|
|
|
|
|
|
name: '出租车',
|
|
|
|
|
|
category: '市内交通',
|
|
|
|
|
|
desc: '虹桥机场 → 静安酒店',
|
|
|
|
|
|
detail: '落地后前往酒店,含过路费',
|
|
|
|
|
|
amount: '¥86',
|
|
|
|
|
|
status: '未超标',
|
|
|
|
|
|
tone: 'ok',
|
|
|
|
|
|
attachmentStatus: '已上传',
|
|
|
|
|
|
attachmentTone: 'ok',
|
|
|
|
|
|
attachmentHint: '已上传 1 张发票',
|
|
|
|
|
|
attachments: ['出租车发票-0710-01.jpg'],
|
|
|
|
|
|
riskLabel: '中风险',
|
|
|
|
|
|
riskTone: 'medium',
|
|
|
|
|
|
riskText: '高峰加价较高,建议顺带核对上车点。'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'metro-1',
|
|
|
|
|
|
time: '07-10 18:20',
|
|
|
|
|
|
dayLabel: '周三',
|
|
|
|
|
|
name: '地铁',
|
|
|
|
|
|
category: '市内交通',
|
|
|
|
|
|
desc: '静安酒店 → 客户园区',
|
|
|
|
|
|
detail: '2 号线换乘,通勤交通',
|
|
|
|
|
|
amount: '¥12',
|
|
|
|
|
|
status: '未超标',
|
|
|
|
|
|
tone: 'ok',
|
|
|
|
|
|
attachmentStatus: '已上传',
|
|
|
|
|
|
attachmentTone: 'ok',
|
|
|
|
|
|
attachmentHint: '已上传电子票据',
|
|
|
|
|
|
attachments: ['地铁电子票据-0710.png'],
|
|
|
|
|
|
riskLabel: '低风险',
|
|
|
|
|
|
riskTone: 'low',
|
|
|
|
|
|
riskText: '路线与拜访行程一致。'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'taxi-2',
|
|
|
|
|
|
time: '07-11 08:40',
|
|
|
|
|
|
dayLabel: '周四',
|
|
|
|
|
|
name: '出租车',
|
|
|
|
|
|
category: '市内交通',
|
|
|
|
|
|
desc: '静安酒店 → 客户园区',
|
|
|
|
|
|
detail: '次日早会前往客户现场',
|
|
|
|
|
|
amount: '¥42',
|
|
|
|
|
|
status: '未超标',
|
|
|
|
|
|
tone: 'ok',
|
|
|
|
|
|
attachmentStatus: '未上传',
|
|
|
|
|
|
attachmentTone: 'missing',
|
|
|
|
|
|
attachmentHint: '缺少对应发票',
|
|
|
|
|
|
attachments: [],
|
|
|
|
|
|
riskLabel: '高风险',
|
|
|
|
|
|
riskTone: 'high',
|
|
|
|
|
|
riskText: '票据缺失,当前无法完成交通费核验。'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'taxi-3',
|
|
|
|
|
|
time: '07-11 20:55',
|
|
|
|
|
|
dayLabel: '周四',
|
|
|
|
|
|
name: '出租车',
|
|
|
|
|
|
category: '返程交通',
|
|
|
|
|
|
desc: '客户园区 → 虹桥机场',
|
|
|
|
|
|
detail: '夜间返程,触发超标校验',
|
|
|
|
|
|
amount: '¥136',
|
|
|
|
|
|
status: '超标 ¥28',
|
|
|
|
|
|
tone: 'bad',
|
|
|
|
|
|
attachmentStatus: '已上传',
|
|
|
|
|
|
attachmentTone: 'ok',
|
|
|
|
|
|
attachmentHint: '已上传 1 张发票',
|
|
|
|
|
|
attachments: ['出租车发票-0711-02.jpg'],
|
|
|
|
|
|
riskLabel: '中风险',
|
|
|
|
|
|
riskTone: 'medium',
|
|
|
|
|
|
riskText: '金额超差旅标准 ¥28,需补充业务说明。'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'hotel-1',
|
|
|
|
|
|
time: '07-10 至 07-11',
|
|
|
|
|
|
dayLabel: '2 晚',
|
|
|
|
|
|
name: '酒店',
|
|
|
|
|
|
category: '住宿',
|
|
|
|
|
|
desc: '上海静安商务酒店',
|
|
|
|
|
|
detail: '标准大床房 2 晚,含早餐',
|
|
|
|
|
|
amount: '¥2,480',
|
|
|
|
|
|
status: '未超标',
|
|
|
|
|
|
tone: 'ok',
|
|
|
|
|
|
attachmentStatus: '部分上传',
|
|
|
|
|
|
attachmentTone: 'partial',
|
|
|
|
|
|
attachmentHint: '发票已上传,入住清单缺失',
|
|
|
|
|
|
attachments: ['酒店发票.jpg'],
|
|
|
|
|
|
riskLabel: '高风险',
|
|
|
|
|
|
riskTone: 'high',
|
|
|
|
|
|
riskText: '缺少入住清单,住宿真实性待补证。'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'meal-1',
|
|
|
|
|
|
time: '07-10 至 07-11',
|
|
|
|
|
|
dayLabel: '2 天',
|
|
|
|
|
|
name: '餐补',
|
|
|
|
|
|
category: '补贴',
|
|
|
|
|
|
desc: '差旅餐补',
|
|
|
|
|
|
detail: '按差旅制度自动计算',
|
|
|
|
|
|
amount: '¥372',
|
|
|
|
|
|
status: '未超标',
|
|
|
|
|
|
tone: 'ok',
|
|
|
|
|
|
attachmentStatus: '免上传',
|
|
|
|
|
|
attachmentTone: 'neutral',
|
|
|
|
|
|
attachmentHint: '制度型补贴无需票据',
|
|
|
|
|
|
attachments: [],
|
|
|
|
|
|
riskLabel: '低风险',
|
|
|
|
|
|
riskTone: 'low',
|
|
|
|
|
|
riskText: '系统自动核算,无额外异常。'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'other-1',
|
|
|
|
|
|
time: '07-11 09:10',
|
|
|
|
|
|
dayLabel: '周四',
|
|
|
|
|
|
name: '其他',
|
|
|
|
|
|
category: '杂费',
|
|
|
|
|
|
desc: '行李寄存 / 打印费',
|
|
|
|
|
|
detail: '客户提案资料打印与寄存服务',
|
|
|
|
|
|
amount: '¥1,612',
|
|
|
|
|
|
status: '未超标',
|
|
|
|
|
|
tone: 'ok',
|
|
|
|
|
|
attachmentStatus: '已上传',
|
|
|
|
|
|
attachmentTone: 'ok',
|
|
|
|
|
|
attachmentHint: '已上传 2 份附件',
|
|
|
|
|
|
attachments: ['打印服务发票.jpg', '行李寄存凭证.jpg'],
|
|
|
|
|
|
riskLabel: '低风险',
|
|
|
|
|
|
riskTone: 'low',
|
|
|
|
|
|
riskText: '用途清晰,金额在授权范围内。'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const expenseTotal = '¥6,920'
|
|
|
|
|
|
|
|
|
|
|
|
const uploadedExpenseCount = computed(() => expenseItems.filter((item) => item.attachments.length).length)
|
|
|
|
|
|
|
|
|
|
|
|
const showExpenseRisk = (item) => item.riskTone === 'medium' || item.riskTone === 'high'
|
|
|
|
|
|
|
|
|
|
|
|
const toggleExpenseAttachments = (id) => {
|
|
|
|
|
|
expandedExpenseId.value = expandedExpenseId.value === id ? null : id
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const attachments = [
|
|
|
|
|
|
{ name: '机票.pdf', size: '256 KB', icon: 'mdi mdi-file-pdf-box', iconClass: 'pdf' },
|
|
|
|
|
|
{ name: '酒店发票.jpg', size: '412 KB', icon: 'mdi mdi-image', iconClass: 'img' },
|
|
|
|
|
|
{ name: '行程单.pdf', size: '198 KB', icon: 'mdi mdi-file-pdf-box', iconClass: 'pdf' },
|
|
|
|
|
|
{ name: '出租车发票1.jpg', size: '128 KB', icon: 'mdi mdi-image', iconClass: 'img' },
|
|
|
|
|
|
{ name: '出租车发票2.jpg', size: '132 KB', icon: 'mdi mdi-image', iconClass: 'img' },
|
|
|
|
|
|
{ name: '酒店入住清单', size: '缺失', icon: 'mdi mdi-minus-circle', iconClass: 'miss', missing: true }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const riskItems = [
|
|
|
|
|
|
{ text: '酒店入住清单缺失', level: '高', tone: 'high', icon: 'mdi mdi-alert-circle' },
|
|
|
|
|
|
{ text: '1 笔出租车费用超差旅标准 ¥28', level: '中', tone: 'medium', icon: 'mdi mdi-alert' },
|
|
|
|
|
|
{ text: '发票抬头识别为个人,建议核对', level: '中', tone: 'medium', icon: 'mdi mdi-lightbulb-on' }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const flowItems = [
|
|
|
|
|
|
{ label: '提交申请', desc: '刘思雨 提交申请', time: '07-11 08:46', icon: 'mdi mdi-check' },
|
|
|
|
|
|
{ label: '票据识别', desc: 'AI 自动识别完成', time: '07-11 08:48', icon: 'mdi mdi-check' },
|
|
|
|
|
|
{ label: '费用归类', desc: '费用归类完成', time: '07-11 08:49', icon: 'mdi mdi-check' },
|
|
|
|
|
|
{ label: '部门负责人审批', desc: '李文静 已通过', time: '07-11 11:28', icon: 'mdi mdi-check' },
|
|
|
|
|
|
{ label: '财务审批', desc: '张晓明 审批中', time: '进行中', icon: 'mdi mdi-circle-slice-8', current: true },
|
|
|
|
|
|
{ label: '归档入账', desc: '待处理', time: '-', icon: 'mdi mdi-circle-outline', pending: true }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
activeTab,
|
|
|
|
|
|
selectedRow,
|
|
|
|
|
|
expandedExpenseId,
|
|
|
|
|
|
tabs,
|
|
|
|
|
|
filters,
|
|
|
|
|
|
rows,
|
|
|
|
|
|
visibleRows,
|
|
|
|
|
|
approvalSteps,
|
|
|
|
|
|
summaryItems,
|
|
|
|
|
|
heroSummaryItems,
|
|
|
|
|
|
currentProgressRingMotion,
|
|
|
|
|
|
expenseItems,
|
|
|
|
|
|
expenseTotal,
|
|
|
|
|
|
uploadedExpenseCount,
|
|
|
|
|
|
showExpenseRisk,
|
|
|
|
|
|
toggleExpenseAttachments,
|
|
|
|
|
|
attachments,
|
|
|
|
|
|
riskItems,
|
|
|
|
|
|
flowItems
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-09 03:04:09 +00:00
|
|
|
|
|