Files
X-Financial/web/src/utils/aiConversationLegacyAttachmentRenderer.js
2026-06-22 11:58:53 +08:00

88 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
function stripInlineMarkdownMarkers(value = '') {
return String(value || '')
.replace(/\*\*/g, '')
.replace(/`/g, '')
.trim()
}
function resolveLegacyAttachmentAssociationField(text = '', label = '') {
const escapedLabel = String(label || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
const match = String(text || '').match(new RegExp(`${escapedLabel}[:]\\s*([^\\n]+)`, 'u'))
return stripInlineMarkdownMarkers(match?.[1] || '')
}
function renderLegacyAttachmentAssociationField(label = '', value = '', options = {}, context = {}) {
const text = String(value || '').trim()
if (!text) {
return ''
}
return [
`<div class="ai-document-card__field${options.wide ? ' ai-document-card__field--wide' : ''}">`,
`<span class="ai-document-card__label">${context.escapeHtml(label)}</span>`,
`<strong class="ai-document-card__value${options.muted ? ' ai-attachment-association__muted' : ''}">${context.escapeHtml(text)}</strong>`,
'</div>'
].join('')
}
function isNoisyLegacyAssociationText(value = '') {
const text = String(value || '').replace(/\s+/g, '').trim()
if (!text) {
return true
}
if (!/[\u4e00-\u9fa5A-Za-z]/.test(text)) {
return true
}
if (/^[:;,.\-\d]+$/.test(text)) {
return true
}
if (/^[:;]/.test(text) && /\d{6,}/.test(text)) {
return true
}
return false
}
function normalizeLegacyAssociationDescription(value = '') {
const text = stripInlineMarkdownMarkers(value).replace(/\s+/g, ' ').trim()
return isNoisyLegacyAssociationText(text) ? '' : text
}
export function renderLegacyAttachmentAssociationHtml(content = '', options = {}) {
const context = {
escapeHtml: options.escapeHtml || ((item) => String(item || ''))
}
const text = String(content || '')
if (!/我已先识别票据,并匹配到最可能的报销单/.test(text)) {
return ''
}
const attachment = resolveLegacyAttachmentAssociationField(text, '本次附件')
const summary = resolveLegacyAttachmentAssociationField(text, '识别摘要')
const claimNo = resolveLegacyAttachmentAssociationField(text, '推荐关联')
const reason = normalizeLegacyAssociationDescription(resolveLegacyAttachmentAssociationField(text, '单据事项'))
const basis = resolveLegacyAttachmentAssociationField(text, '匹配依据')
return [
'<div class="ai-html-flow">',
'<p class="ai-html-paragraph">我已先识别票据,并找到一张可能关联的报销单。请确认是否自动归集:</p>',
'<section class="ai-document-card-list" aria-label="票据关联确认">',
'<article class="ai-document-card ai-attachment-association-card is-warning">',
'<header class="ai-document-card__head">',
'<strong class="ai-document-card__reason">可能关联单据</strong>',
'<span class="ai-document-card__status">待确认</span>',
'</header>',
'<div class="ai-document-card__body">',
'<div class="ai-document-card__details ai-attachment-association__details">',
renderLegacyAttachmentAssociationField('推荐单据', claimNo, {}, context),
renderLegacyAttachmentAssociationField('本次附件', attachment, {}, context),
renderLegacyAttachmentAssociationField('识别摘要', summary, { wide: true, muted: true }, context),
renderLegacyAttachmentAssociationField('关联事项', reason, { wide: true }, context),
renderLegacyAttachmentAssociationField('匹配依据', basis, { wide: true, muted: true }, context),
'</div>',
'<div class="ai-attachment-association__note">如果这就是要归集的单据,可直接使用下方快捷按钮;不确定时也可以先查看单据。</div>',
'</div>',
'</article>',
'</section>',
'</div>'
].join('')
}