137 lines
4.7 KiB
JavaScript
137 lines
4.7 KiB
JavaScript
|
|
import { runOrchestrator } from './orchestrator.js'
|
|||
|
|
import {
|
|||
|
|
buildApplicationPreviewRows,
|
|||
|
|
buildApplicationPreviewSubmitText,
|
|||
|
|
normalizeApplicationPreview
|
|||
|
|
} from '../utils/expenseApplicationPreview.js'
|
|||
|
|
|
|||
|
|
export const AI_APPLICATION_ACTION_SAVE_DRAFT = 'ai_application_save_draft'
|
|||
|
|
export const AI_APPLICATION_ACTION_SUBMIT = 'ai_application_submit'
|
|||
|
|
|
|||
|
|
function normalizeText(value) {
|
|||
|
|
return String(value || '').trim()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function resolveUserValue(user = {}, ...keys) {
|
|||
|
|
for (const key of keys) {
|
|||
|
|
const value = normalizeText(user?.[key])
|
|||
|
|
if (value) return value
|
|||
|
|
}
|
|||
|
|
return ''
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function buildClientTimeContext() {
|
|||
|
|
const now = new Date()
|
|||
|
|
const locale =
|
|||
|
|
typeof navigator !== 'undefined' && typeof navigator.language === 'string'
|
|||
|
|
? navigator.language
|
|||
|
|
: 'zh-CN'
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
client_now_iso: now.toISOString(),
|
|||
|
|
client_timezone_offset_minutes: now.getTimezoneOffset(),
|
|||
|
|
client_locale: locale
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function buildApplicationPreviewSaveText(preview = {}) {
|
|||
|
|
const rows = buildApplicationPreviewRows(preview)
|
|||
|
|
return [
|
|||
|
|
'费用申请保存草稿',
|
|||
|
|
...rows.map((row) => `${row.label}:${row.value}`),
|
|||
|
|
'',
|
|||
|
|
'保存草稿'
|
|||
|
|
].join('\n')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function buildAiApplicationPreviewActionText(actionType, preview = {}) {
|
|||
|
|
const normalized = normalizeApplicationPreview(preview)
|
|||
|
|
return actionType === AI_APPLICATION_ACTION_SUBMIT
|
|||
|
|
? buildApplicationPreviewSubmitText(normalized)
|
|||
|
|
: buildApplicationPreviewSaveText(normalized)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function buildAiApplicationPreviewActionPayload({
|
|||
|
|
actionType,
|
|||
|
|
applicationPreview,
|
|||
|
|
currentUser = {},
|
|||
|
|
conversationId = '',
|
|||
|
|
draftPayload = null
|
|||
|
|
} = {}) {
|
|||
|
|
const normalizedPreview = normalizeApplicationPreview(applicationPreview || {})
|
|||
|
|
const message = buildAiApplicationPreviewActionText(actionType, normalizedPreview)
|
|||
|
|
const username = resolveUserValue(currentUser, 'username', 'account', 'email', 'name') || 'anonymous'
|
|||
|
|
const name = resolveUserValue(currentUser, 'name', 'username')
|
|||
|
|
const employeeNo = resolveUserValue(currentUser, 'employeeNo', 'employee_no')
|
|||
|
|
const managerName = resolveUserValue(currentUser, 'managerName', 'manager_name', 'directManagerName', 'direct_manager_name')
|
|||
|
|
const departmentName = resolveUserValue(currentUser, 'departmentName', 'department_name', 'department')
|
|||
|
|
const position = resolveUserValue(currentUser, 'position', 'employeePosition', 'employee_position')
|
|||
|
|
const grade = resolveUserValue(currentUser, 'grade', 'employeeGrade', 'employee_grade')
|
|||
|
|
const roleCodes = Array.isArray(currentUser.roleCodes)
|
|||
|
|
? currentUser.roleCodes.map((item) => normalizeText(item)).filter(Boolean)
|
|||
|
|
: []
|
|||
|
|
const draftClaimId = normalizeText(draftPayload?.claim_id || draftPayload?.claimId)
|
|||
|
|
const isSubmit = actionType === AI_APPLICATION_ACTION_SUBMIT
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
source: 'user_message',
|
|||
|
|
user_id: username,
|
|||
|
|
conversation_id: normalizeText(conversationId) || null,
|
|||
|
|
message,
|
|||
|
|
context_json: {
|
|||
|
|
role_codes: roleCodes,
|
|||
|
|
is_admin: Boolean(currentUser.isAdmin),
|
|||
|
|
name,
|
|||
|
|
role: resolveUserValue(currentUser, 'role'),
|
|||
|
|
department: departmentName,
|
|||
|
|
department_name: departmentName,
|
|||
|
|
position,
|
|||
|
|
employee_position: position,
|
|||
|
|
employeePosition: position,
|
|||
|
|
grade,
|
|||
|
|
employee_grade: grade,
|
|||
|
|
employeeGrade: grade,
|
|||
|
|
employee_no: employeeNo,
|
|||
|
|
employeeNo,
|
|||
|
|
manager_name: managerName,
|
|||
|
|
managerName,
|
|||
|
|
direct_manager_name: managerName,
|
|||
|
|
directManagerName: managerName,
|
|||
|
|
cost_center: resolveUserValue(currentUser, 'costCenter', 'cost_center'),
|
|||
|
|
finance_owner_name: resolveUserValue(currentUser, 'financeOwnerName', 'finance_owner_name'),
|
|||
|
|
...buildClientTimeContext(),
|
|||
|
|
session_type: 'application',
|
|||
|
|
entry_source: 'workbench_ai_inline',
|
|||
|
|
source: 'workbench',
|
|||
|
|
document_type: 'expense_application',
|
|||
|
|
application_stage: 'expense_application',
|
|||
|
|
user_input_text: message,
|
|||
|
|
application_preview: normalizedPreview,
|
|||
|
|
...(isSubmit
|
|||
|
|
? {}
|
|||
|
|
: {
|
|||
|
|
application_action: 'save_draft',
|
|||
|
|
application_save_mode: true
|
|||
|
|
}),
|
|||
|
|
...(draftClaimId
|
|||
|
|
? {
|
|||
|
|
application_edit_claim_id: draftClaimId,
|
|||
|
|
draft_claim_id: draftClaimId,
|
|||
|
|
selected_claim_id: draftClaimId,
|
|||
|
|
application_edit_mode: true
|
|||
|
|
}
|
|||
|
|
: {})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function runAiApplicationPreviewAction(params = {}, options = {}) {
|
|||
|
|
return runOrchestrator(buildAiApplicationPreviewActionPayload(params), {
|
|||
|
|
timeoutMs: params.actionType === AI_APPLICATION_ACTION_SUBMIT ? 120000 : 75000,
|
|||
|
|
timeoutMessage: params.actionType === AI_APPLICATION_ACTION_SUBMIT
|
|||
|
|
? '申请提交处理超时,请稍后重试。'
|
|||
|
|
: '申请草稿保存超时,请稍后重试。',
|
|||
|
|
...options
|
|||
|
|
})
|
|||
|
|
}
|