feat: 新增归档中心页面并完善知识库与报销查询能力
新增前端归档中心视图及相关工具函数,扩充知识库文档分类和 提取器支持多种格式,增强编排器报销查询的多维度检索,优 化本体规则和用户代理审核消息,前端完善报销创建和审批详 情交互细节,补充单元测试覆盖。
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
} from './travelReimbursementReviewModel.js'
|
||||
|
||||
export const EXPENSE_QUERY_PAGE_SIZE = 5
|
||||
export const EXPENSE_CENTER_HREF = '/app/requests'
|
||||
export const ASSOCIATABLE_CLAIM_STATUSES = new Set(['draft', 'supplement', 'returned'])
|
||||
const EXPENSE_STATUS_LABELS = {
|
||||
draft: '草稿',
|
||||
@@ -14,6 +15,36 @@ const EXPENSE_STATUS_LABELS = {
|
||||
approved: '已审核',
|
||||
paid: '已入账'
|
||||
}
|
||||
const EXPENSE_RISK_LEVEL_LABELS = {
|
||||
high: '高风险',
|
||||
medium: '中风险',
|
||||
warning: '中风险',
|
||||
low: '低风险',
|
||||
info: '低风险'
|
||||
}
|
||||
|
||||
export function normalizeExpenseQueryRiskItem(item, index = 0) {
|
||||
if (!item || typeof item !== 'object') {
|
||||
return null
|
||||
}
|
||||
|
||||
const rawLevel = String(item.level || item.severity || '').trim().toLowerCase()
|
||||
const level = EXPENSE_RISK_LEVEL_LABELS[rawLevel] ? rawLevel : 'medium'
|
||||
const summary = String(item.summary || item.message || item.content || '').trim()
|
||||
const detail = String(item.detail || item.description || summary).trim()
|
||||
if (!summary && !detail) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
key: String(item.key || `${level}-${index}`).trim() || `${level}-${index}`,
|
||||
level,
|
||||
levelLabel: String(item.level_label || item.levelLabel || EXPENSE_RISK_LEVEL_LABELS[level]).trim() || EXPENSE_RISK_LEVEL_LABELS[level],
|
||||
title: String(item.title || item.label || EXPENSE_RISK_LEVEL_LABELS[level]).trim() || EXPENSE_RISK_LEVEL_LABELS[level],
|
||||
summary: summary || detail,
|
||||
detail: detail || summary
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeExpenseQueryStatusGroup(item) {
|
||||
if (!item || typeof item !== 'object') {
|
||||
@@ -57,6 +88,9 @@ export function normalizeExpenseQueryRecord(item) {
|
||||
occurredAt,
|
||||
reason,
|
||||
location: String(item.location || '').trim(),
|
||||
riskItems: (Array.isArray(item.risk_flags) ? item.risk_flags : [])
|
||||
.map((riskItem, index) => normalizeExpenseQueryRiskItem(riskItem, index))
|
||||
.filter(Boolean),
|
||||
summary: reason || `${expenseTypeLabel}报销`,
|
||||
dateDisplay: documentDate || occurredAt || '待补充日期'
|
||||
}
|
||||
@@ -164,6 +198,7 @@ export function normalizeExpenseQueryPayload(payload) {
|
||||
|
||||
const rawRecordCount = Number(payload.record_count || 0)
|
||||
const rawPreviewCount = Number(payload.preview_count || records.length)
|
||||
const rawPreviewLimit = Number(payload.preview_limit || EXPENSE_QUERY_PAGE_SIZE)
|
||||
const rawOlderRecordCount = Number(payload.older_record_count || 0)
|
||||
const totalAmount = Number(payload.total_amount || 0)
|
||||
const rawWindowDays = Number(payload.window_days || 0)
|
||||
@@ -187,6 +222,7 @@ export function normalizeExpenseQueryPayload(payload) {
|
||||
windowEndDate: windowEndDate || '',
|
||||
recordCount: Number.isFinite(rawRecordCount) ? Math.max(0, rawRecordCount) : 0,
|
||||
previewCount: Number.isFinite(rawPreviewCount) ? Math.max(0, rawPreviewCount) : records.length,
|
||||
previewLimit: Number.isFinite(rawPreviewLimit) ? Math.max(1, rawPreviewLimit) : EXPENSE_QUERY_PAGE_SIZE,
|
||||
olderRecordCount: Number.isFinite(rawOlderRecordCount) ? Math.max(0, rawOlderRecordCount) : 0,
|
||||
hasMoreInWindow: Boolean(payload.has_more_in_window || payload.has_more),
|
||||
totalAmount: Number.isFinite(totalAmount) ? totalAmount : 0,
|
||||
@@ -250,18 +286,13 @@ export function buildExpenseQueryHint(queryPayload) {
|
||||
}
|
||||
|
||||
const parts = []
|
||||
const windowText = buildExpenseQueryWindowLabel(queryPayload)
|
||||
const previewLimit = Math.max(1, Number(queryPayload.previewLimit || EXPENSE_QUERY_PAGE_SIZE))
|
||||
const totalCount = Math.max(0, Number(queryPayload.recordCount || 0))
|
||||
|
||||
if (Array.isArray(queryPayload.records) && queryPayload.records.length > EXPENSE_QUERY_PAGE_SIZE) {
|
||||
parts.push(`当前共整理 ${queryPayload.records.length} 笔单据,可左右切换查看`)
|
||||
}
|
||||
|
||||
if (queryPayload.hasMoreInWindow && queryPayload.previewCount < queryPayload.recordCount) {
|
||||
parts.push(`${windowText}共 ${queryPayload.recordCount} 笔,当前先整理最近 ${queryPayload.previewCount} 笔`)
|
||||
}
|
||||
|
||||
if (queryPayload.olderRecordCount > 0 && queryPayload.windowDays) {
|
||||
parts.push(`另有 ${queryPayload.olderRecordCount} 笔超过 ${queryPayload.windowDays} 日的单据,请前往个人报销中心查看`)
|
||||
if (totalCount > previewLimit) {
|
||||
parts.push(`我只会筛选出最近的 ${previewLimit} 条记录;如果想查询全部的单据,请点击 [**这里**](${EXPENSE_CENTER_HREF}) 跳转到报销中心查看。`)
|
||||
} else if (totalCount > 0) {
|
||||
parts.push(`当前已展示本次筛选命中的全部记录;如果想进入报销中心继续筛选,请点击 [**这里**](${EXPENSE_CENTER_HREF})。`)
|
||||
}
|
||||
|
||||
return parts.join('。')
|
||||
|
||||
Reference in New Issue
Block a user