refactor: consolidate finance workflow modules
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
import { isApplicationDocumentNo } from '../../utils/documentClassification.js'
|
||||
import { filterActionableRiskFlags, normalizeRiskFlagTone } from '../../utils/riskFlags.js'
|
||||
import {
|
||||
DOCUMENT_TYPE_APPLICATION,
|
||||
DOCUMENT_TYPE_EXPENSE_APPLICATION,
|
||||
DOCUMENT_TYPE_REIMBURSEMENT,
|
||||
resolveDocumentTypeLabel
|
||||
} from '../../constants/documentProtocol.js'
|
||||
|
||||
const EXPENSE_TYPE_LABELS = {
|
||||
travel: '差旅费',
|
||||
@@ -49,8 +55,6 @@ const DOCUMENT_BACKED_EXPENSE_TYPES = new Set([
|
||||
'hotel_ticket',
|
||||
'ride_ticket'
|
||||
])
|
||||
const DOCUMENT_TYPE_APPLICATION = 'application'
|
||||
const DOCUMENT_TYPE_REIMBURSEMENT = 'reimbursement'
|
||||
const RELATED_APPLICATION_STEP_LABEL = '关联单据'
|
||||
const APPLICATION_LINK_STATUS_STEP_LABEL = '关联单据状态'
|
||||
const APPLICATION_ARCHIVE_STAGE_LABEL = '申请归档'
|
||||
@@ -179,14 +183,14 @@ function resolveDocumentTypeMeta(claim, typeCode) {
|
||||
const normalizedType = String(typeCode || '').trim()
|
||||
const isApplication =
|
||||
explicitType === DOCUMENT_TYPE_APPLICATION
|
||||
|| explicitType === 'expense_application'
|
||||
|| explicitType === DOCUMENT_TYPE_EXPENSE_APPLICATION
|
||||
|| isApplicationDocumentNo(claimNo)
|
||||
|| normalizedType === 'application'
|
||||
|| normalizedType.endsWith('_application')
|
||||
|
||||
return isApplication
|
||||
? { documentTypeCode: DOCUMENT_TYPE_APPLICATION, documentTypeLabel: '申请单' }
|
||||
: { documentTypeCode: DOCUMENT_TYPE_REIMBURSEMENT, documentTypeLabel: '报销单' }
|
||||
? { documentTypeCode: DOCUMENT_TYPE_APPLICATION, documentTypeLabel: resolveDocumentTypeLabel(DOCUMENT_TYPE_APPLICATION) }
|
||||
: { documentTypeCode: DOCUMENT_TYPE_REIMBURSEMENT, documentTypeLabel: resolveDocumentTypeLabel(DOCUMENT_TYPE_REIMBURSEMENT) }
|
||||
}
|
||||
|
||||
function normalizeExpenseType(typeCode) {
|
||||
|
||||
@@ -139,7 +139,14 @@ export function useTopBarNotificationStates() {
|
||||
}
|
||||
|
||||
function markNotificationStateRead(item) {
|
||||
return syncNotificationPatches([buildPatch(item, { read: true })])
|
||||
return markNotificationStatesRead([item])
|
||||
}
|
||||
|
||||
function markNotificationStatesRead(items) {
|
||||
const patches = (Array.isArray(items) ? items : [])
|
||||
.map((item) => buildPatch(item, { read: true, hidden: false }))
|
||||
.filter(Boolean)
|
||||
return syncNotificationPatches(patches)
|
||||
}
|
||||
|
||||
function hideNotificationStates(items) {
|
||||
@@ -158,6 +165,7 @@ export function useTopBarNotificationStates() {
|
||||
isNotificationHidden,
|
||||
isNotificationRead,
|
||||
loadNotificationStates,
|
||||
markNotificationStateRead
|
||||
markNotificationStateRead,
|
||||
markNotificationStatesRead
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,7 @@ import {
|
||||
} from './workbenchAiComposerModel.js'
|
||||
import {
|
||||
createWorkbenchAiMessageRuntime,
|
||||
formatMessageTime,
|
||||
normalizeInlineAttachmentOcrDetails
|
||||
formatMessageTime
|
||||
} from './workbenchAiMessageModel.js'
|
||||
import { useWorkbenchAiActionRouter } from './useWorkbenchAiActionRouter.js'
|
||||
import { useWorkbenchAiAttachmentAssociationFlow } from './useWorkbenchAiAttachmentAssociationFlow.js'
|
||||
@@ -34,8 +33,10 @@ import { useWorkbenchAiComposerFiles } from './useWorkbenchAiComposerFiles.js'
|
||||
import { useWorkbenchAiDocumentQueryFlow } from './useWorkbenchAiDocumentQueryFlow.js'
|
||||
import { useWorkbenchAiExpenseFlow } from './useWorkbenchAiExpenseFlow.js'
|
||||
import { useWorkbenchAiMessageActions } from './useWorkbenchAiMessageActions.js'
|
||||
import { useWorkbenchAiMessageExpansion } from './useWorkbenchAiMessageExpansion.js'
|
||||
import { useWorkbenchAiSessionCommands } from './useWorkbenchAiSessionCommands.js'
|
||||
import { useWorkbenchAiStewardFlow } from './useWorkbenchAiStewardFlow.js'
|
||||
import { isReimbursementCreationIntent } from './workbenchAiApplicationGateModel.js'
|
||||
|
||||
const AI_SEARCH_CONVERSATION_ID = 'ai-search'
|
||||
const INLINE_ANSWER_STREAM_CHUNK_SIZE = 6
|
||||
@@ -174,6 +175,23 @@ export function usePersonalWorkbenchAiMode(props, emit) {
|
||||
...card,
|
||||
ocrState: attachmentFlow.resolveAiModeReceiptRecognitionState(selectedFiles.value[index])
|
||||
})))
|
||||
const {
|
||||
hasInlineAttachmentOcrDetails,
|
||||
hasInlineThinking,
|
||||
isInlineAttachmentOcrExpanded,
|
||||
isInlineThinkingExpanded,
|
||||
resolveInlineAttachmentOcrDocuments,
|
||||
resolveInlineAttachmentOcrFileCount,
|
||||
resolveInlineThinkingEvents,
|
||||
toggleInlineAttachmentOcrDetails,
|
||||
toggleInlineThinking
|
||||
} = useWorkbenchAiMessageExpansion({
|
||||
attachmentOcrExpandedMessageIds,
|
||||
inlineConversationAutoScrollPinned,
|
||||
scrollInlineConversationToBottom,
|
||||
thinkingCollapsedMessageIds,
|
||||
thinkingExpandedMessageIds
|
||||
})
|
||||
|
||||
const applicationFlow = useWorkbenchAiApplicationPreviewFlow({
|
||||
activateInlineConversation,
|
||||
@@ -324,6 +342,10 @@ export function usePersonalWorkbenchAiMode(props, emit) {
|
||||
})
|
||||
}
|
||||
|
||||
function setAssistantInputRef(element) {
|
||||
assistantInputRef.value = element
|
||||
}
|
||||
|
||||
function isInlineConversationNearBottom() {
|
||||
const el = conversationScrollRef.value
|
||||
if (!el) {
|
||||
@@ -499,78 +521,6 @@ export function usePersonalWorkbenchAiMode(props, emit) {
|
||||
return renderAiConversationHtml(content)
|
||||
}
|
||||
|
||||
function resolveInlineThinkingEvents(message) {
|
||||
return Array.isArray(message?.stewardPlan?.thinkingEvents) ? message.stewardPlan.thinkingEvents : []
|
||||
}
|
||||
|
||||
function hasInlineThinking(message) {
|
||||
return resolveInlineThinkingEvents(message).length > 0
|
||||
}
|
||||
|
||||
function isInlineThinkingExpanded(message) {
|
||||
if (!message?.id) {
|
||||
return Boolean(message?.pending)
|
||||
}
|
||||
if (thinkingCollapsedMessageIds.value.has(message.id)) {
|
||||
return false
|
||||
}
|
||||
return Boolean(message.pending || thinkingExpandedMessageIds.value.has(message.id))
|
||||
}
|
||||
|
||||
function toggleInlineThinking(message) {
|
||||
if (!message?.id) {
|
||||
return
|
||||
}
|
||||
const nextExpandedIds = new Set(thinkingExpandedMessageIds.value)
|
||||
const nextCollapsedIds = new Set(thinkingCollapsedMessageIds.value)
|
||||
if (isInlineThinkingExpanded(message)) {
|
||||
nextExpandedIds.delete(message.id)
|
||||
nextCollapsedIds.add(message.id)
|
||||
} else {
|
||||
nextCollapsedIds.delete(message.id)
|
||||
nextExpandedIds.add(message.id)
|
||||
}
|
||||
thinkingExpandedMessageIds.value = nextExpandedIds
|
||||
thinkingCollapsedMessageIds.value = nextCollapsedIds
|
||||
}
|
||||
|
||||
function hasInlineAttachmentOcrDetails(message = {}) {
|
||||
const details = normalizeInlineAttachmentOcrDetails(message?.attachmentOcrDetails || null)
|
||||
return Boolean(details?.documents?.length || details?.fileNames?.length)
|
||||
}
|
||||
|
||||
function resolveInlineAttachmentOcrDocuments(message = {}) {
|
||||
return normalizeInlineAttachmentOcrDetails(message?.attachmentOcrDetails || null)?.documents || []
|
||||
}
|
||||
|
||||
function resolveInlineAttachmentOcrFileCount(message = {}) {
|
||||
const details = normalizeInlineAttachmentOcrDetails(message?.attachmentOcrDetails || null)
|
||||
return Math.max(details?.documents?.length || 0, details?.fileNames?.length || 0)
|
||||
}
|
||||
|
||||
function isInlineAttachmentOcrExpanded(message = {}) {
|
||||
return Boolean(message?.id && attachmentOcrExpandedMessageIds.value.has(message.id))
|
||||
}
|
||||
|
||||
function toggleInlineAttachmentOcrDetails(message = {}, forceExpanded = null) {
|
||||
if (!message?.id || !hasInlineAttachmentOcrDetails(message)) {
|
||||
return
|
||||
}
|
||||
const nextExpandedIds = new Set(attachmentOcrExpandedMessageIds.value)
|
||||
const shouldExpand = forceExpanded === null
|
||||
? !nextExpandedIds.has(message.id)
|
||||
: Boolean(forceExpanded)
|
||||
if (shouldExpand) {
|
||||
nextExpandedIds.add(message.id)
|
||||
} else {
|
||||
nextExpandedIds.delete(message.id)
|
||||
}
|
||||
attachmentOcrExpandedMessageIds.value = nextExpandedIds
|
||||
nextTick(() => {
|
||||
scrollInlineConversationToBottom({ force: inlineConversationAutoScrollPinned.value })
|
||||
})
|
||||
}
|
||||
|
||||
function buildInlinePromptText(rawPrompt, files = []) {
|
||||
const prompt = buildWorkbenchPromptText(rawPrompt)
|
||||
if (prompt) {
|
||||
@@ -579,20 +529,6 @@ export function usePersonalWorkbenchAiMode(props, emit) {
|
||||
return files.length ? '请帮我处理已上传的附件。' : ''
|
||||
}
|
||||
|
||||
function isReimbursementCreationIntent(prompt = '') {
|
||||
const compact = String(prompt || '').replace(/\s+/g, '')
|
||||
if (!compact || !/报销|报账/.test(compact)) {
|
||||
return false
|
||||
}
|
||||
if (/标准|制度|规则|政策|口径|怎么|如何|能不能|可以吗|查一下|查询|状态|进度|多少钱|多少/.test(compact)) {
|
||||
return false
|
||||
}
|
||||
return (
|
||||
/^(我要|我想|我需要|帮我|请帮我|需要|发起|新建|创建|提交|办理|走).{0,16}(报销|报账)/.test(compact) ||
|
||||
/^(报销|报账)(一下|一笔|单|流程)?$/.test(compact)
|
||||
)
|
||||
}
|
||||
|
||||
function handleAiAnswerMarkdownClick(event) {
|
||||
const target = event?.target
|
||||
const link = target?.closest?.('a[href^="#ai-open-document-detail:"], a[href^="#ai-open-application-detail:"]')
|
||||
@@ -800,6 +736,7 @@ export function usePersonalWorkbenchAiMode(props, emit) {
|
||||
scrollInlineConversationToTop,
|
||||
selectedFileCards,
|
||||
sending,
|
||||
setAssistantInputRef,
|
||||
setWorkbenchDateMode,
|
||||
submitAiModePrompt,
|
||||
toggleInlineAttachmentOcrDetails,
|
||||
|
||||
@@ -24,10 +24,15 @@ import {
|
||||
buildInlineApplicationSubmitPrecheckPayload,
|
||||
buildInlineApplicationSubmitThinkingEvents,
|
||||
completeInlineThinkingEvents,
|
||||
extractInlineApplicationDraftPayload,
|
||||
resolveInlineApplicationPreviewActionFromText
|
||||
extractInlineApplicationDraftPayload
|
||||
} from './workbenchAiApplicationPreviewModel.js'
|
||||
import { AI_ATTACHMENT_ASSOCIATION_CONFIRM_ACTION } from './workbenchAiMessageModel.js'
|
||||
import {
|
||||
isOrphanInlineApplicationPreviewMessage,
|
||||
resolveInlineApplicationPreviewTextAction,
|
||||
resolveLatestApplicationPreviewMessage,
|
||||
resolveLatestOrphanApplicationPreviewMessage
|
||||
} from './workbenchAiApplicationGateModel.js'
|
||||
|
||||
function isApplicationPreviewEstimatePendingPreview(applicationPreview = {}) {
|
||||
const fields = normalizeApplicationPreview(applicationPreview).fields || {}
|
||||
@@ -197,23 +202,12 @@ export function useWorkbenchAiApplicationPreviewFlow({
|
||||
].join('\n\n')
|
||||
}
|
||||
|
||||
function resolveLatestApplicationPreviewMessage() {
|
||||
return [...conversationMessages.value]
|
||||
.reverse()
|
||||
.find((message) => message.role === 'assistant' && message.applicationPreview)
|
||||
function resolveLatestInlineApplicationPreviewMessage() {
|
||||
return resolveLatestApplicationPreviewMessage(conversationMessages.value)
|
||||
}
|
||||
|
||||
function isOrphanInlineApplicationPreviewMessage(message = {}) {
|
||||
if (message?.applicationPreview || message?.role !== 'assistant') {
|
||||
return false
|
||||
}
|
||||
return /下方表格|申请核对表|点击对应行即可直接编辑/.test(String(message.content || message.text || ''))
|
||||
}
|
||||
|
||||
function resolveLatestOrphanApplicationPreviewMessage() {
|
||||
return [...conversationMessages.value]
|
||||
.reverse()
|
||||
.find((message) => isOrphanInlineApplicationPreviewMessage(message))
|
||||
function resolveLatestOrphanInlineApplicationPreviewMessage() {
|
||||
return resolveLatestOrphanApplicationPreviewMessage(conversationMessages.value)
|
||||
}
|
||||
|
||||
function requestInlineApplicationSubmitConfirmation(targetMessage, options = {}) {
|
||||
@@ -310,7 +304,7 @@ export function useWorkbenchAiApplicationPreviewFlow({
|
||||
}
|
||||
|
||||
async function executeInlineApplicationPreviewAction(actionType, sourceMessage = null, options = {}) {
|
||||
const targetMessage = sourceMessage?.applicationPreview ? sourceMessage : resolveLatestApplicationPreviewMessage()
|
||||
const targetMessage = sourceMessage?.applicationPreview ? sourceMessage : resolveLatestInlineApplicationPreviewMessage()
|
||||
if (!targetMessage?.applicationPreview) {
|
||||
toast('当前没有可提交的申请表。')
|
||||
return false
|
||||
@@ -446,12 +440,12 @@ export function useWorkbenchAiApplicationPreviewFlow({
|
||||
toast('请等待费用测算完成后再继续操作。')
|
||||
return true
|
||||
}
|
||||
const actionType = resolveInlineApplicationPreviewActionFromText(prompt)
|
||||
const actionType = resolveInlineApplicationPreviewTextAction(prompt)
|
||||
if (!actionType) {
|
||||
return false
|
||||
}
|
||||
if (!resolveLatestApplicationPreviewMessage()) {
|
||||
const orphanPreviewMessage = resolveLatestOrphanApplicationPreviewMessage()
|
||||
if (!resolveLatestInlineApplicationPreviewMessage()) {
|
||||
const orphanPreviewMessage = resolveLatestOrphanInlineApplicationPreviewMessage()
|
||||
if (!orphanPreviewMessage) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
import { normalizeInlineAttachmentOcrDetails } from './workbenchAiMessageModel.js'
|
||||
|
||||
export function useWorkbenchAiMessageExpansion({
|
||||
attachmentOcrExpandedMessageIds,
|
||||
inlineConversationAutoScrollPinned,
|
||||
scrollInlineConversationToBottom,
|
||||
thinkingCollapsedMessageIds,
|
||||
thinkingExpandedMessageIds
|
||||
}) {
|
||||
function resolveInlineThinkingEvents(message) {
|
||||
return Array.isArray(message?.stewardPlan?.thinkingEvents) ? message.stewardPlan.thinkingEvents : []
|
||||
}
|
||||
|
||||
function hasInlineThinking(message) {
|
||||
return resolveInlineThinkingEvents(message).length > 0
|
||||
}
|
||||
|
||||
function isInlineThinkingExpanded(message) {
|
||||
if (!message?.id) {
|
||||
return Boolean(message?.pending)
|
||||
}
|
||||
if (thinkingCollapsedMessageIds.value.has(message.id)) {
|
||||
return false
|
||||
}
|
||||
return Boolean(message.pending || thinkingExpandedMessageIds.value.has(message.id))
|
||||
}
|
||||
|
||||
function toggleInlineThinking(message) {
|
||||
if (!message?.id) {
|
||||
return
|
||||
}
|
||||
const nextExpandedIds = new Set(thinkingExpandedMessageIds.value)
|
||||
const nextCollapsedIds = new Set(thinkingCollapsedMessageIds.value)
|
||||
if (isInlineThinkingExpanded(message)) {
|
||||
nextExpandedIds.delete(message.id)
|
||||
nextCollapsedIds.add(message.id)
|
||||
} else {
|
||||
nextCollapsedIds.delete(message.id)
|
||||
nextExpandedIds.add(message.id)
|
||||
}
|
||||
thinkingExpandedMessageIds.value = nextExpandedIds
|
||||
thinkingCollapsedMessageIds.value = nextCollapsedIds
|
||||
}
|
||||
|
||||
function hasInlineAttachmentOcrDetails(message = {}) {
|
||||
const details = normalizeInlineAttachmentOcrDetails(message?.attachmentOcrDetails || null)
|
||||
return Boolean(details?.documents?.length || details?.fileNames?.length)
|
||||
}
|
||||
|
||||
function resolveInlineAttachmentOcrDocuments(message = {}) {
|
||||
return normalizeInlineAttachmentOcrDetails(message?.attachmentOcrDetails || null)?.documents || []
|
||||
}
|
||||
|
||||
function resolveInlineAttachmentOcrFileCount(message = {}) {
|
||||
const details = normalizeInlineAttachmentOcrDetails(message?.attachmentOcrDetails || null)
|
||||
return Math.max(details?.documents?.length || 0, details?.fileNames?.length || 0)
|
||||
}
|
||||
|
||||
function isInlineAttachmentOcrExpanded(message = {}) {
|
||||
return Boolean(message?.id && attachmentOcrExpandedMessageIds.value.has(message.id))
|
||||
}
|
||||
|
||||
function toggleInlineAttachmentOcrDetails(message = {}, forceExpanded = null) {
|
||||
if (!message?.id || !hasInlineAttachmentOcrDetails(message)) {
|
||||
return
|
||||
}
|
||||
const nextExpandedIds = new Set(attachmentOcrExpandedMessageIds.value)
|
||||
const shouldExpand = forceExpanded === null
|
||||
? !nextExpandedIds.has(message.id)
|
||||
: Boolean(forceExpanded)
|
||||
if (shouldExpand) {
|
||||
nextExpandedIds.add(message.id)
|
||||
} else {
|
||||
nextExpandedIds.delete(message.id)
|
||||
}
|
||||
attachmentOcrExpandedMessageIds.value = nextExpandedIds
|
||||
nextTick(() => {
|
||||
scrollInlineConversationToBottom({ force: inlineConversationAutoScrollPinned.value })
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
hasInlineAttachmentOcrDetails,
|
||||
hasInlineThinking,
|
||||
isInlineAttachmentOcrExpanded,
|
||||
isInlineThinkingExpanded,
|
||||
resolveInlineAttachmentOcrDocuments,
|
||||
resolveInlineAttachmentOcrFileCount,
|
||||
resolveInlineThinkingEvents,
|
||||
toggleInlineAttachmentOcrDetails,
|
||||
toggleInlineThinking
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import {
|
||||
AI_APPLICATION_ACTION_SAVE_DRAFT,
|
||||
AI_APPLICATION_ACTION_SUBMIT
|
||||
} from '../../services/aiApplicationPreviewActions.js'
|
||||
|
||||
export function isReimbursementCreationIntent(prompt = '') {
|
||||
const compact = String(prompt || '').replace(/\s+/g, '')
|
||||
if (!compact || !/报销|报账/.test(compact)) {
|
||||
return false
|
||||
}
|
||||
if (/标准|制度|规则|政策|口径|怎么|如何|能不能|可以吗|查一下|查询|状态|进度|多少钱|多少/.test(compact)) {
|
||||
return false
|
||||
}
|
||||
return (
|
||||
/^(我要|我想|我需要|帮我|请帮我|需要|发起|新建|创建|提交|办理|走).{0,16}(报销|报账)/.test(compact) ||
|
||||
/^(报销|报账)(一下|一笔|单|流程)?$/.test(compact)
|
||||
)
|
||||
}
|
||||
|
||||
export function resolveInlineApplicationPreviewTextAction(text = '') {
|
||||
const normalized = String(text || '').replace(/\s+/g, '').trim()
|
||||
if (!normalized) {
|
||||
return ''
|
||||
}
|
||||
if (/^(保存草稿|保存|存草稿|先保存)$/.test(normalized)) {
|
||||
return AI_APPLICATION_ACTION_SAVE_DRAFT
|
||||
}
|
||||
if (/^(提交|提交申请|确认提交|提交审批|直接提交)$/.test(normalized)) {
|
||||
return AI_APPLICATION_ACTION_SUBMIT
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
export function resolveLatestApplicationPreviewMessage(messages = []) {
|
||||
return [...(Array.isArray(messages) ? messages : [])]
|
||||
.reverse()
|
||||
.find((message) => message?.role === 'assistant' && message.applicationPreview) || null
|
||||
}
|
||||
|
||||
export function isOrphanInlineApplicationPreviewMessage(message = {}) {
|
||||
if (message?.applicationPreview || message?.role !== 'assistant') {
|
||||
return false
|
||||
}
|
||||
return /下方表格|申请核对表|点击对应行即可直接编辑/.test(String(message.content || message.text || ''))
|
||||
}
|
||||
|
||||
export function resolveLatestOrphanApplicationPreviewMessage(messages = []) {
|
||||
return [...(Array.isArray(messages) ? messages : [])]
|
||||
.reverse()
|
||||
.find((message) => isOrphanInlineApplicationPreviewMessage(message)) || null
|
||||
}
|
||||
@@ -13,19 +13,8 @@ import {
|
||||
AI_APPLICATION_ACTION_SAVE_DRAFT,
|
||||
AI_APPLICATION_ACTION_SUBMIT
|
||||
} from '../../services/aiApplicationPreviewActions.js'
|
||||
|
||||
const INLINE_APPLICATION_STATUS_LABELS = {
|
||||
draft: '草稿',
|
||||
submitted: '审批中',
|
||||
pending: '待处理',
|
||||
approved: '已审批',
|
||||
completed: '已完成',
|
||||
archived: '已归档',
|
||||
returned: '已退回',
|
||||
rejected: '已驳回',
|
||||
pending_payment: '待付款',
|
||||
paid: '已付款'
|
||||
}
|
||||
import { INLINE_APPLICATION_STATUS_LABELS } from '../../constants/documentProtocol.js'
|
||||
import { resolveInlineApplicationPreviewTextAction } from './workbenchAiApplicationGateModel.js'
|
||||
|
||||
function normalizeInlineApplicationResultTableCell(value, fallback = '-') {
|
||||
const text = String(value || '')
|
||||
@@ -201,17 +190,7 @@ export function buildInlineApplicationDetailAction(draftPayload = {}) {
|
||||
}
|
||||
|
||||
export function resolveInlineApplicationPreviewActionFromText(text = '') {
|
||||
const normalized = String(text || '').replace(/\s+/g, '').trim()
|
||||
if (!normalized) {
|
||||
return ''
|
||||
}
|
||||
if (/^(保存草稿|保存|存草稿|先保存)$/.test(normalized)) {
|
||||
return AI_APPLICATION_ACTION_SAVE_DRAFT
|
||||
}
|
||||
if (/^(提交|提交申请|确认提交|提交审批|直接提交)$/.test(normalized)) {
|
||||
return AI_APPLICATION_ACTION_SUBMIT
|
||||
}
|
||||
return ''
|
||||
return resolveInlineApplicationPreviewTextAction(text)
|
||||
}
|
||||
|
||||
export function normalizeInlineApplicationTypeLabel(expenseTypeLabel, fallback = '费用申请') {
|
||||
|
||||
Reference in New Issue
Block a user