fix: 优化报销创建页面样式与洞察面板交互

修复侧边栏和审计视图样式细节,完善差旅报销洞察面板和消息
组件布局,优化报销创建页面会话管理和流程状态持久化,增强
申请预览工具函数和导航图标,补充单元测试。
This commit is contained in:
caoxiaozhu
2026-05-27 10:32:08 +08:00
parent 2dcc72102d
commit b1a9c8a194
21 changed files with 922 additions and 148 deletions

View File

@@ -12,6 +12,7 @@ import {
} from './travelReimbursementAttachmentModel.js'
import {
ASSISTANT_SESSION_TYPES,
filterAssistantSessionTypes,
SESSION_TYPE_APPLICATION,
SESSION_TYPE_EXPENSE,
buildInitialInsightFromConversation,
@@ -43,6 +44,25 @@ export function useTravelReimbursementSessionState({
scrollToBottom,
getSessionRuntimeRefs = () => ({})
}) {
function resolveAccessibleSessionTypes() {
return filterAssistantSessionTypes(ASSISTANT_SESSION_TYPES, currentUser.value)
}
function resolveAccessibleSessionType(rawSessionType, fallback = resolveDefaultSessionTypeFromEntry()) {
const normalized = normalizeAssistantSessionType(rawSessionType, fallback)
const accessible = resolveAccessibleSessionTypes()
if (accessible.includes(normalized)) {
return normalized
}
const fallbackNormalized = String(fallback || '').trim()
if (accessible.includes(fallbackNormalized)) {
return fallbackNormalized
}
return accessible[0] || SESSION_TYPE_APPLICATION
}
function resolveDefaultSessionTypeFromEntry() {
return props.entrySource === 'application' ? SESSION_TYPE_APPLICATION : SESSION_TYPE_EXPENSE
}
@@ -65,7 +85,10 @@ export function useTravelReimbursementSessionState({
}
function buildConversationSessionState(conversation, fallbackSessionType = resolveDefaultSessionTypeFromEntry()) {
const sessionType = resolveInitialSessionType(conversation, fallbackSessionType)
const sessionType = resolveAccessibleSessionType(
resolveInitialSessionType(conversation, fallbackSessionType),
fallbackSessionType
)
const restoredMessages = refreshWelcomeQuickActions(normalizeInitialConversationMessages(conversation), sessionType)
const initialInsight = buildInitialInsightFromConversation(conversation)
const restoredReviewFilePreviews = buildReviewFilePreviewsFromMessages(restoredMessages)
@@ -90,7 +113,10 @@ export function useTravelReimbursementSessionState({
}
function buildEmptySessionState(sessionType) {
const normalizedSessionType = normalizeAssistantSessionType(sessionType, resolveDefaultSessionTypeFromEntry())
const normalizedSessionType = resolveAccessibleSessionType(
sessionType,
resolveDefaultSessionTypeFromEntry()
)
return {
sessionType: normalizedSessionType,
messages: [
@@ -120,7 +146,7 @@ export function useTravelReimbursementSessionState({
return null
}
const sessionType = normalizeAssistantSessionType(
const sessionType = resolveAccessibleSessionType(
state.sessionType || snapshot.sessionType || fallbackSessionType,
fallbackSessionType
)
@@ -159,9 +185,12 @@ export function useTravelReimbursementSessionState({
}
const defaultInitialSessionType = resolveDefaultSessionTypeFromEntry()
const initialSessionType = props.initialConversation
? resolveInitialSessionType(props.initialConversation, defaultInitialSessionType)
: defaultInitialSessionType
const initialSessionType = resolveAccessibleSessionType(
props.initialConversation
? resolveInitialSessionType(props.initialConversation, defaultInitialSessionType)
: defaultInitialSessionType,
defaultInitialSessionType
)
const shouldPersistLocalSnapshot = props.entrySource !== 'detail'
const conversationInitialState = props.initialConversation
? buildConversationSessionState(props.initialConversation, initialSessionType)
@@ -188,7 +217,7 @@ export function useTravelReimbursementSessionState({
const draftClaimId = ref(initialSessionState.draftClaimId)
const reviewFilePreviews = ref(initialSessionState.reviewFilePreviews)
const sessionSnapshots = ref(
ASSISTANT_SESSION_TYPES.reduce((result, sessionType) => {
resolveAccessibleSessionTypes().reduce((result, sessionType) => {
result[sessionType] = null
return result
}, {})
@@ -202,7 +231,7 @@ export function useTravelReimbursementSessionState({
function buildPersistableSessionState(sessionState) {
const state = sessionState || captureCurrentSessionState()
return {
sessionType: normalizeAssistantSessionType(state.sessionType, resolveDefaultSessionTypeFromEntry()),
sessionType: resolveAccessibleSessionType(state.sessionType, resolveDefaultSessionTypeFromEntry()),
messages: serializeSessionMessages(state.messages),
conversationId: String(state.conversationId || '').trim(),
draftClaimId: String(state.draftClaimId || '').trim(),
@@ -258,7 +287,10 @@ export function useTravelReimbursementSessionState({
function applySessionState(sessionState) {
const runtimeRefs = getSessionRuntimeRefs()
const nextState = sessionState || buildEmptySessionState(activeSessionType.value)
activeSessionType.value = normalizeAssistantSessionType(nextState.sessionType, resolveDefaultSessionTypeFromEntry())
activeSessionType.value = resolveAccessibleSessionType(
nextState.sessionType,
resolveDefaultSessionTypeFromEntry()
)
messages.value = Array.isArray(nextState.messages) && nextState.messages.length
? nextState.messages
: [
@@ -301,7 +333,7 @@ export function useTravelReimbursementSessionState({
}
async function loadLatestSessionState(targetSessionType) {
const normalizedTarget = normalizeAssistantSessionType(targetSessionType, resolveDefaultSessionTypeFromEntry())
const normalizedTarget = resolveAccessibleSessionType(targetSessionType, resolveDefaultSessionTypeFromEntry())
const payload = await fetchLatestConversation(resolveCurrentUserId(), normalizedTarget, {
preferRecoverable: normalizedTarget === SESSION_TYPE_EXPENSE
})
@@ -312,7 +344,7 @@ export function useTravelReimbursementSessionState({
}
async function switchSessionType(targetSessionType) {
const normalizedTarget = normalizeAssistantSessionType(targetSessionType, resolveDefaultSessionTypeFromEntry())
const normalizedTarget = resolveAccessibleSessionType(targetSessionType, resolveDefaultSessionTypeFromEntry())
if (normalizedTarget === activeSessionType.value || sessionSwitchBusy.value) {
return
}