feat: 增强知识库索引与设置页面模块化拆分
扩展知识库索引任务和 RAG 检索支持增量入库和文档去重,优 化本体检测和规则匹配精度,前端设置页面拆分为 LLM、邮件 和 Hermes 员工同步子面板并重构样式,新增日志详情组件和 知识入库日志模型,补充单元测试覆盖。
This commit is contained in:
@@ -93,8 +93,11 @@ import {
|
||||
buildReviewStateLabel,
|
||||
buildReviewStateTone,
|
||||
buildReviewPlainFollowupCopy,
|
||||
buildReviewNextStepRichCopy,
|
||||
buildReviewRiskLevelCounts,
|
||||
resolveReviewFooterActions,
|
||||
resolveReviewSaveDraftAction,
|
||||
resolveReviewNextStepAction,
|
||||
buildReviewPrimaryButtonLabel,
|
||||
buildReviewIntentText,
|
||||
buildReviewSceneValue,
|
||||
@@ -129,6 +132,7 @@ import {
|
||||
buildOcrSummaryFromDocuments,
|
||||
buildReviewFilePreviewsFromReviewPayload,
|
||||
extractReviewAttachmentNames,
|
||||
isTemporaryPreviewUrl,
|
||||
mergeFilePreviews,
|
||||
mergeFilesWithLimit,
|
||||
mergeUploadAttachmentNames,
|
||||
@@ -169,6 +173,11 @@ const REVIEW_RISK_LEVEL_META = {
|
||||
icon: 'mdi mdi-alert-circle-outline',
|
||||
suggestion: '提交前建议核对业务真实性、附件完整性和规则口径。'
|
||||
},
|
||||
info: {
|
||||
label: '提示',
|
||||
icon: 'mdi mdi-information-outline',
|
||||
suggestion: '该项主要用于辅助判断,可结合当前单据情况简单核对。'
|
||||
},
|
||||
low: {
|
||||
label: '低风险',
|
||||
icon: 'mdi mdi-information-outline',
|
||||
@@ -184,6 +193,9 @@ const REVIEW_DRAWER_MODE_FLOW = 'flow'
|
||||
const REVIEW_PANEL_SCOPE_OVERVIEW = 'overview'
|
||||
const REVIEW_PANEL_SCOPE_DOCUMENTS = 'documents'
|
||||
const REVIEW_PANEL_SCOPE_RISK = 'risk'
|
||||
const REVIEW_NEXT_STEP_HREF = '#review-next-step'
|
||||
const REVIEW_RISK_PANEL_HREF_PREFIX = '#review-risk'
|
||||
const REVIEW_QUICK_EDIT_HREF = '#review-quick-edit'
|
||||
const FLOW_STEP_STATUS_PENDING = 'pending'
|
||||
const FLOW_STEP_STATUS_RUNNING = 'running'
|
||||
const FLOW_STEP_STATUS_COMPLETED = 'completed'
|
||||
@@ -326,15 +338,6 @@ function buildReviewFactCards(reviewPayload, inlineState = createEmptyInlineRevi
|
||||
modelKey: 'scene_label',
|
||||
placeholder: '请选择场景'
|
||||
},
|
||||
{
|
||||
key: 'customer_name',
|
||||
label: '关联客户',
|
||||
value: String(inlineState.customer_name || '').trim() || '待补充',
|
||||
icon: 'mdi mdi-domain',
|
||||
editor: 'text',
|
||||
modelKey: 'customer_name',
|
||||
placeholder: '请输入客户名称'
|
||||
},
|
||||
{
|
||||
key: 'attachments',
|
||||
label: '票据状态',
|
||||
@@ -346,8 +349,20 @@ function buildReviewFactCards(reviewPayload, inlineState = createEmptyInlineRevi
|
||||
}
|
||||
]
|
||||
|
||||
if (shouldShowReviewFactCard(reviewPayload, 'customer_name', inlineState.customer_name)) {
|
||||
cards.splice(cards.length - 1, 0, {
|
||||
key: 'customer_name',
|
||||
label: '关联客户',
|
||||
value: String(inlineState.customer_name || '').trim() || '待补充',
|
||||
icon: 'mdi mdi-domain',
|
||||
editor: 'text',
|
||||
modelKey: 'customer_name',
|
||||
placeholder: '请输入客户名称'
|
||||
})
|
||||
}
|
||||
|
||||
if (shouldShowReviewFactCard(reviewPayload, 'location', inlineState.location)) {
|
||||
cards.splice(4, 0, {
|
||||
cards.splice(cards.length - 1, 0, {
|
||||
key: 'location',
|
||||
label: '业务地点',
|
||||
value: String(inlineState.location || '').trim() || '待补充',
|
||||
@@ -432,18 +447,19 @@ function buildReviewRiskConversationText(item, detailTarget = {}) {
|
||||
const summary = String(item?.summary || '').trim()
|
||||
const detail = String(item?.detail || '').trim()
|
||||
const suggestion = String(item?.suggestion || '').trim()
|
||||
const isInfo = String(item?.level || '').trim() === 'info'
|
||||
const detailHref = String(detailTarget?.href || '').trim()
|
||||
const detailLabel = String(detailTarget?.label || '').trim() || '进入该单据详情重新填写'
|
||||
const lines = [`${title}`]
|
||||
|
||||
if (summary) {
|
||||
lines.push('', `风险点:${summary}`)
|
||||
lines.push('', `${isInfo ? '提示内容' : '风险点'}:${summary}`)
|
||||
}
|
||||
if (detail && detail !== summary) {
|
||||
lines.push('', `规则依据:${detail}`)
|
||||
}
|
||||
if (suggestion) {
|
||||
lines.push('', `修改建议:${suggestion}`)
|
||||
lines.push('', `${isInfo ? '处理建议' : '修改建议'}:${suggestion}`)
|
||||
}
|
||||
if (detailHref) {
|
||||
lines.push('', `[${detailLabel}](${detailHref})`)
|
||||
@@ -539,6 +555,11 @@ export default {
|
||||
getSessionRuntimeRefs: () => sessionRuntimeRefs
|
||||
})
|
||||
const deleteSessionDialogOpen = ref(false)
|
||||
const nextStepConfirmDialog = ref({
|
||||
open: false,
|
||||
message: null,
|
||||
action: null
|
||||
})
|
||||
const reviewActionBusy = ref(false)
|
||||
const deleteSessionBusy = ref(false)
|
||||
const reviewDrawerMode = ref(REVIEW_DRAWER_MODE_REVIEW)
|
||||
@@ -839,6 +860,7 @@ export default {
|
||||
extractReviewAttachmentNames,
|
||||
mergeFilesWithLimit,
|
||||
mergeFilePreviews,
|
||||
isTemporaryPreviewUrl,
|
||||
resolveAttachmentPreviewKind,
|
||||
resolveDocumentPreview,
|
||||
buildFilePreviews,
|
||||
@@ -1418,9 +1440,10 @@ export default {
|
||||
nextTick(scrollToBottom)
|
||||
}
|
||||
|
||||
function resolveReviewRiskDetailTarget() {
|
||||
function resolveReviewDetailTarget(message = null) {
|
||||
const latestDraftMessage = [...messages.value].reverse().find((item) => item?.draftPayload)
|
||||
const candidates = [
|
||||
message?.draftPayload,
|
||||
currentInsight.value.agent?.draftPayload,
|
||||
latestReviewMessage.value?.draftPayload,
|
||||
latestDraftMessage?.draftPayload,
|
||||
@@ -1443,6 +1466,74 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveReviewRiskDetailTarget() {
|
||||
return resolveReviewDetailTarget()
|
||||
}
|
||||
|
||||
function buildReviewNextStepRichCopyForMessage(message) {
|
||||
const target = resolveReviewDetailTarget(message)
|
||||
return buildReviewNextStepRichCopy(message?.reviewPayload, {
|
||||
detailHref: target.href || ''
|
||||
})
|
||||
}
|
||||
|
||||
function buildMessageBubbleClass(message) {
|
||||
if (message?.role !== 'assistant' || !resolveReviewNextStepAction(message?.reviewPayload)) {
|
||||
return ''
|
||||
}
|
||||
const counts = buildReviewRiskLevelCounts(message.reviewPayload)
|
||||
if (counts.high > 0) {
|
||||
return 'message-bubble-review-risk-high'
|
||||
}
|
||||
if (counts.medium > 0) {
|
||||
return 'message-bubble-review-risk-medium'
|
||||
}
|
||||
if (counts.low > 0) {
|
||||
return 'message-bubble-review-risk-low'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function openReviewNextStepConfirm(message) {
|
||||
const action = resolveReviewNextStepAction(message?.reviewPayload)
|
||||
if (!action) {
|
||||
return
|
||||
}
|
||||
nextStepConfirmDialog.value = {
|
||||
open: true,
|
||||
message,
|
||||
action
|
||||
}
|
||||
}
|
||||
|
||||
function closeReviewNextStepConfirm() {
|
||||
if (reviewActionBusy.value) {
|
||||
return
|
||||
}
|
||||
nextStepConfirmDialog.value = {
|
||||
open: false,
|
||||
message: null,
|
||||
action: null
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmReviewNextStepSubmit() {
|
||||
const message = nextStepConfirmDialog.value.message
|
||||
const action = nextStepConfirmDialog.value.action
|
||||
if (!message || !action || reviewActionBusy.value) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await handleReviewActionInternal(message, action)
|
||||
} finally {
|
||||
nextStepConfirmDialog.value = {
|
||||
open: false,
|
||||
message: null,
|
||||
action: null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isWorkbenchBusy() {
|
||||
return submitting.value || reviewActionBusy.value || sessionSwitchBusy.value
|
||||
}
|
||||
@@ -1665,6 +1756,31 @@ export default {
|
||||
}
|
||||
|
||||
const href = String(anchor.getAttribute('href') || '').trim()
|
||||
if (href === REVIEW_NEXT_STEP_HREF) {
|
||||
event.preventDefault()
|
||||
openReviewNextStepConfirm(message)
|
||||
return
|
||||
}
|
||||
|
||||
if (href.startsWith(REVIEW_RISK_PANEL_HREF_PREFIX)) {
|
||||
event.preventDefault()
|
||||
if (reviewRiskDrawerAvailable.value) {
|
||||
switchReviewDrawerMode(REVIEW_DRAWER_MODE_RISK)
|
||||
} else {
|
||||
toast('当前没有需要额外处理的风险信息。')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (href === REVIEW_QUICK_EDIT_HREF) {
|
||||
event.preventDefault()
|
||||
if (reviewOverviewDrawerAvailable.value) {
|
||||
switchReviewDrawerMode(REVIEW_DRAWER_MODE_REVIEW)
|
||||
toast('已打开右侧核对信息,可以直接修改当前单据。')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (href.startsWith('/app/')) {
|
||||
event.preventDefault()
|
||||
router.push(href)
|
||||
@@ -1738,12 +1854,12 @@ export default {
|
||||
reviewDrawerTitle, reviewOverviewDrawerAvailable, reviewDocumentDrawerAvailable, reviewRiskDrawerAvailable, reviewFlowDrawerAvailable, reviewDocumentDrawerLabel, reviewDocumentDrawerIcon, reviewRiskDrawerLabel, reviewRiskDrawerIcon, reviewFlowDrawerLabel, reviewFlowDrawerIcon, activeReviewDocument, activeReviewDocumentIndex, activeReviewDocumentPreview, canPreviewActiveReviewDocument,
|
||||
reviewIntentText, reviewFactCards, reviewCategoryOptions, reviewOtherCategoryOptions, reviewSelectedOtherCategory, reviewInlineDirty, reviewInlineForm, reviewInlineEditorKey, reviewInlineErrors, reviewOtherCategoryOpen, reviewInlinePendingFiles, DATE_INPUT_FORMAT, REVIEW_SCENE_OTHER_OPTION, REVIEW_SCENE_OPTIONS, REVIEW_OTHER_CATEGORY_OPTIONS,
|
||||
workbenchVisible, reviewPanelConfidence, reviewRiskSummary, reviewRiskItems, reviewRiskEmpty, recognizedNarratives, reviewRecognitionNotes, reviewDocumentSummaries, reviewDocumentCount, reviewDocumentDirty, reviewHasUnsavedChanges,
|
||||
travelCalculatorOpen, travelCalculatorBusy, travelCalculatorError, travelCalculatorResult, travelCalculatorForm, travelCalculatorCanSubmit, deleteSessionDialogOpen, reviewActionBusy, deleteSessionBusy, documentPreviewDialog, shortcuts,
|
||||
resolveReviewMissingSlotCards, resolveReviewRiskBriefs, buildReviewHeadline, buildReviewSubline, buildReviewStateLabel, buildReviewStateTone, buildReviewPlainFollowupCopy, buildReviewPlainFollowupForMessage, resolveReviewFooterActions, resolveReviewSaveDraftAction, buildReviewPrimaryButtonLabel, buildReviewMainMessageText,
|
||||
travelCalculatorOpen, travelCalculatorBusy, travelCalculatorError, travelCalculatorResult, travelCalculatorForm, travelCalculatorCanSubmit, deleteSessionDialogOpen, nextStepConfirmDialog, reviewActionBusy, deleteSessionBusy, documentPreviewDialog, shortcuts,
|
||||
resolveReviewMissingSlotCards, resolveReviewRiskBriefs, buildReviewHeadline, buildReviewSubline, buildReviewStateLabel, buildReviewStateTone, buildReviewPlainFollowupCopy, buildReviewPlainFollowupForMessage, buildReviewNextStepRichCopyForMessage, buildMessageBubbleClass, resolveReviewFooterActions, resolveReviewSaveDraftAction, buildReviewPrimaryButtonLabel, buildReviewMainMessageText,
|
||||
renderMarkdown, buildExpenseQueryWindowLabel, buildExpenseQueryHint, getExpenseQueryActivePage, getExpenseQueryTotalPages, getExpenseQueryVisibleRecords, resolveDocumentPreview, triggerFileUpload, applyComposerDateSelection, handleFilesChange, handleComposerInput, handleComposerEnter, runShortcut, runWelcomeQuickAction: runShortcut, handleSuggestedAction, isSuggestedActionSelected, askHotKnowledgeQuestion, resolveKnowledgeRankLabel, resolveKnowledgeRankTone,
|
||||
refreshFlowRunDetail, formatFlowStepDuration, resolveFlowStepStatusLabel, resolveFlowStepDetail, toggleInsightPanel, openTravelCalculator, toggleTravelCalculator, closeTravelCalculator, submitTravelCalculator, switchToReviewOverviewDrawer, toggleReviewDocumentDrawer, toggleReviewRiskDrawer, toggleReviewFlowDrawer, toggleAttachedFilesExpanded, removeAttachedFile, clearAttachedFiles,
|
||||
requestCloseWorkbench, emitCloseAfterLeave, handleAssistantModalAfterEnter, openExpenseQueryRecord, handleExpenseQueryRecordClick, setExpenseQueryPage, shiftExpenseQueryPage, openDeleteSessionDialog, closeDeleteSessionDialog, confirmDeleteCurrentSession, openInlineReviewEditor, closeInlineReviewEditor, commitInlineReviewEditor, clearInlineReviewFieldError, selectInlineScene, selectReviewCategory, selectReviewOtherCategory,
|
||||
queryDraftByClaimNo, appendReviewRiskBriefToConversation, appendExpenseQueryRiskToConversation, goReviewDocument, openActiveReviewDocumentPreview, closeDocumentPreview, saveInlineReviewChanges, submitComposer, handleAssistantMarkdownClick, handleReviewAction, handleSaveDraftDirectly, isDraftSavedReviewMessage, canUseInlineSaveDraft, handleInlineSaveDraft
|
||||
queryDraftByClaimNo, appendReviewRiskBriefToConversation, appendExpenseQueryRiskToConversation, goReviewDocument, openActiveReviewDocumentPreview, closeDocumentPreview, saveInlineReviewChanges, submitComposer, handleAssistantMarkdownClick, handleReviewAction, handleSaveDraftDirectly, closeReviewNextStepConfirm, confirmReviewNextStepSubmit, isDraftSavedReviewMessage, canUseInlineSaveDraft, handleInlineSaveDraft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user