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

142 lines
4.5 KiB
JavaScript

import { isApplicationDocumentNo } from './documentClassification.js'
export const AI_DOCUMENT_DETAIL_HREF_PREFIX = '#ai-open-document-detail:'
export const AI_APPLICATION_DETAIL_HREF_PREFIX = '#ai-open-application-detail:'
const SHORT_BUSINESS_DOCUMENT_NO_PATTERN = /^(?:A|R|D)[A-HJ-NP-Z2-9]{8}$/
const LEGACY_BUSINESS_DOCUMENT_NO_PATTERN = /^(?:AP|APP|RE|AD|EXP|CL|BX)-/
function normalizeText(value = '') {
return String(value ?? '').trim()
}
export function isBusinessDocumentReference(value = '') {
const text = normalizeText(value)
return Boolean(
text &&
(
SHORT_BUSINESS_DOCUMENT_NO_PATTERN.test(text) ||
LEGACY_BUSINESS_DOCUMENT_NO_PATTERN.test(text)
)
)
}
function parseDetailReferencePayload(reference = '', options = {}) {
const text = normalizeText(reference)
if (!text) {
return null
}
const params = new URLSearchParams(text)
const claimId = normalizeText(params.get('claim_id') || params.get('claimId'))
const claimNo = normalizeText(
params.get('claim_no') ||
params.get('claimNo') ||
params.get('document_no') ||
params.get('documentNo')
)
const documentType = normalizeText(options.documentType)
if (claimId || claimNo) {
return {
reference: claimNo || claimId,
claimId,
claimNo,
...(documentType ? { documentType } : {})
}
}
return {
reference: text,
...(documentType ? { documentType } : {})
}
}
function parseAiDetailHref(href = '', prefix = '', options = {}) {
const value = normalizeText(href)
if (!value.startsWith(prefix)) {
return null
}
const encodedReference = value.slice(prefix.length)
if (!encodedReference) {
return null
}
try {
return parseDetailReferencePayload(decodeURIComponent(encodedReference), options)
} catch {
return parseDetailReferencePayload(encodedReference, options)
}
}
export function parseAiDocumentDetailHref(href = '') {
return parseAiDetailHref(href, AI_DOCUMENT_DETAIL_HREF_PREFIX)
}
export function parseAiApplicationDetailHref(href = '') {
return parseAiDetailHref(href, AI_APPLICATION_DETAIL_HREF_PREFIX, { documentType: 'application' })
}
function resolveExplicitClaimId(source = {}) {
const claimNo = normalizeText(source.claimNo || source.claim_no || source.documentNo || source.document_no)
const rawClaimId = normalizeText(source.claimId || source.claim_id || source.id)
if (!rawClaimId || rawClaimId === claimNo || isBusinessDocumentReference(rawClaimId)) {
return ''
}
return rawClaimId
}
export function buildAiDocumentDetailHref(source = {}, options = {}) {
const prefix = normalizeText(options.prefix) || AI_DOCUMENT_DETAIL_HREF_PREFIX
const claimId = resolveExplicitClaimId(source)
const claimNo = normalizeText(source.claimNo || source.claim_no || source.documentNo || source.document_no)
const fallback = normalizeText(source.reference)
if (claimId || claimNo) {
const params = new URLSearchParams()
if (claimId) {
params.set('claim_id', claimId)
}
if (claimNo) {
params.set('claim_no', claimNo)
}
return `${prefix}${encodeURIComponent(params.toString())}`
}
return fallback ? `${prefix}${encodeURIComponent(fallback)}` : ''
}
export function buildAiDocumentDetailRequest(detailReference = {}) {
const reference = normalizeText(detailReference.reference)
const explicitClaimId = resolveExplicitClaimId(detailReference)
const explicitClaimNo = normalizeText(
detailReference.claimNo ||
detailReference.claim_no ||
detailReference.documentNo ||
detailReference.document_no
)
const referenceIsBusinessNo = isBusinessDocumentReference(reference)
const claimId = explicitClaimId || (!referenceIsBusinessNo ? reference : '')
const claimNo = explicitClaimNo || (referenceIsBusinessNo ? reference : '')
const lookupReference = claimId || claimNo || reference
const displayReference = claimNo || reference || lookupReference
const documentTypeCode = normalizeText(
detailReference.documentTypeCode ||
detailReference.document_type_code ||
detailReference.documentType ||
detailReference.document_type
).toLowerCase()
const isApplication = documentTypeCode === 'application' || isApplicationDocumentNo(displayReference)
return {
id: lookupReference,
claimId,
claimNo,
documentNo: displayReference,
documentType: isApplication ? 'application' : 'reimbursement',
documentTypeCode: isApplication ? 'application' : 'reimbursement',
detailLookupOnly: true,
source: 'ai-conversation',
returnTo: 'conversation'
}
}