feat: 新增归档中心页面并完善知识库与报销查询能力
新增前端归档中心视图及相关工具函数,扩充知识库文档分类和 提取器支持多种格式,增强编排器报销查询的多维度检索,优 化本体规则和用户代理审核消息,前端完善报销创建和审批详 情交互细节,补充单元测试覆盖。
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
|
||||
import { fetchExpenseClaims } from '../services/reimbursements.js'
|
||||
import { filterActionableRiskFlags } from '../utils/riskFlags.js'
|
||||
|
||||
const EXPENSE_TYPE_LABELS = {
|
||||
travel: '差旅费',
|
||||
train_ticket: '火车票',
|
||||
flight_ticket: '机票',
|
||||
ship_ticket: '轮船票',
|
||||
ferry_ticket: '轮船票',
|
||||
hotel_ticket: '住宿票',
|
||||
ride_ticket: '乘车',
|
||||
travel_allowance: '出差补贴',
|
||||
@@ -31,6 +34,8 @@ const LOCATION_REQUIRED_EXPENSE_TYPES = new Set([
|
||||
|
||||
const SYSTEM_GENERATED_EXPENSE_TYPES = new Set(['travel_allowance'])
|
||||
const LONG_DISTANCE_TRAVEL_EXPENSE_TYPES = new Set(['train_ticket', 'flight_ticket'])
|
||||
const ROUTE_DESCRIPTION_EXPENSE_TYPES = new Set(['train_ticket', 'flight_ticket', 'ship_ticket', 'ferry_ticket', 'ride_ticket'])
|
||||
const HOTEL_DESCRIPTION_EXPENSE_TYPES = new Set(['hotel_ticket'])
|
||||
|
||||
const REIMBURSEMENT_PROGRESS_LABELS = [
|
||||
'创建单据',
|
||||
@@ -135,6 +140,17 @@ function resolveLocationDisplay(location, typeCode) {
|
||||
return isLocationRequiredExpenseType(typeCode) ? '待补充' : '非必填'
|
||||
}
|
||||
|
||||
function resolveExpenseDescriptionDetail(itemType, itemLocation) {
|
||||
const normalizedType = normalizeExpenseType(itemType)
|
||||
if (ROUTE_DESCRIPTION_EXPENSE_TYPES.has(normalizedType)) {
|
||||
return '起始地-目的地'
|
||||
}
|
||||
if (HOTEL_DESCRIPTION_EXPENSE_TYPES.has(normalizedType)) {
|
||||
return '目的地酒店'
|
||||
}
|
||||
return resolveLocationDisplay(itemLocation, normalizedType)
|
||||
}
|
||||
|
||||
function resolveExpenseItemViewId(item, index, claim) {
|
||||
return String(item?.id || `${claim?.id || 'claim'}-item-${index}`)
|
||||
}
|
||||
@@ -273,7 +289,7 @@ function buildRiskSummary(riskFlags) {
|
||||
return '无'
|
||||
}
|
||||
|
||||
const items = riskFlags.map((item) => stringifyRiskFlag(item)).filter(Boolean)
|
||||
const items = filterActionableRiskFlags(riskFlags).map((item) => stringifyRiskFlag(item)).filter(Boolean)
|
||||
return items.length ? items.join(';') : '无'
|
||||
}
|
||||
|
||||
@@ -602,7 +618,7 @@ function buildExpenseItems(claim, riskSummary) {
|
||||
name: itemTypeLabel,
|
||||
category: itemTypeLabel,
|
||||
desc: itemReason || '待补充',
|
||||
detail: resolveLocationDisplay(itemLocation, itemType),
|
||||
detail: resolveExpenseDescriptionDetail(itemType, itemLocation),
|
||||
amount: itemAmountDisplay,
|
||||
status: isSystemGenerated ? '系统计算' : attachments.length ? '已识别' : '待补充',
|
||||
tone: isSystemGenerated ? 'system' : attachments.length ? 'ok' : 'bad',
|
||||
@@ -654,6 +670,7 @@ export function mapExpenseClaimToRequest(claim) {
|
||||
applyTime: formatDateTime(applyDateTime) || '待补充',
|
||||
submittedAt: applyDateTime || '',
|
||||
createdAt: claim?.created_at || '',
|
||||
updatedAt: claim?.updated_at || '',
|
||||
amount: parseNumber(claim?.amount),
|
||||
riskFlags: Array.isArray(claim?.risk_flags_json) ? claim.risk_flags_json : [],
|
||||
invoiceCount,
|
||||
|
||||
Reference in New Issue
Block a user