import { isBudgetMonitorUser, isExecutiveUser, isPlatformAdminUser } from '../../utils/accessControl.js' import { GUIDED_ACTION_OPEN_TRAVEL_CALCULATOR, GUIDED_ACTION_START_APPLICATION, GUIDED_ACTION_START_REIMBURSEMENT, GUIDED_ACTION_START_STATUS_QUERY } from './travelReimbursementGuidedFlowModel.js' export const SESSION_TYPE_EXPENSE = 'expense' export const SESSION_TYPE_APPLICATION = 'application' export const SESSION_TYPE_APPROVAL = 'approval' export const SESSION_TYPE_KNOWLEDGE = 'knowledge' export const SESSION_TYPE_BUDGET = 'budget' export const SESSION_TYPE_STEWARD = 'steward' export const ASSISTANT_SESSION_TYPES = [ SESSION_TYPE_STEWARD, SESSION_TYPE_APPLICATION, SESSION_TYPE_EXPENSE, SESSION_TYPE_APPROVAL, SESSION_TYPE_KNOWLEDGE, SESSION_TYPE_BUDGET ] export const ASSISTANT_SESSION_MODE_OPTIONS = [ { key: SESSION_TYPE_STEWARD, label: '小财管家', icon: 'mdi mdi-account-tie-outline', description: '统一拆解多任务、归集附件,并调度申请助手和报销助手' }, { key: SESSION_TYPE_APPLICATION, label: '申请助手', icon: 'mdi mdi-file-plus-outline', description: '只处理费用申请、事前审批、申请材料和申请状态' }, { key: SESSION_TYPE_EXPENSE, label: '报销助手', icon: 'mdi mdi-receipt-text-plus-outline', description: '只处理报销发起、票据识别、草稿归集和报销状态' }, { key: SESSION_TYPE_APPROVAL, label: '审核助手', icon: 'mdi mdi-clipboard-check-outline', description: '只处理待审单据、风险解释、审批动作和审核意见' }, { key: SESSION_TYPE_KNOWLEDGE, label: '财务知识助手', icon: 'mdi mdi-book-open-page-variant-outline', description: '只处理财务制度、标准规则、票据要求和政策解释' }, { key: SESSION_TYPE_BUDGET, label: '预算编制助手', icon: 'mdi mdi-calculator-variant-outline', description: '帮助你进行预算编制与预算相关问题的整理' } ] export function canUseBudgetAssistantSession(user = null) { return Boolean(isPlatformAdminUser(user) || isBudgetMonitorUser(user) || isExecutiveUser(user)) } function canUseAssistantSessionType(sessionType, user = null) { const normalized = String(sessionType || '').trim() if (normalized === SESSION_TYPE_BUDGET) { return canUseBudgetAssistantSession(user) } return true } export function filterAssistantSessionModes(sessionModes = [], user = null) { return Array.isArray(sessionModes) ? sessionModes.filter((mode) => canUseAssistantSessionType(mode?.key, user)) : [] } export function filterAssistantSessionTypes(sessionTypes = [], user = null) { return Array.isArray(sessionTypes) ? sessionTypes.filter((sessionType) => canUseAssistantSessionType(String(sessionType || '').trim(), user)) : [] } export function normalizeAssistantSessionType(sessionType, fallback = SESSION_TYPE_EXPENSE) { const normalized = String(sessionType || '').trim() if (ASSISTANT_SESSION_TYPES.includes(normalized)) { return normalized } const fallbackType = String(fallback || '').trim() return ASSISTANT_SESSION_TYPES.includes(fallbackType) ? fallbackType : SESSION_TYPE_EXPENSE } export function resolveAssistantSessionMode(sessionType) { const normalized = normalizeAssistantSessionType(sessionType) return ASSISTANT_SESSION_MODE_OPTIONS.find((item) => item.key === normalized) || ASSISTANT_SESSION_MODE_OPTIONS[1] } export const aiAvatar = '/assets/header.png' export const userAvatar = '/assets/person.png' export const SOURCE_LABELS = { workbench: '来自个人工作台', topbar: '来自发起报销', application: '来自发起申请', budget: '来自预算中心', detail: '来自智能录入', upload: '来自附件上传', requests: '来自报销列表' } export const SCENARIO_LABELS = { expense: '报销', accounts_receivable: '应收', accounts_payable: '应付', budget: '预算', knowledge: '知识', unknown: '通用' } export const INTENT_LABELS = { query: '查询', explain: '解释', compare: '对比', risk_check: '风险检查', draft: '信息核对', operate: '动作请求' } export const FLOW_STEP_FALLBACKS = { intent: { title: '意图识别', tool: 'IntentRecognizer', runningText: '正在识别业务意图...', completedText: '意图识别完成' }, extraction: { title: '信息提取', tool: 'SemanticExtractor', runningText: '正在提取时间、金额、费用类型和待补项...', completedText: '信息提取完成' }, ocr: { title: '票据/OCR识别', tool: 'OCRService', runningText: '正在识别票据附件...', completedText: '票据识别完成' }, 'expense-review-preview': { title: '报销信息核对', tool: 'user_agent.expense_review_preview', runningText: '正在整理识别结果和右侧核对信息...', completedText: '核对信息已整理' }, 'expense-claim-draft': { title: '保存报销草稿', tool: 'database.expense_claims.save_or_submit', runningText: '正在把已确认信息保存为草稿...', completedText: '草稿已保存' }, 'draft-risk-review': { title: '草稿风险识别', tool: 'RuleEngine', runningText: '正在对草稿执行规则校验...', completedText: '已完成草稿风险识别' }, 'application-submit-success': { title: '申请单提交成功', tool: 'ApplicationSubmit', runningText: '正在提交费用申请...', completedText: '申请单提交成功' }, 'attachment-association': { title: '票据关联草稿', tool: 'database.expense_claims.save_or_submit', runningText: '正在把本次票据关联到已保存草稿...', completedText: '票据已归集到草稿' }, 'expense-scene-selection': { title: '报销场景确认', tool: 'UserConfirmation', runningText: '等待用户选择报销场景...', completedText: '已进入场景选择,等待用户确认' }, 'expense-intent-confirmation': { title: '报销意图确认', tool: 'UserConfirmation', runningText: '等待用户确认是否发起报销...', completedText: '用户已确认报销意图' } } export const ASSISTANT_DISPLAY_NAME = '财务助手' export const EXPENSE_WELCOME_QUICK_ACTIONS = [ { label: '快速发起报销', action: GUIDED_ACTION_START_REIMBURSEMENT, icon: 'mdi mdi-receipt-text-plus-outline' }, { label: '查询单据状态', action: GUIDED_ACTION_START_STATUS_QUERY, icon: 'mdi mdi-file-search-outline' }, { label: '差旅计算器', action: GUIDED_ACTION_OPEN_TRAVEL_CALCULATOR, icon: 'mdi mdi-calculator-variant-outline' } ] export const APPLICATION_WELCOME_QUICK_ACTIONS = [ { label: '快速发起申请', action: GUIDED_ACTION_START_APPLICATION, icon: 'mdi mdi-file-plus-outline' }, { label: '查询申请状态', prompt: '帮我查询我的费用申请单状态,筛选最近的 5 条记录。', icon: 'mdi mdi-file-search-outline' }, { label: '申请材料清单', prompt: '请告诉我发起费用申请通常需要准备哪些关键信息和附件。', icon: 'mdi mdi-clipboard-text-search-outline' } ] export const APPROVAL_WELCOME_QUICK_ACTIONS = [ { label: '待我审核', prompt: '帮我查询当前待我审核的单据,筛选最近的 5 条记录。', icon: 'mdi mdi-clipboard-list-outline' }, { label: '审核风险说明', prompt: '帮我梳理待审核单据中需要重点关注的风险,并按高、中、低风险分类说明。', icon: 'mdi mdi-alert-circle-outline' }, { label: '生成审核意见', prompt: '请根据当前待审核单据的风险点,帮我生成一段专业、克制的审核意见草稿。', icon: 'mdi mdi-text-box-edit-outline' } ] export const BUDGET_WELCOME_QUICK_ACTIONS = [ { label: '预算编制查询', prompt: '帮我查询当前部门本季度预算编制情况,重点看差旅、通信、招待费和办公用品。', icon: 'mdi mdi-calculator-variant-outline' }, { label: '阈值风险检查', prompt: '帮我检查当前预算的提醒阈值、告警阈值和风险阈值设置是否合理,并指出需要关注的费用类型。', icon: 'mdi mdi-alert-decagram-outline' }, { label: '预算调整建议', prompt: '请根据已发生、已占用和剩余预算,帮我整理下一轮预算调整建议。', icon: 'mdi mdi-chart-box-plus-outline' } ] export const HOT_KNOWLEDGE_QUESTIONS = [ '差旅住宿标准按什么规则执行?', '酒店超标后如何申请例外报销?', '招待费报销需要哪些凭证?', '发票抬头不一致还能报销吗?', '电子发票验真失败怎么处理?', '借款多久内需要冲销?', '预算不足还能先提交报销吗?', '会议费和招待费如何区分?', '跨部门项目费用应该怎么归集?', '员工退票手续费是否可以报销?' ] export const FLOW_MISSING_SLOT_LABELS = { expense_type: '报销类型', customer_name: '客户名称', time_range: '发生时间', location: '地点', merchant_name: '酒店/商户', amount: '金额', reason: '事由说明', participants: '参与人员', attachments: '票据附件' } let messageSeed = 0