import { computed, ref } from 'vue' import { useRoute, useRouter } from 'vue-router' import { useNavigation, navItems } from './useNavigation.js' import { useRequests } from './useRequests.js' import { useToast } from './useToast.js' import { normalizeRequestForUi } from '../utils/requestViewModel.js' export function useAppShell() { const route = useRoute() const router = useRouter() const smartEntryOpen = ref(false) const smartEntryContext = ref({ prompt: '', source: 'requests', request: null, files: [], conversation: null }) const smartEntrySessionId = ref(0) const { activeView, currentView, setView } = useNavigation() const { requests, loading: requestsLoading, error: requestsError, search, filters, ranges, activeRange, filteredRequests, approveRequest, rejectRequest, reload: reloadRequests } = useRequests() const { toast } = useToast() const customRange = ref({ start: '2024-07-06', end: '2024-07-12' }) const selectedRequest = computed(() => { const requestId = String(route.params.requestId || '') if (!requestId) { return null } const rawRequest = requests.value.find( (item) => String(item.claimId || '').trim() === requestId || String(item.id || '').trim() === requestId ) return normalizeRequestForUi(rawRequest) }) const detailMode = computed(() => route.name === 'app-request-detail') const topBarView = computed(() => { if (detailMode.value) { return { title: '报销单详情', desc: '查看报销明细、票据材料、审批进度与风险提示。' } } return currentView.value }) const requestSummary = computed(() => filteredRequests.value.reduce( (summary, item) => { const request = normalizeRequestForUi(item) if (!request) { return summary } summary.total += 1 if (request.approvalKey === 'draft') { summary.draft += 1 } else if (request.approvalKey === 'in_progress') { summary.inProgress += 1 } else if (request.approvalKey === 'supplement') { summary.supplement += 1 } else if (request.approvalKey === 'completed') { summary.completed += 1 } return summary }, { total: 0, draft: 0, inProgress: 0, supplement: 0, completed: 0 } ) ) function handleApprove(request) { const message = approveRequest(request) toast(message) } function handleReject(request) { const message = rejectRequest(request) toast(message) } function handleNavigate(view) { smartEntryOpen.value = false setView(view) } function openTravelCreate() { smartEntryOpen.value = true smartEntryContext.value = { prompt: '', source: 'topbar', request: null, files: [], conversation: null } smartEntrySessionId.value += 1 } function openSmartEntry(payload = {}) { smartEntryOpen.value = true smartEntryContext.value = { prompt: payload.prompt ?? '', source: payload.source ?? 'workbench', request: payload.request ?? selectedRequest.value, files: Array.isArray(payload.files) ? payload.files : [], conversation: payload.conversation ?? null } smartEntrySessionId.value += 1 } function closeSmartEntry() { smartEntryOpen.value = false } async function handleDraftSaved(payload = {}) { const claimNo = String(payload.claimNo || payload.claim_no || '').trim() smartEntryOpen.value = false await reloadRequests() toast(`${claimNo || '该'}单据已保存到草稿,请到报销页面查看。`) router.push({ name: 'app-requests' }) } function openRequestDetail(request) { router.push({ name: 'app-request-detail', params: { requestId: request.claimId || request.id } }) } function closeRequestDetail() { router.push({ name: 'app-requests' }) } async function handleRequestUpdated() { await reloadRequests() } async function handleRequestDeleted() { await reloadRequests() router.push({ name: 'app-requests' }) } return { activeRange, activeView, closeRequestDetail, closeSmartEntry, currentView, customRange, detailMode, filteredRequests, filters, handleApprove, handleDraftSaved, handleNavigate, handleReject, handleRequestDeleted, handleRequestUpdated, navItems, openRequestDetail, openSmartEntry, openTravelCreate, ranges, requestSummary, requestsError, requestsLoading, reloadRequests, requests, search, selectedRequest, setView, smartEntryContext, smartEntryOpen, smartEntrySessionId, toast, topBarView } }