feat(web): 差旅申请详情进度 viewer 与审批/加载态组件增强

- 新增 requestProgressViewer,申请单在直属领导审批视角下将当前步骤展示为'等待批复',travel-request-detail/app-shell/useRequests 接入
- TravelRequestApprovalDialog 增强审批交互,TableLoadingState 补充表格加载占位,ConfirmDialog 扩展确认对话框能力
- useAppShell/useRequests/AppShellRouteView 配套适配申请详情跳转与会话状态
- 同步更新 requestProgressSteps、travel-request-detail-leader-approval、assistant-session-draft-delete、documents-center-status-filter、app-shell-financial-assistant-entry、request-progress-viewer 等测试
This commit is contained in:
caoxiaozhu
2026-06-21 22:49:58 +08:00
parent 8b3495455b
commit 24b5b71b0f
14 changed files with 295 additions and 49 deletions

View File

@@ -258,6 +258,7 @@ import TravelRequestDetailView from './TravelRequestDetailView.vue'
import { useAppShell } from '../composables/useAppShell.js'
import { useSystemState } from '../composables/useSystemState.js'
import { filterNavItemsByAccess, isPlatformAdminUser } from '../utils/accessControl.js'
import { isBusinessDocumentReference } from '../utils/aiDocumentDetailReference.js'
import { loadAiWorkbenchConversationHistory, saveAiWorkbenchConversation } from '../utils/aiWorkbenchConversationStore.js'
const employeeSummary = ref(null)
@@ -346,6 +347,7 @@ const {
openTravelCreate,
ranges,
requestSummary,
workbenchRequests,
workbenchSummary,
requestsError,
requestsLoading,
@@ -411,12 +413,24 @@ const resolvedDetailKpis = computed(() => (
))
function openWorkbenchDocument(payload = {}) {
const requestId = String(payload.claimId || payload.id || payload.claimNo || payload.documentNo || '').trim()
const payloadClaimId = String(payload.claimId || payload.claim_id || '').trim()
const payloadId = String(payload.id || '').trim()
const payloadClaimNo = String(
payload.claimNo ||
payload.claim_no ||
payload.documentNo ||
payload.document_no ||
''
).trim()
const requestId = String(payloadClaimId || payloadId || payloadClaimNo).trim()
if (!requestId) {
return
}
const request = requests.value.find((item) => (
const requestCandidates = Array.isArray(workbenchRequests.value) && workbenchRequests.value.length
? workbenchRequests.value
: requests.value
const request = requestCandidates.find((item) => (
String(item.claimId || '').trim() === requestId
|| String(item.id || '').trim() === requestId
|| String(item.claimNo || '').trim() === requestId
@@ -429,12 +443,15 @@ function openWorkbenchDocument(payload = {}) {
)
? 'workbench'
: ''
const payloadIdIsBusinessNo = isBusinessDocumentReference(payloadId)
const fallbackClaimId = payloadClaimId || (payloadClaimNo || payloadIdIsBusinessNo ? '' : payloadId || requestId)
const fallbackClaimNo = payloadClaimNo || (payloadIdIsBusinessNo ? payloadId : fallbackClaimId ? '' : requestId)
const detailPayload = request || {
...payload,
id: payload.id || requestId,
claimId: payload.claimId || requestId,
claimNo: payload.claimNo || payload.documentNo || requestId,
documentNo: payload.documentNo || requestId,
id: payloadId || fallbackClaimId || fallbackClaimNo || requestId,
claimId: fallbackClaimId,
claimNo: fallbackClaimNo,
documentNo: String(payload.documentNo || payload.document_no || fallbackClaimNo || requestId).trim(),
detailLookupOnly: true
}
openRequestDetail(detailPayload, { returnTo })

View File

@@ -51,6 +51,7 @@ import {
buildApplicationDetailFactItems,
buildRelatedApplicationFactItems
} from '../../utils/expenseApplicationDetail.js'
import { resolveProgressStepsForViewer } from '../../utils/requestProgressViewer.js'
import { isArchivedRequestView, normalizeRequestForUi } from '../../utils/requestViewModel.js'
import {
buildAiAdviceViewModel,
@@ -1027,11 +1028,15 @@ export default {
}
])
const progressSteps = computed(() =>
Array.isArray(request.value.progressSteps) && request.value.progressSteps.length
const progressSteps = computed(() => {
const sourceSteps = Array.isArray(request.value.progressSteps) && request.value.progressSteps.length
? request.value.progressSteps
: buildFallbackProgressSteps(request.value)
)
return resolveProgressStepsForViewer(sourceSteps, {
isApplicationDocument: isApplicationDocument.value,
isCurrentDirectManagerApprover: isCurrentDirectManagerApprover.value
})
})
const currentProgressRingMotion = {
initial: {