import { buildFileIdentity } from '../../views/scripts/travelReimbursementAttachmentModel.js' export const AI_COMPOSER_FILE_TYPE_META = { pdf: { label: 'PDF', icon: 'mdi mdi-file-pdf-box', tone: 'pdf' }, image: { label: '图片', icon: 'mdi mdi-file-image-outline', tone: 'image' }, spreadsheet: { label: '表格', icon: 'mdi mdi-file-excel-outline', tone: 'spreadsheet' }, document: { label: '文档', icon: 'mdi mdi-file-document-outline', tone: 'document' }, archive: { label: '压缩包', icon: 'mdi mdi-folder-zip-outline', tone: 'archive' }, file: { label: '文件', icon: 'mdi mdi-file-outline', tone: 'file' } } export const AI_MODE_ACTION_ITEMS = [ { label: '发起报销', icon: 'mdi mdi-file-document-plus-outline', prompt: '帮我发起一笔报销,并检查需要准备哪些票据材料。', source: 'workbench', sessionType: 'expense' }, { label: '查询预算', icon: 'mdi mdi-chart-pie-outline', prompt: '帮我查询当前预算余额和近期费用占用情况。', source: 'budget', sessionType: 'budget' }, { label: '解释制度', icon: 'mdi mdi-book-open-page-variant-outline', prompt: '帮我解释公司报销制度,并列出这次需要注意的条款。', source: 'workbench', sessionType: 'knowledge' }, { label: '催办审批', icon: 'mdi mdi-bell-ring-outline', prompt: '帮我查询待审批单据,并生成一段礼貌的催办说明。', source: 'workbench', sessionType: 'approval' } ] export function resolveAiComposerFileName(file) { return String(file?.name || '未命名附件').trim() || '未命名附件' } export function resolveAiComposerFileType(file) { const fileName = resolveAiComposerFileName(file).toLowerCase() const mimeType = String(file?.type || '').toLowerCase() const extension = fileName.includes('.') ? fileName.split('.').pop() : '' if (extension === 'pdf' || mimeType.includes('pdf')) { return AI_COMPOSER_FILE_TYPE_META.pdf } if (/^(png|jpe?g|gif|webp|bmp|svg|heic)$/.test(extension) || mimeType.startsWith('image/')) { return AI_COMPOSER_FILE_TYPE_META.image } if (/^(xls|xlsx|csv|numbers)$/.test(extension) || mimeType.includes('spreadsheet') || mimeType.includes('excel')) { return AI_COMPOSER_FILE_TYPE_META.spreadsheet } if (/^(doc|docx|txt|md|pages)$/.test(extension) || mimeType.includes('word') || mimeType.includes('text')) { return AI_COMPOSER_FILE_TYPE_META.document } if (/^(zip|rar|7z|tar|gz)$/.test(extension) || mimeType.includes('zip') || mimeType.includes('compressed')) { return AI_COMPOSER_FILE_TYPE_META.archive } return AI_COMPOSER_FILE_TYPE_META.file } export function buildSelectedFileCards(files = []) { return files.map((file) => ({ key: buildFileIdentity(file), name: resolveAiComposerFileName(file), ...resolveAiComposerFileType(file) })) } export function isLikelyAiModeOcrFile(file = {}) { const name = String(file?.name || '').trim() const type = String(file?.type || '').trim() return /\.(pdf|jpe?g|png|webp|bmp)$/i.test(name) || /^(image\/|application\/pdf)/i.test(type) } export function isLikelyReceiptAssociationFile(file = {}) { return isLikelyAiModeOcrFile(file) } export function shouldKeepAiAttachmentInAssistantReply(prompt = '') { const compact = String(prompt || '').replace(/\s+/g, '') return /(OCR|ocr|识别|票面|票据内容|发票内容|文字|读一下|看一下)/.test(compact) } export function shouldRunAiAttachmentAutoAssociation(entry = {}, files = [], prompt = '') { return Boolean( Array.isArray(files) && files.length && files.every((file) => isLikelyReceiptAssociationFile(file)) && !shouldKeepAiAttachmentInAssistantReply(prompt) && String(entry?.sessionType || '').trim() === 'steward' ) }