export const GUIDED_FLOW_MODE_NONE = '' export const GUIDED_FLOW_MODE_REIMBURSEMENT = 'reimbursement_guide' export const GUIDED_FLOW_MODE_STATUS_QUERY = 'status_query_guide' export const GUIDED_ACTION_START_REIMBURSEMENT = 'start_guided_reimbursement' export const GUIDED_ACTION_START_APPLICATION = 'start_guided_application' export const GUIDED_ACTION_START_STATUS_QUERY = 'start_guided_status_query' export const GUIDED_ACTION_OPEN_TRAVEL_CALCULATOR = 'open_travel_calculator' export const GUIDED_ACTION_SELECT_EXPENSE_TYPE = 'guided_select_expense_type' export const GUIDED_ACTION_SELECT_REQUIRED_APPLICATION = 'guided_select_required_application' export const GUIDED_ACTION_CONFIRM_REIMBURSEMENT_REVIEW = 'guided_confirm_reimbursement_review' export const GUIDED_ACTION_CONTINUE_FILLING = 'guided_continue_filling' export const GUIDED_ACTION_PROCESS_INTERRUPTION = 'guided_process_interruption' export const GUIDED_ACTION_SELECT_QUERY_MODE = 'guided_select_query_mode' export const GUIDED_ACTION_SELECT_QUERY_STATUS = 'guided_select_query_status' export const GUIDED_EXPENSE_TYPES = [ { key: 'travel', label: '差旅费', description: '出差、跨城交通、住宿和补贴', icon: 'mdi mdi-bag-suitcase-outline' }, { key: 'transport', label: '交通费', description: '市内交通、打车、停车和通行费', icon: 'mdi mdi-car-outline' }, { key: 'hotel', label: '住宿费', description: '单独住宿或酒店票据', icon: 'mdi mdi-bed-outline' }, { key: 'meal', label: '业务招待费', description: '客户接待、餐饮和工作招待', icon: 'mdi mdi-food-fork-drink' }, { key: 'office', label: '办公用品费', description: '办公用品、文具和低值易耗品', icon: 'mdi mdi-briefcase-outline' }, { key: 'other', label: '其他费用', description: '暂不属于以上类型的费用', icon: 'mdi mdi-dots-horizontal-circle-outline' } ] const GUIDED_REIMBURSEMENT_STEPS = { travel: [ { key: 'reason', summaryLabel: '事由', prompt: '请先告诉我本次出差事由,例如:去上海支持项目部署。' }, { key: 'location', summaryLabel: '出差地点', prompt: '本次出差地点是哪里?可以回复城市或具体客户地点。' }, { key: 'time_range', summaryLabel: '出差时间/天数', prompt: '请补充出差时间或天数,例如:2026-05-20 至 2026-05-23,出差 3 天。' }, { key: 'amount', summaryLabel: '金额', prompt: '请补充本次预计或实际报销金额。如果还没有汇总,可以回复“待核算”。' }, { key: 'attachments', summaryLabel: '票据', prompt: '票据可以现在上传,也可以回复“稍后上传”。上传后我会在生成核对信息时一起处理。' } ], transport: [ { key: 'reason', summaryLabel: '出行事由', prompt: '请说明本次交通费事由,例如:送客户去机场。' }, { key: 'time_range', summaryLabel: '出行时间', prompt: '请补充出行时间,例如:2026-05-20 下午。' }, { key: 'location', summaryLabel: '路线/地点', prompt: '请补充出行路线或地点,例如:公司至机场。' }, { key: 'amount', summaryLabel: '金额', prompt: '请补充交通费金额。如果票据里再识别金额,可以回复“以票据为准”。' }, { key: 'attachments', summaryLabel: '票据', prompt: '请上传出租车、网约车、停车或通行费等票据;也可以回复“稍后上传”。' } ], hotel: [ { key: 'reason', summaryLabel: '住宿事由', prompt: '请说明住宿事由,例如:项目现场支持期间住宿。' }, { key: 'location', summaryLabel: '城市/酒店地点', prompt: '住宿城市或酒店地点是哪里?' }, { key: 'time_range', summaryLabel: '入住离店时间', prompt: '请补充入住和离店时间,例如:2026-05-20 至 2026-05-23。' }, { key: 'amount', summaryLabel: '金额', prompt: '请补充住宿金额。如果还没有汇总,可以回复“待核算”。' }, { key: 'attachments', summaryLabel: '票据', prompt: '请上传酒店发票或住宿水单;也可以回复“稍后上传”。' } ], meal: [ { key: 'customer_name', summaryLabel: '客户单位', prompt: '请补充客户单位或接待对象。' }, { key: 'participants', summaryLabel: '参与人员', prompt: '请补充参与人员,例如:客户 2 人,我方 1 人。' }, { key: 'time_range', summaryLabel: '招待时间', prompt: '请补充招待时间,例如:2026-05-20 晚。' }, { key: 'location', summaryLabel: '招待地点', prompt: '请补充招待地点或商户名称。' }, { key: 'amount', summaryLabel: '金额', prompt: '请补充招待金额。' }, { key: 'reason', summaryLabel: '事由', prompt: '请补充招待事由,例如:项目沟通或客户接待。' }, { key: 'attachments', summaryLabel: '票据', prompt: '请上传餐饮发票或相关凭证;也可以回复“稍后上传”。' } ], office: [ { key: 'reason', summaryLabel: '采购用途', prompt: '请说明采购用途,例如:项目现场临时采购办公用品。' }, { key: 'location', summaryLabel: '商户/采购地点', prompt: '请补充商户或采购地点。' }, { key: 'time_range', summaryLabel: '发生时间', prompt: '请补充费用发生时间。' }, { key: 'amount', summaryLabel: '金额', prompt: '请补充办公用品金额。' }, { key: 'attachments', summaryLabel: '票据', prompt: '请上传办公用品发票或购物凭证;也可以回复“稍后上传”。' } ], other: [ { key: 'reason', summaryLabel: '费用说明', prompt: '请说明这笔费用的具体内容和用途。' }, { key: 'time_range', summaryLabel: '发生时间', prompt: '请补充费用发生时间。' }, { key: 'location', summaryLabel: '地点/对象', prompt: '请补充费用发生地点或关联对象。' }, { key: 'amount', summaryLabel: '金额', prompt: '请补充费用金额。' }, { key: 'attachments', summaryLabel: '票据', prompt: '请上传相关票据;也可以回复“稍后上传”。' } ] } export const GUIDED_QUERY_MODES = [ { key: 'claim_no', label: '按单号', description: '输入报销单号精准查询', icon: 'mdi mdi-pound' }, { key: 'status', label: '按状态', description: '查询草稿、审批中或已归档单据', icon: 'mdi mdi-list-status' }, { key: 'time_range', label: '按时间范围', description: '例如上周、去年、2026-05', icon: 'mdi mdi-calendar-search-outline' }, { key: 'keyword', label: '按地点/事由', description: '例如北京、上海电力、服务器部署', icon: 'mdi mdi-map-search-outline' } ] export const GUIDED_QUERY_STATUS_OPTIONS = [ { key: 'draft', label: '草稿', description: '还没有正式提交的单据' }, { key: 'pending', label: '审批中', description: '正在流转审批的单据' }, { key: 'returned', label: '已退回', description: '需要补充或修改的单据' }, { key: 'archived', label: '已归档', description: '已完成归档的单据' }, { key: 'completed', label: '已完成', description: '已审核完成或已付款的单据' } ] const NO_ATTACHMENT_TEXT_PATTERN = /^(稍后|暂不|不用|没有|待上传|后面|后续|先不|以票据为准)/u const INTERRUPTION_PATTERN = /(查一下|查询|状态|报销了吗|报销了么|多少|总额|标准|制度|规则|为什么|怎么|可以吗|能不能|差旅计算器|计算一下|解释|风险|打开|跳转|查看|审批|归档|入账|[??])/u function uniqueValues(values) { return Array.from(new Set((Array.isArray(values) ? values : []).map((item) => String(item || '').trim()).filter(Boolean))) } function normalizeText(value) { return String(value || '').trim() } function normalizeValues(values) { if (!values || typeof values !== 'object') { return {} } return Object.entries(values).reduce((result, [key, value]) => { if (key === 'attachment_names') { result[key] = uniqueValues(value) return result } result[key] = normalizeText(value) return result }, {}) } function hasLinkedApplication(values) { return Boolean(normalizeText(values?.application_claim_id) || normalizeText(values?.application_claim_no)) } function buildApplicationSummaryParts(values) { return [ normalizeText(values?.application_claim_no), normalizeText(values?.application_reason), normalizeText(values?.application_business_time), normalizeText(values?.application_location), normalizeText(values?.application_amount_label || values?.application_amount) ].filter(Boolean) } function normalizeApplicationCandidates(applications) { if (!Array.isArray(applications)) { return [] } return applications .map((item) => (item && typeof item === 'object' ? item : null)) .filter(Boolean) .map((item) => ({ id: normalizeText(item.id || item.application_claim_id), claim_no: normalizeText(item.claim_no || item.application_claim_no), expense_type: normalizeText(item.expense_type || item.application_expense_type), reason: normalizeText(item.reason || item.application_reason), location: normalizeText(item.location || item.application_location), amount: normalizeText(item.amount || item.application_amount), amount_label: normalizeText(item.amount_label || item.application_amount_label), business_time: normalizeText(item.business_time || item.application_business_time), days: normalizeText(item.days || item.application_days), transport_mode: normalizeText(item.transport_mode || item.application_transport_mode), lodging_daily_cap: normalizeText(item.lodging_daily_cap || item.application_lodging_daily_cap), subsidy_daily_cap: normalizeText(item.subsidy_daily_cap || item.application_subsidy_daily_cap), transport_policy: normalizeText(item.transport_policy || item.application_transport_policy), policy_estimate: normalizeText(item.policy_estimate || item.application_policy_estimate), rule_name: normalizeText(item.rule_name || item.application_rule_name), rule_version: normalizeText(item.rule_version || item.application_rule_version), status: normalizeText(item.status || item.application_status), status_label: normalizeText(item.status_label || item.application_status_label), application_date: normalizeText(item.application_date) })) .filter((item) => item.id || item.claim_no) } export function createEmptyGuidedFlowState() { return { mode: GUIDED_FLOW_MODE_NONE, stepKey: '', expenseType: '', values: {}, pendingInterruptionText: '', applicationCandidates: [] } } export function normalizeGuidedFlowState(state) { const source = state && typeof state === 'object' ? state : {} const mode = normalizeText(source.mode) const supportedMode = [GUIDED_FLOW_MODE_REIMBURSEMENT, GUIDED_FLOW_MODE_STATUS_QUERY].includes(mode) ? mode : GUIDED_FLOW_MODE_NONE if (!supportedMode) { return createEmptyGuidedFlowState() } return { mode: supportedMode, stepKey: normalizeText(source.stepKey), expenseType: normalizeText(source.expenseType), values: normalizeValues(source.values), pendingInterruptionText: normalizeText(source.pendingInterruptionText), applicationCandidates: normalizeApplicationCandidates(source.applicationCandidates) } } export function isGuidedFlowActive(state) { return Boolean(normalizeGuidedFlowState(state).mode) } export function getGuidedExpenseType(expenseType) { const key = normalizeText(expenseType) return GUIDED_EXPENSE_TYPES.find((item) => item.key === key) || null } export function getGuidedExpenseTypeLabel(expenseType) { return getGuidedExpenseType(expenseType)?.label || '' } export function buildGuidedExpenseTypeActions() { return GUIDED_EXPENSE_TYPES.map((option) => ({ label: option.label, description: option.description, icon: option.icon, action_type: GUIDED_ACTION_SELECT_EXPENSE_TYPE, payload: { expense_type: option.key, expense_type_label: option.label } })) } export function buildGuidedReimbursementStartText() { return [ '请问你要报销的类型?', '', '先选一个最贴近的费用场景,我会按对应流程逐项询问。这个过程只做本地引导,不会自动创建草稿。' ].join('\n') } export function createGuidedReimbursementState() { return { ...createEmptyGuidedFlowState(), mode: GUIDED_FLOW_MODE_REIMBURSEMENT, stepKey: 'expense_type' } } export function selectGuidedExpenseType(state, expenseType) { const type = getGuidedExpenseType(expenseType) if (!type) { return normalizeGuidedFlowState(state) } const steps = GUIDED_REIMBURSEMENT_STEPS[type.key] || [] return { ...normalizeGuidedFlowState(state), mode: GUIDED_FLOW_MODE_REIMBURSEMENT, expenseType: type.key, stepKey: steps[0]?.key || 'summary', pendingInterruptionText: '', applicationCandidates: [] } } export function waitForGuidedApplicationSelection(state, expenseType, applications = []) { const type = getGuidedExpenseType(expenseType) if (!type) { return normalizeGuidedFlowState(state) } return { ...normalizeGuidedFlowState(state), mode: GUIDED_FLOW_MODE_REIMBURSEMENT, expenseType: type.key, stepKey: 'application_selection', pendingInterruptionText: '', applicationCandidates: normalizeApplicationCandidates(applications) } } export function selectGuidedRequiredApplication(state, application = {}) { const current = normalizeGuidedFlowState(state) return { ...current, values: normalizeValues({ ...current.values, application_claim_id: application.application_claim_id || application.id || '', application_claim_no: application.application_claim_no || application.claim_no || '', application_reason: application.application_reason || application.reason || '', application_location: application.application_location || application.location || '', application_amount: application.application_amount || application.amount || '', application_amount_label: application.application_amount_label || application.amount_label || '', application_business_time: application.application_business_time || application.business_time || '', application_days: application.application_days || application.days || '', application_transport_mode: application.application_transport_mode || application.transport_mode || '', application_lodging_daily_cap: application.application_lodging_daily_cap || application.lodging_daily_cap || '', application_subsidy_daily_cap: application.application_subsidy_daily_cap || application.subsidy_daily_cap || '', application_transport_policy: application.application_transport_policy || application.transport_policy || '', application_policy_estimate: application.application_policy_estimate || application.policy_estimate || '', application_rule_name: application.application_rule_name || application.rule_name || '', application_rule_version: application.application_rule_version || application.rule_version || '', application_status_label: application.application_status_label || application.status_label || '', application_date: application.application_date || '' }), stepKey: 'summary', pendingInterruptionText: '', applicationCandidates: [] } } export function getGuidedReimbursementSteps(expenseType) { const key = normalizeText(expenseType) return GUIDED_REIMBURSEMENT_STEPS[key] || [] } export function getCurrentGuidedStep(state) { const current = normalizeGuidedFlowState(state) if (current.mode !== GUIDED_FLOW_MODE_REIMBURSEMENT || !current.expenseType) { return null } return getGuidedReimbursementSteps(current.expenseType).find((step) => step.key === current.stepKey) || null } export function buildGuidedStepPromptText(state) { const current = normalizeGuidedFlowState(state) const step = getCurrentGuidedStep(current) const typeLabel = getGuidedExpenseTypeLabel(current.expenseType) if (!step || !typeLabel) { return buildGuidedReimbursementStartText() } const steps = getGuidedReimbursementSteps(current.expenseType) const stepIndex = Math.max(0, steps.findIndex((item) => item.key === step.key)) return [ `已选择“${typeLabel}”。`, '', `第 ${stepIndex + 1} 步:${step.summaryLabel}`, step.prompt, '', '直接回复这一项即可。' ].join('\n') } export function resolveGuidedExpenseTypeFromText(text) { const normalized = normalizeText(text) if (!normalized) { return '' } const exact = GUIDED_EXPENSE_TYPES.find((item) => normalized === item.label || normalized === item.key) if (exact) { return exact.key } const matched = GUIDED_EXPENSE_TYPES.find((item) => normalized.includes(item.label)) return matched?.key || '' } export function applyGuidedReimbursementAnswer(state, answerText, attachmentNames = []) { const current = normalizeGuidedFlowState(state) const step = getCurrentGuidedStep(current) if (!step) { return current } const answer = normalizeText(answerText) const nextValues = { ...current.values } if (step.key === 'attachments') { const nextAttachmentNames = uniqueValues([ ...(Array.isArray(nextValues.attachment_names) ? nextValues.attachment_names : []), ...attachmentNames ]) if (nextAttachmentNames.length) { nextValues.attachment_names = nextAttachmentNames } nextValues.attachments = answer || (nextAttachmentNames.length ? `已选择 ${nextAttachmentNames.length} 份附件` : '稍后上传') } else { nextValues[step.key] = answer } const steps = getGuidedReimbursementSteps(current.expenseType) const currentIndex = steps.findIndex((item) => item.key === step.key) const nextStep = steps[currentIndex + 1] return { ...current, values: normalizeValues(nextValues), stepKey: nextStep?.key || 'summary', pendingInterruptionText: '' } } export function isGuidedReimbursementReadyForReview(state) { const current = normalizeGuidedFlowState(state) return current.mode === GUIDED_FLOW_MODE_REIMBURSEMENT && Boolean(current.expenseType) && current.stepKey === 'summary' } export function buildGuidedReimbursementSummaryText(state) { const current = normalizeGuidedFlowState(state) const typeLabel = getGuidedExpenseTypeLabel(current.expenseType) || '报销' const steps = getGuidedReimbursementSteps(current.expenseType) const linkedApplication = hasLinkedApplication(current.values) const lines = [ `已完成“${typeLabel}”的引导填写。`, '', '请核查下面的关键信息:' ] if (linkedApplication) { const applicationParts = buildApplicationSummaryParts(current.values) lines.push(`- 关联申请单:${applicationParts.join(' / ')}`) lines.push('- 报销票据:可先生成草稿,随后在草稿详情中上传对应票据。') } else { steps.forEach((step) => { const value = step.key === 'attachments' ? (current.values.attachment_names?.length ? current.values.attachment_names.join('、') : current.values.attachments || '稍后上传') : current.values[step.key] lines.push(`- ${step.summaryLabel}:${value || '待补充'}`) }) } lines.push('') lines.push( linkedApplication ? '如果关联信息无误,我可以直接生成报销草稿;后续由你在草稿详情中上传和归集票据。' : '如果这些信息无误,我可以继续生成报销草稿;草稿生成后可继续上传票据或补充信息。' ) return lines.join('\n') } export function buildGuidedReviewConfirmationActions() { return [{ label: '生成报销草稿', description: '使用当前信息生成草稿,票据可在草稿详情继续上传', icon: 'mdi mdi-clipboard-check-outline', action_type: GUIDED_ACTION_CONFIRM_REIMBURSEMENT_REVIEW }] } export function buildGuidedReviewSubmitOptions(state, files = []) { const current = normalizeGuidedFlowState(state) const type = getGuidedExpenseType(current.expenseType) const values = current.values || {} const typeLabel = type?.label || '其他费用' const linkedApplication = hasLinkedApplication(values) const applicationReason = values.application_reason || '' const applicationLocation = values.application_location || '' const applicationAmount = values.application_amount || values.application_amount_label || '' const applicationBusinessTime = values.application_business_time || '' const applicationTransportMode = values.application_transport_mode || '' const fieldLines = [] if (linkedApplication) { const applicationParts = buildApplicationSummaryParts(values) fieldLines.push(`关联申请单:${applicationParts.join(' / ')}`) fieldLines.push('报销票据:草稿生成后在详情中上传') } else { getGuidedReimbursementSteps(current.expenseType).forEach((step) => { const value = step.key === 'attachments' ? (values.attachment_names?.length ? values.attachment_names.join('、') : values.attachments || '稍后上传') : values[step.key] fieldLines.push(`${step.summaryLabel}:${value || '待补充'}`) }) } const rawText = [ `报销类型:${typeLabel}`, ...fieldLines ].join('\n') const reviewFormValues = { expense_type: typeLabel, reason: values.reason || applicationReason || values.customer_name || '', customer_name: values.customer_name || '', participants: values.participants || '', location: values.location || applicationLocation || '', time_range: values.time_range || applicationBusinessTime || '', transport_mode: values.transport_mode || applicationTransportMode || '', amount: linkedApplication ? (values.amount || '') : (values.amount || applicationAmount || ''), attachments: Array.isArray(values.attachment_names) ? values.attachment_names.join('、') : '', application_claim_id: values.application_claim_id || '', application_claim_no: values.application_claim_no || '', application_reason: values.application_reason || '', application_location: values.application_location || '', application_amount: values.application_amount || '', application_amount_label: values.application_amount_label || '', application_business_time: values.application_business_time || '', application_days: values.application_days || '', application_transport_mode: values.application_transport_mode || '', application_lodging_daily_cap: values.application_lodging_daily_cap || '', application_subsidy_daily_cap: values.application_subsidy_daily_cap || '', application_transport_policy: values.application_transport_policy || '', application_policy_estimate: values.application_policy_estimate || '', application_rule_name: values.application_rule_name || '', application_rule_version: values.application_rule_version || '', application_date: values.application_date || '' } return { rawText, userText: '生成报销草稿', pendingText: '正在生成报销草稿...', systemGenerated: true, files, extraContext: { draft_claim_id: '', review_action: 'save_draft', user_input_text: rawText, expense_scene_selection: { expense_type: type?.key || current.expenseType || 'other', expense_type_label: typeLabel, original_message: rawText, application_claim_id: values.application_claim_id || '', application_claim_no: values.application_claim_no || '' }, review_form_values: reviewFormValues } } } export function shouldConfirmGuidedInterruption(text, state) { const current = normalizeGuidedFlowState(state) if (!current.mode || current.pendingInterruptionText) { return false } const normalized = normalizeText(text) if (!normalized || NO_ATTACHMENT_TEXT_PATTERN.test(normalized)) { return false } return INTERRUPTION_PATTERN.test(normalized) } export function buildGuidedInterruptionText(text) { return [ `我看到你刚才输入的是:“${normalizeText(text)}”。`, '', '这看起来像一个新的问题。你想继续填写当前引导,还是先暂停当前引导并处理这个问题?' ].join('\n') } export function buildGuidedInterruptionActions() { return [ { label: '继续填写', description: '保留当前引导,继续回答这一项', icon: 'mdi mdi-pencil-outline', action_type: GUIDED_ACTION_CONTINUE_FILLING }, { label: '暂停当前引导并处理这个问题', description: '暂停引导,把刚才输入交给财务助手处理', icon: 'mdi mdi-chat-processing-outline', action_type: GUIDED_ACTION_PROCESS_INTERRUPTION } ] } export function createGuidedStatusQueryState() { return { ...createEmptyGuidedFlowState(), mode: GUIDED_FLOW_MODE_STATUS_QUERY, stepKey: 'query_mode' } } export function buildGuidedStatusQueryStartText() { return [ '你想按什么条件查询单据状态?', '', '先选查询方式,我再向你收集对应条件。' ].join('\n') } export function buildGuidedQueryModeActions() { return GUIDED_QUERY_MODES.map((option) => ({ label: option.label, description: option.description, icon: option.icon, action_type: GUIDED_ACTION_SELECT_QUERY_MODE, payload: { query_mode: option.key, query_mode_label: option.label } })) } export function buildGuidedQueryStatusActions() { return GUIDED_QUERY_STATUS_OPTIONS.map((option) => ({ label: option.label, description: option.description, icon: 'mdi mdi-checkbox-marked-circle-outline', action_type: GUIDED_ACTION_SELECT_QUERY_STATUS, payload: { query_status: option.key, query_status_label: option.label } })) } export function resolveGuidedQueryModeFromText(text) { const normalized = normalizeText(text) if (!normalized) return '' const exact = GUIDED_QUERY_MODES.find((item) => normalized === item.label || normalized === item.key) if (exact) return exact.key if (/单号|编号|EXP-|APP-|AP-|RE-|AD-/i.test(normalized)) return 'claim_no' if (/状态|草稿|审批|退回|归档|完成/.test(normalized)) return 'status' if (/上周|本周|去年|今年|月份|时间|日期|[0-9]{4}-[0-9]{2}/.test(normalized)) return 'time_range' return 'keyword' } export function selectGuidedQueryMode(state, queryMode) { const current = normalizeGuidedFlowState(state) const mode = GUIDED_QUERY_MODES.find((item) => item.key === normalizeText(queryMode)) if (!mode) { return current } return { ...current, mode: GUIDED_FLOW_MODE_STATUS_QUERY, stepKey: mode.key === 'status' ? 'status_value' : 'query_value', values: { ...current.values, query_mode: mode.key, query_mode_label: mode.label }, pendingInterruptionText: '' } } export function buildGuidedQueryPromptText(state) { const current = normalizeGuidedFlowState(state) const mode = normalizeText(current.values.query_mode) if (!mode) { return buildGuidedStatusQueryStartText() } if (mode === 'status') { return [ '请选择要查询的单据状态。', '', '我会按所选状态筛选最近的报销单据。' ].join('\n') } const prompts = { claim_no: '请输入单据编号,例如 RE-20260525103045-ABCDEFGH。', time_range: '请输入查询时间范围,例如:上周、今年 5 月、2025 年全年。', keyword: '请输入地点、客户或事由关键词,例如:上海电力、北京、服务器部署。' } return prompts[mode] || '请补充查询条件。' } export function buildGuidedStatusQueryText(state, valueText) { const current = normalizeGuidedFlowState(state) const mode = normalizeText(current.values.query_mode) const value = normalizeText(valueText) if (mode === 'claim_no') { return `帮我查询单号 ${value} 的报销单状态` } if (mode === 'status') { return `帮我查询${value}的报销单据,筛选最近的 5 条记录` } if (mode === 'time_range') { return `帮我查询${value}提交或发生的报销单据状态,筛选最近的 5 条记录` } return `帮我查询地点或事由包含“${value}”的报销单据状态,筛选最近的 5 条记录` }