This commit is contained in:
zlwu committed 2026-05-28 13:05:46 +08:00
1 parent f1f5d24eff
commit 3c7a47981a
138 files changed
+18654 -12092

No files matched your search

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+99 -71
View File
@@ -1,11 +1,11 @@
# Graph Report - src (2026-05-28)
## Corpus Check
- Large corpus: 668 files · ~413,834 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
- Large corpus: 671 files · ~417,254 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary
- 1910 nodes · 2459 edges · 39 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 548 edges (avg confidence: 0.8)
- 1942 nodes · 2508 edges · 43 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 556 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
@@ -37,17 +37,21 @@
- [[_COMMUNITY_Community 25|Community 25]]
- [[_COMMUNITY_Community 26|Community 26]]
- [[_COMMUNITY_Community 27|Community 27]]
- [[_COMMUNITY_Community 29|Community 29]]
- [[_COMMUNITY_Community 28|Community 28]]
- [[_COMMUNITY_Community 30|Community 30]]
- [[_COMMUNITY_Community 31|Community 31]]
- [[_COMMUNITY_Community 33|Community 33]]
- [[_COMMUNITY_Community 32|Community 32]]
- [[_COMMUNITY_Community 34|Community 34]]
- [[_COMMUNITY_Community 35|Community 35]]
- [[_COMMUNITY_Community 36|Community 36]]
- [[_COMMUNITY_Community 40|Community 40]]
- [[_COMMUNITY_Community 41|Community 41]]
- [[_COMMUNITY_Community 37|Community 37]]
- [[_COMMUNITY_Community 38|Community 38]]
- [[_COMMUNITY_Community 42|Community 42]]
- [[_COMMUNITY_Community 43|Community 43]]
- [[_COMMUNITY_Community 44|Community 44]]
- [[_COMMUNITY_Community 45|Community 45]]
- [[_COMMUNITY_Community 47|Community 47]]
- [[_COMMUNITY_Community 49|Community 49]]
## God Nodes (most connected - your core abstractions)
1. `get()` - 203 edges
@@ -68,16 +72,16 @@
utils/http/index.ts → views/operations/storage-facility/index.vue
- `handleUnauthorizedResponse()` --calls--> `fetchRefreshToken()` [INFERRED]
utils/http/index.ts → api/auth.ts
- `fetchConsumableList()` --calls--> `get()` [INFERRED]
api/production.ts → views/production/process/ProcessRouteTab.vue
- `fetchReagentList()` --calls--> `get()` [INFERRED]
api/production.ts → views/production/process/ProcessRouteTab.vue
- `fetchOutboundReleaseReviewDetail()` --calls--> `get()` [INFERRED]
api/outbound-release-review.ts → views/production/process/ProcessRouteTab.vue
- `fetchOutboundReleaseMaterial()` --calls--> `get()` [INFERRED]
api/outbound-release-review.ts → views/production/process/ProcessRouteTab.vue
## Communities
### Community 0 - "Community 0"
Cohesion: 0.01
Nodes (136): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchCellSampleTypeList() (+128 more)
Nodes (141): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchCellSampleTypeList() (+133 more)
### Community 1 - "Community 1"
Cohesion: 0.01
@@ -93,169 +97,193 @@ Nodes (40): fetchGetMenuList(), fetchGetMenuCodes(), fetchGetUserInfo(), fetchLo
### Community 4 - "Community 4"
Cohesion: 0.03
Nodes (42): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), submitOutboundReleaseReview(), fetchStorageReleaseReviewDetail(), fetchStorageReleaseReviewList(), submitStorageReleaseReview() (+34 more)
Nodes (50): fetchCollectionRegionList(), fetchCreateCollectionRegion(), fetchCreateHospital(), fetchDeleteCollectionRegion(), fetchDeleteHospital(), fetchHospitalList(), fetchUpdateCollectionRegion(), fetchUpdateHospital() (+42 more)
### Community 5 - "Community 5"
Cohesion: 0.03
Nodes (36): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumableStockLogs(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents(), fetchAllReagentStockLogs() (+28 more)
Cohesion: 0.04
Nodes (35): handleBlur(), handleFocus(), handleInput(), fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed() (+27 more)
### Community 6 - "Community 6"
Cohesion: 0.04
Nodes (30): fetchCollectionRegionList(), fetchCreateCollectionRegion(), fetchCreateHospital(), fetchDeleteCollectionRegion(), fetchDeleteHospital(), fetchHospitalList(), fetchUpdateCollectionRegion(), fetchUpdateHospital() (+22 more)
Cohesion: 0.05
Nodes (26): auditorDisplay(), dash(), expressName(), formatYm(), formatYmd(), sampleTypeName(), siteName(), unitName() (+18 more)
### Community 7 - "Community 7"
Cohesion: 0.06
Nodes (11): fetchGetLatestUpgradeLog(), getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager (+3 more)
Cohesion: 0.05
Nodes (39): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), fetchAttachmentDownloadUrl(), formatLocalDate(), handleAdd(), handleBatchDelete() (+31 more)
### Community 8 - "Community 8"
Cohesion: 0.08
Nodes (7): updateInfusionScheduleStatus(), handleSubmit(), handleReset(), handleSearch(), WebSocketClient, TableCache, emit()
Cohesion: 0.06
Nodes (34): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+26 more)
### Community 9 - "Community 9"
Cohesion: 0.05
Nodes (20): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), collectIds(), handleAdd(), handleBatchDelete(), handleDelete() (+12 more)
Nodes (23): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), collectIds(), postorder(), preorder(), applyTreeExpand() (+15 more)
### Community 10 - "Community 10"
Cohesion: 0.07
Nodes (21): auditorDisplay(), dash(), expressName(), formatYm(), formatYmd(), sampleTypeName(), siteName(), unitName() (+13 more)
Cohesion: 0.08
Nodes (7): updateInfusionScheduleStatus(), handleSubmit(), handleReset(), handleSearch(), WebSocketClient, TableCache, emit()
### Community 11 - "Community 11"
Cohesion: 0.08
Nodes (32): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+24 more)
### Community 12 - "Community 12"
Cohesion: 0.06
Nodes (25): fetchAttachmentDownloadUrl(), formatLocalDate(), fullFileUrl(), handleDownloadAttachment(), handlePreviewAttachment(), isVideoFile(), handleReceptionAttachmentDownload(), handleDownloadAttachment() (+17 more)
### Community 13 - "Community 13"
Cohesion: 0.07
Nodes (21): handleBlur(), handleFocus(), handleInput(), fetchEthnicList(), addSample(), applyDonationBundleToForm(), confirmBatchTransportApply(), createEmptyTransport() (+13 more)
### Community 14 - "Community 14"
Cohesion: 0.07
Nodes (22): for(), set(), walk(), annotateForkEdges(), chainApiToElements(), walkAncestorBranch(), walkAncestorParents(), if() (+14 more)
### Community 15 - "Community 15"
### Community 12 - "Community 12"
Cohesion: 0.09
Nodes (8): getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager, validateStorageData()
### Community 13 - "Community 13"
Cohesion: 0.08
Nodes (24): fetchCreateSite(), fetchDeleteSite(), fetchDictDataOptions(), fetchSiteList(), fetchUpdateSite(), fetchUserList(), formatHandoverUserLabel(), formatNowDatetime() (+16 more)
### Community 16 - "Community 16"
### Community 14 - "Community 14"
Cohesion: 0.08
Nodes (11): maskIdCard(), buildOutboundPilotContextSections(), applicationStatusLabel(), applicationStatusTagType(), infusionMethodLabel(), infusionStatusLabel(), infusionStatusTagType(), qcStatusLabel() (+3 more)
### Community 17 - "Community 17"
### Community 15 - "Community 15"
Cohesion: 0.11
Nodes (21): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolDetail(), buildInsuranceAttachmentsValue(), buildInsurancePayload(), formatYmdFromAny(), fullFileUrl(), handleBatchEdit() (+13 more)
### Community 18 - "Community 18"
### Community 16 - "Community 16"
Cohesion: 0.11
Nodes (22): fetchCreateUser(), fetchDeleteUser(), fetchResetPassword(), fetchRoleOptions(), fetchUpdateUser(), fetchUserDetail(), formatUserDeptDisplay(), handleAdd() (+14 more)
### Community 19 - "Community 19"
### Community 17 - "Community 17"
Cohesion: 0.12
Nodes (22): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), handleBatchComplete(), handleBatchStart(), handleBatchVoid() (+14 more)
### Community 20 - "Community 20"
### Community 18 - "Community 18"
Cohesion: 0.12
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
### Community 21 - "Community 21"
### Community 19 - "Community 19"
Cohesion: 0.1
Nodes (6): fetchProductionTaskDetail(), fetchProductionTaskList(), fetchUpdateProductionTask(), handleClose(), handleSubmit(), loadTaskDetail()
### Community 22 - "Community 22"
### Community 20 - "Community 20"
Cohesion: 0.16
Nodes (14): fetchPilotCheckupList(), canEditCheckup(), canFillCheckupInfo(), canMarkChecked(), handleDropdownCommand(), handleEdit(), handleReset(), handleSearch() (+6 more)
### Community 21 - "Community 21"
Cohesion: 0.15
Nodes (11): fetchEthnicList(), addSample(), applyDonationBundleToForm(), confirmBatchTransportApply(), createEmptyTransport(), ensureEthnicOptionInList(), handleOpenForAdd(), loadEthnicOptions() (+3 more)
### Community 22 - "Community 22"
Cohesion: 0.15
Nodes (15): fetchConsumablePackDetail(), fetchConsumablePackList(), fetchCreateConsumablePack(), fetchUpdateConsumablePack(), confirmAddConsumable(), handleAdd(), handleDelete(), handleDropdownCommand() (+7 more)
### Community 23 - "Community 23"
Cohesion: 0.16
Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
### Community 24 - "Community 24"
Cohesion: 0.14
Nodes (8): fetchOutboundReleaseMaterial(), fetchOutboundReleaseReviewDetail(), fetchOutboundReleaseReviewList(), fetchReleaseReviewList(), handleReset(), handleSearch(), loadData(), onReviewSubmitted()
### Community 25 - "Community 25"
Cohesion: 0.2
Nodes (2): ComponentLoader, RouteTransformer
### Community 25 - "Community 25"
### Community 26 - "Community 26"
Cohesion: 0.27
Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
### Community 26 - "Community 26"
### Community 27 - "Community 27"
Cohesion: 0.14
Nodes (8): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), useCeremony(), useTheme(), themeAnimation(), toggleTheme(), toggleTransition()
### Community 27 - "Community 27"
### Community 28 - "Community 28"
Cohesion: 0.18
Nodes (5): fetchServiceOrderTxnList(), handleReset(), handleSearch(), handleTabChange(), loadData()
### Community 29 - "Community 29"
### Community 30 - "Community 30"
Cohesion: 0.17
Nodes (3): fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
### Community 30 - "Community 30"
Cohesion: 0.18
Nodes (3): fetchMaterialList(), fetchMaterialOptions(), fetchMaterialStockLogList()
### Community 31 - "Community 31"
Cohesion: 0.2
Nodes (2): fetchQcMaterialList(), fetchQcMaterialOptions()
### Community 33 - "Community 33"
### Community 32 - "Community 32"
Cohesion: 0.28
Nodes (1): FireworkSystem
### Community 34 - "Community 34"
Cohesion: 0.39
Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle()
### Community 34 - "Community 34"
### Community 35 - "Community 35"
Cohesion: 0.36
Nodes (1): TableHeightCalculator
### Community 35 - "Community 35"
### Community 36 - "Community 36"
Cohesion: 0.25
Nodes (2): fetchQcTaskDetail(), fetchQcTaskList()
### Community 37 - "Community 37"
Cohesion: 0.33
Nodes (2): logApiCryptoBootInfo(), maskSecret()
### Community 36 - "Community 36"
### Community 38 - "Community 38"
Cohesion: 0.47
Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
### Community 40 - "Community 40"
### Community 42 - "Community 42"
Cohesion: 0.5
Nodes (2): focusInput(), handleKeydown()
### Community 41 - "Community 41"
### Community 43 - "Community 43"
Cohesion: 0.67
Nodes (2): if(), logSidebarMenu()
### Community 43 - "Community 43"
### Community 44 - "Community 44"
Cohesion: 0.5
Nodes (1): fetchStorageEntrySmsList()
### Community 45 - "Community 45"
Cohesion: 0.5
Nodes (1): fetchSampleSmsNotificationList()
### Community 47 - "Community 47"
Cohesion: 1.0
Nodes (2): getSettingDefaults(), resetToDefaults()
### Community 45 - "Community 45"
### Community 49 - "Community 49"
Cohesion: 1.0
Nodes (2): defaultAvatarPathByRole(), resolveUserAvatarUrl()
## Knowledge Gaps
- **Thin community `Community 24`** (17 nodes): `ComponentLoader`, `.constructor()`, `.createEmptyComponent()`, `.createErrorComponent()`, `.load()`, `.loadIframe()`, `.loadLayout()`, `.load()`, `RouteTransformer`, `.extractFirstSegment()`, `.handleFirstLevelRoute()`, `.handleIframeRoute()`, `.handleNormalRoute()`, `.isFirstLevelRoute()`, `.transform()`, `ComponentLoader.ts`, `RouteTransformer.ts`
- **Thin community `Community 25`** (17 nodes): `ComponentLoader`, `.constructor()`, `.createEmptyComponent()`, `.createErrorComponent()`, `.load()`, `.loadIframe()`, `.loadLayout()`, `.load()`, `RouteTransformer`, `.extractFirstSegment()`, `.handleFirstLevelRoute()`, `.handleIframeRoute()`, `.handleNormalRoute()`, `.isFirstLevelRoute()`, `.transform()`, `ComponentLoader.ts`, `RouteTransformer.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 31`** (10 nodes): `fetchBatchStockInQcMaterial()`, `fetchBatchStockOutQcMaterial()`, `fetchCreateQcMaterial()`, `fetchDeleteQcMaterial()`, `fetchQcMaterialList()`, `fetchQcMaterialOptions()`, `fetchStockInQcMaterial()`, `fetchStockOutQcMaterial()`, `fetchUpdateQcMaterial()`, `qc-material.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 34`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
- **Thin community `Community 32`** (9 nodes): `FireworkSystem`, `.constructor()`, `.createFirework()`, `.createParticle()`, `.getAvailableParticle()`, `.initializePool()`, `.preloadAllImages()`, `.preloadImage()`, `index.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 35`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
- **Thin community `Community 35`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 40`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
- **Thin community `Community 36`** (8 nodes): `fetchCompleteQcTask()`, `fetchCreateQcTask()`, `fetchDeleteQcTask()`, `fetchQcTaskDetail()`, `fetchQcTaskList()`, `fetchStartQcTask()`, `fetchUpdateQcTaskAttachments()`, `qc-task.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 41`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
- **Thin community `Community 37`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 43`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
- **Thin community `Community 42`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 45`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
- **Thin community `Community 43`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 44`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 45`** (4 nodes): `fetchGenerateSms()`, `fetchSampleSmsNotificationList()`, `fetchToggleSmsNotified()`, `sample-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 47`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 49`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 9`, `Community 13`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 21`, `Community 22`, `Community 27`, `Community 29`, `Community 30`, `Community 31`?**
_High betweenness centrality (0.255) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 2` to `Community 1`, `Community 5`, `Community 7`, `Community 8`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 17`?**
_High betweenness centrality (0.120) - this node is a cross-community bridge._
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 7`, `Community 9`, `Community 11`, `Community 13`, `Community 15`, `Community 16`, `Community 17`, `Community 19`, `Community 20`, `Community 21`, `Community 22`, `Community 24`, `Community 28`, `Community 30`, `Community 31`, `Community 36`, `Community 44`, `Community 45`?**
_High betweenness centrality (0.268) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 2` to `Community 32`, `Community 1`, `Community 5`, `Community 7`, `Community 8`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 15`, `Community 21`, `Community 22`?**
_High betweenness centrality (0.116) - this node is a cross-community bridge._
- **Are the 202 inferred relationships involving `get()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `buildTreePathLabelFromFlat()`) actually correct?**
_`get()` has 202 INFERRED edges - model-reasoned connections that need verification._
- **Are the 35 inferred relationships involving `push()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `fetchAllPagedRecords()`) actually correct?**
+4 -4
View File
@@ -57,12 +57,12 @@
</div>
<div id="legend"></div>
</div>
<div id="stats">1910 nodes &middot; 2459 edges &middot; 285 communities</div>
<div id="stats">1942 nodes &middot; 2508 edges &middot; 286 communities</div>
</div>
<script>
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 35, "community_name": "Community 35", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 35, "community_name": "Community 35", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 35, "community_name": "Community 35", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 35, "community_name": "Community 35", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 35, "community_name": "Community 35", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 35, "community_name": "Community 35", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 77, "community_name": "Community 77", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 78, "community_name": "Community 78", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 20, "community_name": "Community 20", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 20, "community_name": "Community 20", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 20, "community_name": "Community 20", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 20, "community_name": "Community 20", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 20, "community_name": "Community 20", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective", "laLine truncated
const RAW_EDGES = [{"from": "app_vue", "to": "src_app_refreshbuttonautoicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "src_app_refreshpaneltitleicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "main_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "utils_sys_console_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_masksecret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_logapicryptobootinfo", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_main_masksecret", "to": "src_main_logapicryptobootinfo", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_ts", "to": "directives_index_setupglobdirectives", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_setupglobdirectives", "to": "core_auth_setupauthdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "core_roles_setuprolesdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_highlight_setuphighlightdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_ripple_setuprippledirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_core_roles_ts", "to": "core_roles_checkrolepermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_setuprolesdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_roles_checkrolepermission", "to": "core_roles_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_checkauthpermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_setupauthdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_checkauthpermission", "to": "core_auth_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_ripple_ts", "to": "business_ripple_setuprippledirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_highlightcode", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_insertlinenumbers", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_addcopybutton", "label": "contains", "title": "contains [EXTRACTED]", "dLine truncated
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 230}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 189}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 131}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 104}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 83}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 81}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 56}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 55}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 51}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 48}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 41}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 40}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 40}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 38}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 37}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 33}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 31}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 27}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 26}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 26}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 22}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 22}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 20}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 17}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 17}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 16}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 15}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 14}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 13}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 12}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 11}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 10}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 9}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 8}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 8}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 7}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 6}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 6}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 6}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 6}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 5}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 4}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 4}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 3}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 3}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 3}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 3}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 3}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 3}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 3}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 3}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 3}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 2}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 2}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 2}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 2}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 2}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 2}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 2}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 2}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 2}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 2}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 2}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 2}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 2}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 2}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 2}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 2}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 2}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 2}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "count": 2Line truncated
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 37, "community_name": "Community 37", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 37, "community_name": "Community 37", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 37, "community_name": "Community 37", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 37, "community_name": "Community 37", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 37, "community_name": "Community 37", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 37, "community_name": "Community 37", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 80, "community_name": "Community 80", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 81, "community_name": "Community 81", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 18, "community_name": "Community 18", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 18, "community_name": "Community 18", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 18, "community_name": "Community 18", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 18, "community_name": "Community 18", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 18, "community_name": "Community 18", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective", "laLine truncated
const RAW_EDGES = [{"from": "app_vue", "to": "src_app_refreshbuttonautoicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "src_app_refreshpaneltitleicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "main_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "utils_sys_console_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_masksecret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_logapicryptobootinfo", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_main_masksecret", "to": "src_main_logapicryptobootinfo", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_ts", "to": "directives_index_setupglobdirectives", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_setupglobdirectives", "to": "core_auth_setupauthdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "core_roles_setuprolesdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_highlight_setuphighlightdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_ripple_setuprippledirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_core_roles_ts", "to": "core_roles_checkrolepermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_setuprolesdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_roles_checkrolepermission", "to": "core_roles_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_checkauthpermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_setupauthdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_checkauthpermission", "to": "core_auth_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_ripple_ts", "to": "business_ripple_setuprippledirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_highlightcode", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_insertlinenumbers", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_addcopybutton", "label": "contains", "title": "contains [EXTRACTED]", "dLine truncated
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 255}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 189}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 127}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 104}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 97}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 67}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 59}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 57}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 57}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 54}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 51}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 37}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 37}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 33}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 31}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 27}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 26}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 26}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 22}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 22}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 20}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 19}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 19}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 17}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 17}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 17}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 16}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 15}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 14}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 13}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 12}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 10}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 9}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 9}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 8}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 8}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 8}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 7}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 6}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 6}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 6}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 6}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 5}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 4}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 4}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 4}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 4}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 3}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 3}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 3}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 3}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 3}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 3}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 3}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 3}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 3}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 2}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 2}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 2}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 2}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 2}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 2}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 2}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 2}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 2}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 2}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 2}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 2}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 2}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 2}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "count": 2Line truncated
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
function esc(s) {
File diff suppressed because it is too large. Load diff
+30 -27
View File
@@ -17,8 +17,8 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/common/index.ts": 1778582068.0254738,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/directive/directive.d.ts": 1778582068.026978,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/api/api.d.ts": 1778582068.0246184,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1779926043.3788598,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1779896972.9881423,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1779944059.7845695,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1779942433.4020183,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/store/index.ts": 1778582068.0293276,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/router/index.ts": 1778775532.895603,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/locales/index.ts": 1778582068.004279,
@@ -42,7 +42,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/storage-slot-options.ts": 1779790341.466299,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/user-avatar.ts": 1779790341.943788,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/fullscreen-loading.ts": 1779117454.818312,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts": 1778582068.0393815,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts": 1779938225.7809103,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-payment-labels.ts": 1779199125.4894068,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts": 1779826490.6921933,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/fetch-paged-list.ts": 1778775532.895782,
@@ -144,7 +144,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-settings-panel/widget/ContainerSettings.vue": 1779525781.5920076,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-work-tab/index.vue": 1779525781.592554,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-chat-window/index.vue": 1779525781.59301,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-page-content/index.vue": 1779525781.5935369,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-page-content/index.vue": 1779942912.5296464,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-horizontal-menu/index.vue": 1779525781.5938804,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-horizontal-menu/widget/HorizontalSubmenu.vue": 1779525781.5942907,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-mixed-menu/index.vue": 1779525781.5947194,
@@ -176,6 +176,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-finance-confirm-fields/finance-attachments.ts": 1778987672.644368,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/qc-task-view-dialog/index.vue": 1779824466.9487405,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/dialog-form-body/index.vue": 1779790325.0384986,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-submit-readonly/index.vue": 1779943712.367428,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-cards/index.vue": 1779824462.0648055,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/order-operate-local-dialog/index.vue": 1779790325.101185,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/product-view-dialog/index.vue": 1779790325.4147334,
@@ -183,6 +184,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-storage-release-info/index.vue": 1779542542.2434525,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue": 1779830492.0922873,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/work-order-remark-dialog/index.vue": 1779790326.4187233,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue": 1779944059.476768,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-form-sections/index.vue": 1779830388.1680186,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-payment-detail-readonly/index.vue": 1779885197.8109932,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/system-view-dialog/index.vue": 1779889640.2061684,
@@ -206,7 +208,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception-check-item.ts": 1779007909.2933023,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts": 1779790323.3656075,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/infusion-schedule-handover.ts": 1779828287.9085703,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts": 1779841832.5347204,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts": 1779940548.5759916,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-third-party-item.ts": 1779017836.101254,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts": 1779615813.3431153,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/workflow.ts": 1779790323.5709383,
@@ -216,7 +218,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/collection-protocol.ts": 1779790323.1950388,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/chinaRegion.ts": 1778582067.8620915,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-entry-sms-notification.ts": 1779691739.8547683,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts": 1779882001.8287263,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts": 1779943218.8543665,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts": 1779882001.828555,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/ethnic.ts": 1778929297.3919344,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-lab-test-item.ts": 1779017838.8231559,
@@ -233,7 +235,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts": 1779692503.163169,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/auth.ts": 1778582067.8610063,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1779924334.8954625,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/auth/login/index.vue": 1779790342.0297484,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/auth/login/index.vue": 1779938231.136978,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/refund-confirm/index.vue": 1779866933.9349332,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/index.vue": 1779859546.0906804,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue": 1779525781.613681,
@@ -295,7 +297,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/dict/index.vue": 1779857764.622668,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/leave/index.vue": 1779856871.1846657,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/output-type/index.vue": 1779864076.2860792,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/index.vue": 1779859699.7487218,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/index.vue": 1779927539.2907355,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/SourceChainGraph.vue": 1779790358.2354698,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/source-chain/ChainLinkEdge.vue": 1779897605.7247741,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/source-chain/chainInject.ts": 1779790358.0222821,
@@ -312,7 +314,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts": 1779790360.26504,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/StepDetailPanel.vue": 1779790359.9189978,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/CompleteProductionTaskDialog.vue": 1779790359.5464847,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskInputEnhancedTable.vue": 1779925657.238902,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskInputEnhancedTable.vue": 1779927445.154478,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue": 1779925652.4510176,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue": 1779925648.9018784,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskOutputList.vue": 1779525781.6822913,
@@ -334,7 +336,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/index.vue": 1779864504.1085482,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/ThirdPartyCompanyTab.vue": 1779864511.579237,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue": 1779864345.8312566,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue": 1779864348.32489,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue": 1779928630.307365,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue": 1779884110.7197206,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue": 1779926469.2154074,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/storage-release-review/index.vue": 1779857044.9472554,
@@ -351,9 +353,9 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-type/CellProductSpecTab.vue": 1779864875.1171246,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/index.vue": 1779871734.0706396,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/CheckupPackagePanel.vue": 1779790354.1964018,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/index.vue": 1779869699.206076,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/index.vue": 1779941177.032692,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/InfusionScheduleHandoverDialog.vue": 1779830388.4782345,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleViewDialog.vue": 1779830147.6915238,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleViewDialog.vue": 1779944277.8142326,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleCancelDialog.vue": 1779785733.3155978,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleEditDialog.vue": 1779790355.024449,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue": 1779865135.982138,
@@ -362,21 +364,22 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue": 1779871848.481235,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelViewDialog.vue": 1779790352.7457726,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue": 1779923364.6801205,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-refund-confirm/index.vue": 1779857041.790119,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/index.vue": 1779857039.564749,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue": 1779857036.1353672,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue": 1779830031.9999688,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-refund-confirm/index.vue": 1779941952.780368,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/index.vue": 1779943711.951672,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue": 1779943344.5801125,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue": 1779940973.1366372,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue": 1779927107.3150873,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue": 1779824973.037717,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseMaterialDialog.vue": 1779829323.2023485,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/index.vue": 1779869680.1829238,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/index.vue": 1779941172.6551938,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationDetailDialog.vue": 1779841841.9942307,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue": 1779870527.5393612,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue": 1779830501.0475526,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/InfusionScheduleTab.vue": 1779923781.8331578,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue": 1779835904.8876522,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue": 1779870993.5511904,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue": 1779940944.365843,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue": 1779944085.8337502,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/InfusionScheduleTab.vue": 1779940945.395297,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue": 1779940036.5255854,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue": 1779940970.6155307,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-price/index.vue": 1779864955.5971668,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/index.vue": 1779869699.1782947,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/index.vue": 1779935807.47013,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupReserveItemsTable.vue": 1779790354.7691844,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupViewDialog.vue": 1779790354.8122675,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupRegisterDialog.vue": 1779790354.7432914,
@@ -384,7 +387,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/checkup-reserve-items.ts": 1779923701.3416343,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupFillDialog.vue": 1779790354.549774,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupMarkCheckedDialog.vue": 1779923727.345238,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue": 1779857023.6723864,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue": 1779943278.6593158,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue": 1779857021.6808643,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue": 1779864957.7299743,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-spec/index.vue": 1779864953.7554574,
@@ -402,7 +405,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/table.ts": 1779257771.098434,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/menu.ts": 1779790340.600478,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/setting.ts": 1778582068.0225098,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts": 1779313361.6982958,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts": 1779938228.2554607,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/routesAlias.ts": 1778582068.0211735,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/index.ts": 1779232037.727516,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/core/RouteTransformer.ts": 1778582068.0132053,
@@ -413,12 +416,12 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/core/RoutePermissionValidator.ts": 1778582068.0127926,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/core/index.ts": 1778582068.0138035,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/core/IframeRouteManager.ts": 1778582068.0121944,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts": 1779882681.237498,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts": 1779941886.108251,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/index.ts": 1778598510.6043763,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/exception.ts": 1779546186.993006,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/routes/staticRoutes.ts": 1779546226.1088154,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/routes/asyncRoutes.ts": 1778582068.0206802,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts": 1779546205.411209,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts": 1779938234.2979362,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/afterEach.ts": 1778582068.0146143,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/assets/svg/my-copy.svg": 1778582067.9349968,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/assets/svg/search.svg": 1778582067.9393654,
+6 -5
View File
@@ -167,16 +167,17 @@ export function fetchClinicalPaymentDetail(id: string) {
})
}
export function submitClinicalReceipt(id: string) {
export function submitClinicalReceipt(id: string, data?: Record<string, unknown>) {
return request.post({
url: `/web/admin/clinical-payments/${id}/submit-receipt`
url: `/web/admin/clinical-payments/${id}/submit-receipt`,
params: data
})
}
export function batchSubmitClinicalReceipt(ids: string[]) {
export function batchSubmitClinicalReceipt(ids: string[], data?: Record<string, unknown>) {
return request.post({
url: '/web/admin/clinical-payments/submit-receipt-batch',
params: { ids }
params: { paymentIds: ids, ...data }
})
}
@@ -197,7 +198,7 @@ export function submitClinicalRefund(id: string, data: any) {
export function batchSubmitClinicalRefund(ids: string[], data: any) {
return request.post({
url: '/web/admin/clinical-payments/submit-refund-batch',
params: { ...data, ids }
params: { ...data, paymentIds: ids }
})
}
@@ -158,6 +158,8 @@ export function fetchOutboundReleaseReviewList(params?: {
reviewConclusion?: string
qcStatus?: string
keyword?: string
/** pilot_service | clinical_application */
bizType?: string
}) {
return request.get<PageList<OutboundReleaseReview>>({
url: '/web/admin/pilot-release-reviews',
@@ -0,0 +1,208 @@
<!-- 临床应用缴费/退费提交信息只读展示 -->
<template>
<div class="clinical-payment-submit-readonly">
<h4 v-if="title" class="detail-block-title">{{ title }}</h4>
<dl class="view-kv-grid view-kv-grid--4">
<div class="view-kv">
<dt>申请单号</dt>
<dd>{{ dash(detail?.applicationNo) }}</dd>
</div>
<div class="view-kv">
<dt>患者姓名</dt>
<dd>{{ dash(detail?.patientName) }}</dd>
</div>
<div class="view-kv">
<dt>渠道名称</dt>
<dd>{{ dash(detail?.channelName) }}</dd>
</div>
<div class="view-kv">
<dt>细胞类型/规格</dt>
<dd>{{ dash(detail?.cellTypeSpec) }}</dd>
</div>
<div class="view-kv">
<dt>输注时间</dt>
<dd>{{ dash(detail?.infusionTime) }}</dd>
</div>
<div v-if="showPayStatus" class="view-kv">
<dt>缴费状态</dt>
<dd>
<el-tag :type="payStatusTagType(String(detail?.payStatus || ''))" size="small">
{{ payStatusLabel(String(detail?.payStatus || '')) }}
</el-tag>
</dd>
</div>
<template v-if="mode === 'refund'">
<div class="view-kv">
<dt>缴费金额(元)</dt>
<dd>{{ formatAmount(detail?.paymentAmount ?? detail?.amount) }}</dd>
</div>
</template>
<template v-if="mode === 'receipt' || mode === 'full'">
<div class="view-kv">
<dt>缴费金额(元)</dt>
<dd>{{ formatAmount(detail?.paymentAmount ?? detail?.amount) }}</dd>
</div>
<div v-if="detail?.remark" class="view-kv view-kv-span-2">
<dt>备注</dt>
<dd>{{ dash(detail?.remark) }}</dd>
</div>
<div class="view-field-block view-kv-span-2 clinical-payment-submit-readonly__attachments">
<div class="view-field-block__label">转账凭证</div>
<ProtocolAttachmentReadonly
:files="receiptAttachmentFiles"
@preview="(f) => emit('preview', f)"
@download="(f) => emit('download', f)"
/>
</div>
</template>
<template v-if="mode === 'refund' || (mode === 'full' && hasRefundInfo)">
<div class="view-kv">
<dt>退费金额(元)</dt>
<dd>{{ formatAmount(detail?.refundAmount) }}</dd>
</div>
<div v-if="detail?.refundRemark" class="view-kv view-kv-span-2">
<dt>退费备注</dt>
<dd>{{ dash(detail?.refundRemark) }}</dd>
</div>
<div class="view-field-block view-kv-span-2 clinical-payment-submit-readonly__attachments">
<div class="view-field-block__label">退费附件</div>
<ProtocolAttachmentReadonly
:files="refundAttachmentFiles"
@preview="(f) => emit('preview', f)"
@download="(f) => emit('download', f)"
/>
</div>
</template>
</dl>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import { payStatusLabel, payStatusTagType } from '@/utils/status-tag-registry'
const props = withDefaults(
defineProps<{
detail?: Record<string, unknown> | null
title?: string
mode?: 'receipt' | 'refund' | 'full'
showPayStatus?: boolean
}>(),
{ mode: 'receipt', showPayStatus: false }
)
const emit = defineEmits<{
(e: 'preview', file: Record<string, unknown>): void
(e: 'download', file: Record<string, unknown>): void
}>()
function dash(v: unknown) {
if (v == null || v === '') return '—'
return String(v)
}
function formatAmount(v: unknown) {
if (v == null || v === '') return '—'
return '¥' + formatMoneyDisplay(v)
}
function urlsToFiles(urlField: unknown) {
const urls = String(urlField || '')
if (!urls.trim()) return []
return urls
.split(',')
.map((u, i) => {
const url = u.trim()
if (!url) return null
const name = url.includes('/') ? url.split('/').pop() || `附件${i + 1}` : url
return { id: `url_${i}`, fileUrl: url, fileName: name }
})
.filter(Boolean) as Array<Record<string, unknown>>
}
const receiptAttachmentFiles = computed(() => urlsToFiles(props.detail?.transferAttachments))
const refundAttachmentFiles = computed(() => urlsToFiles(props.detail?.refundAttachments))
const hasRefundInfo = computed(() => {
const d = props.detail
if (!d) return false
return (
d.refundAmount != null ||
Boolean(d.refundRemark) ||
Boolean(String(d.refundAttachments || '').trim())
)
})
</script>
<style scoped lang="scss">
.clinical-payment-submit-readonly {
width: 100%;
}
.detail-block-title {
margin: 0 0 12px;
font-size: 14px;
font-weight: 600;
color: var(--mint-text, #334155);
line-height: 1.4;
}
.view-kv-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px 20px;
margin: 0;
}
.view-kv-grid--4 {
@media (min-width: 720px) {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
.view-kv {
min-width: 0;
dt {
margin: 0 0 4px;
font-size: 12px;
color: var(--mint-text-muted, #64748b);
font-weight: 500;
}
dd {
margin: 0;
font-size: 14px;
color: var(--mint-text, #334155);
line-height: 1.5;
word-break: break-word;
}
}
.view-kv-span-2 {
grid-column: 1 / -1;
}
.view-field-block__label {
font-size: 12px;
color: var(--mint-text-muted, #64748b);
font-weight: 500;
margin-bottom: 8px;
}
.clinical-payment-submit-readonly__attachments {
margin-top: 4px;
}
.form-section-divider--inner {
height: 1px;
margin: 16px 0;
background: var(--mint-border, #e2e8f0);
}
</style>
@@ -0,0 +1,729 @@
<!-- 临床应用 · 输注计划缴费明细(查看态,对齐 ProtocolViewDialog 缴费明细) -->
<template>
<div
class="payment-detail-card"
:class="{
'payment-detail-card--refunded': payStatus === 'ytf',
'payment-detail-card--refund-pending': payStatus === 'tfqrz'
}"
>
<div class="pdc-header">
<div class="pdc-header-left" :class="payDetailColorClass(payStatus)">
缴费明细 ·
<span class="pdc-header-amount" :class="payDetailColorClass(payStatus)">
{{ fmtMoney(planAmount) }}
</span>
</div>
<el-tag :type="payStatusTagType(payStatus)" size="small">
{{ payStatusLabel(payStatus) }}
</el-tag>
</div>
<div class="pdc-info-row">
<div class="pdc-info-item">
<span class="info-label">应缴费金额(元)</span>
<span class="info-value">{{ fmtMoney(planAmount) }}</span>
</div>
<div class="pdc-info-item">
<span class="info-label">实缴金额(元)</span>
<span class="info-value">{{ fmtMoney(payment?.transferAmount ?? planAmount) }}</span>
</div>
<div v-if="payment?.remark" class="pdc-info-item">
<span class="info-label">备注</span>
<span class="info-value">{{ dash(payment?.remark) }}</span>
</div>
<div v-if="payStatus !== 'dfj' && payment?.updateTime" class="pdc-info-item">
<span class="info-label">提交时间</span>
<span class="info-value">{{ dash(payment?.updateTime) }}</span>
</div>
</div>
<div v-if="transferAttachmentFiles.length" class="pdc-attachments-row">
<div class="data-label">转账凭证</div>
<ProtocolAttachmentReadonly
:files="transferAttachmentFiles"
@preview="(f) => emit('preview', f)"
@download="(f) => emit('download', f)"
/>
</div>
<template v-if="flowSteps.length">
<div class="flow-section">
<div class="mini-flow">
<template v-for="(step, sIdx) in flowSteps" :key="`c-${step.key}`">
<div
v-if="step.connectorToNext"
class="mini-flow-connector"
:class="step.connectorToNext"
:style="miniFlowConnectorStyle(flowSteps.length, sIdx)"
/>
</template>
<div v-for="step in flowSteps" :key="step.key" class="mini-flow-step">
<div class="mini-flow-dot" :class="step.dotClass">{{ step.dotIcon }}</div>
<div class="mini-flow-label" :class="step.labelClass">{{ step.label }}</div>
</div>
</div>
<div class="flow-detail-cards">
<template v-for="step in flowSteps" :key="`d-${step.key}`">
<div
v-if="step.hasDetailCard"
class="flow-detail-card"
:class="'flow-detail-card--' + step.dotClass"
>
<div class="flow-detail-card__header">
<span class="flow-detail-card__dot" :class="step.dotClass">{{
step.dotIcon
}}</span>
<span class="flow-detail-card__title" :class="step.labelClass">{{
step.label
}}</span>
</div>
<div class="flow-detail-card__body">
<template v-if="step.key === 'pay'">
<div class="flow-detail-card__kv">
<span class="flow-detail-card__label">确认状态</span>
<span class="flow-detail-card__value">
<el-tag type="success" size="small">已提交</el-tag>
</span>
</div>
<div v-if="payment?.remark" class="flow-detail-card__kv">
<span class="flow-detail-card__label">备注</span>
<span class="flow-detail-card__value">{{ payment.remark }}</span>
</div>
<div v-if="transferAttachmentFiles.length" class="flow-detail-card__kv">
<span class="flow-detail-card__label">转账凭证</span>
<ProtocolAttachmentReadonly
:files="transferAttachmentFiles"
@preview="(f) => emit('preview', f)"
@download="(f) => emit('download', f)"
/>
</div>
</template>
<template v-else-if="step.key === 'receipt-finance'">
<div class="flow-detail-card__kv">
<span class="flow-detail-card__label">确认状态</span>
<span class="flow-detail-card__value">
<el-tag v-if="isReceiptFinanceConfirmed" type="success" size="small"
>已确认</el-tag
>
<el-tag v-else type="warning" size="small">待确认</el-tag>
</span>
</div>
<div
v-if="isReceiptFinanceConfirmed && receiptFinanceTime"
class="flow-detail-card__kv"
>
<span class="flow-detail-card__label">确认时间</span>
<span class="flow-detail-card__value">{{ receiptFinanceTime }}</span>
</div>
<div
v-if="isReceiptFinanceConfirmed && payment?.financeRemark"
class="flow-detail-card__kv"
>
<span class="flow-detail-card__label">财务备注</span>
<span class="flow-detail-card__value">{{ payment.financeRemark }}</span>
</div>
<div
v-if="isReceiptFinanceConfirmed && financeAttachmentFiles.length"
class="flow-detail-card__kv"
>
<span class="flow-detail-card__label">财务附件</span>
<ProtocolAttachmentReadonly
:files="financeAttachmentFiles"
@preview="(f) => emit('preview', f)"
@download="(f) => emit('download', f)"
/>
</div>
</template>
<template v-else-if="step.key === 'refund-apply'">
<div class="flow-detail-card__kv">
<span class="flow-detail-card__label">退费金额(元)</span>
<span class="flow-detail-card__value" :class="payDetailColorClass(payStatus)">{{
fmtMoney(payment?.refundAmount)
}}</span>
</div>
<div v-if="payment?.refundRemark" class="flow-detail-card__kv">
<span class="flow-detail-card__label">退费备注</span>
<span class="flow-detail-card__value">{{ payment.refundRemark }}</span>
</div>
<div v-if="refundAttachmentFiles.length" class="flow-detail-card__kv">
<span class="flow-detail-card__label">退费附件</span>
<ProtocolAttachmentReadonly
:files="refundAttachmentFiles"
@preview="(f) => emit('preview', f)"
@download="(f) => emit('download', f)"
/>
</div>
</template>
<template v-else-if="step.key === 'refund-finance'">
<div class="flow-detail-card__kv">
<span class="flow-detail-card__label">确认状态</span>
<span class="flow-detail-card__value">
<el-tag type="danger" size="small">已退费</el-tag>
</span>
</div>
<div v-if="refundFinanceTime" class="flow-detail-card__kv">
<span class="flow-detail-card__label">确认时间</span>
<span class="flow-detail-card__value">{{ refundFinanceTime }}</span>
</div>
<div v-if="payment?.refundFinanceRemark" class="flow-detail-card__kv">
<span class="flow-detail-card__label">财务备注</span>
<span class="flow-detail-card__value">{{ payment.refundFinanceRemark }}</span>
</div>
<div v-if="refundFinanceAttachmentFiles.length" class="flow-detail-card__kv">
<span class="flow-detail-card__label">财务附件</span>
<ProtocolAttachmentReadonly
:files="refundFinanceAttachmentFiles"
@preview="(f) => emit('preview', f)"
@download="(f) => emit('download', f)"
/>
</div>
</template>
</div>
</div>
</template>
</div>
</div>
</template>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import { payStatusLabel, payStatusTagType } from '@/utils/status-tag-registry'
const props = defineProps<{
payment?: Record<string, any> | null
}>()
const emit = defineEmits<{
(e: 'preview', file: Record<string, unknown>): void
(e: 'download', file: Record<string, unknown>): void
}>()
interface MiniFlowStep {
key: string
label: string
dotClass: string
dotIcon: string
labelClass: string
connectorToNext?: string
hasDetailCard?: boolean
}
const payStatus = computed(() => String(props.payment?.payStatus || 'dfj'))
const planAmount = computed(
() => props.payment?.paymentAmount ?? props.payment?.amount ?? null
)
const isReceiptFinanceConfirmed = computed(() => {
const s = payStatus.value
return s !== 'jfqrz' && s !== 'dfj'
})
const receiptFinanceTime = computed(
() => props.payment?.financeConfirmTime || props.payment?.updateTime || ''
)
const refundFinanceTime = computed(
() => props.payment?.refundFinanceConfirmTime || props.payment?.updateTime || ''
)
const transferAttachmentFiles = computed(() =>
urlsToAttachmentFiles(String(props.payment?.transferAttachments || ''))
)
const financeAttachmentFiles = computed(() =>
urlsToAttachmentFiles(String(props.payment?.financeConfirmAttachments || ''))
)
const refundAttachmentFiles = computed(() =>
urlsToAttachmentFiles(String(props.payment?.refundAttachments || ''))
)
const refundFinanceAttachmentFiles = computed(() =>
urlsToAttachmentFiles(String(props.payment?.refundFinanceConfirmAttachments || ''))
)
const flowSteps = computed(() => buildMiniFlowSteps(props.payment || {}))
function dash(v: unknown) {
if (v == null || v === '') return '—'
return String(v)
}
function fmtMoney(v: unknown) {
if (v == null || v === '') return '—'
return '¥' + formatMoneyDisplay(v)
}
function urlsToAttachmentFiles(urls: string) {
if (!urls.trim()) return []
return urls
.split(',')
.map((u, i) => {
const url = u.trim()
if (!url) return null
const name = url.includes('/') ? url.split('/').pop() || `附件${i + 1}` : url
return { id: `url_${i}`, fileUrl: url, fileName: name, fileSize: 0 }
})
.filter(Boolean) as Array<Record<string, unknown>>
}
function payDetailColorClass(status: string) {
if (status === 'ytf') return 'red'
if (status === 'tfqrz') return 'amber'
return 'green'
}
function buildMiniFlowSteps(detail: Record<string, any>): MiniFlowStep[] {
const s = String(detail.payStatus || '')
if (s === 'dfj') return []
const steps: MiniFlowStep[] = []
steps.push({
key: 'pay',
label: '缴费确认',
dotClass: 'done',
dotIcon: '✓',
labelClass: 'done',
connectorToNext: 'done',
hasDetailCard: true
})
if (s === 'jfqrz') {
steps.push({
key: 'receipt-finance',
label: '财务确认',
dotClass: 'current-amber',
dotIcon: '●',
labelClass: 'current-amber',
hasDetailCard: true
})
} else {
steps.push({
key: 'receipt-finance',
label: '财务确认',
dotClass: 'done',
dotIcon: '✓',
labelClass: 'done',
connectorToNext: s === 'yjf' ? undefined : 'done',
hasDetailCard: true
})
}
if (s === 'tfqrz' || s === 'ytf') {
steps.push({
key: 'refund-apply',
label: '退费申请',
dotClass: s === 'tfqrz' ? 'current-amber' : 'done',
dotIcon: s === 'tfqrz' ? '●' : '✓',
labelClass: s === 'tfqrz' ? 'current-amber' : 'done',
connectorToNext: s === 'tfqrz' ? 'pending-gray' : 'done-red',
hasDetailCard: true
})
}
if (s === 'tfqrz') {
steps.push({
key: 'refund-finance',
label: '退费确认',
dotClass: 'pending-gray',
dotIcon: '○',
labelClass: 'pending-gray',
hasDetailCard: false
})
} else if (s === 'ytf') {
steps.push({
key: 'refund-finance',
label: '退费确认',
dotClass: 'done-red',
dotIcon: '✓',
labelClass: 'done-red',
hasDetailCard: true
})
}
if (steps.length) {
delete steps[steps.length - 1].connectorToNext
}
return steps
}
function miniFlowConnectorStyle(total: number, index: number) {
const leftPct = ((index + 0.5) / total) * 100
const widthPct = 100 / total
return `left: calc(${leftPct}% + 12px); width: calc(${widthPct}% - 12px);`
}
</script>
<style scoped lang="scss">
.payment-detail-card {
background: #fff;
border-radius: 8px;
padding: 14px 16px;
border: 1px solid #e2e8f0;
&--refunded {
border-left: 3px solid #dc2626;
border-color: #e2e8f0;
border-left-color: #dc2626;
}
&--refund-pending {
border-left: 3px solid #d97706;
border-color: #e2e8f0;
border-left-color: #d97706;
}
}
.pdc-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
padding-bottom: 10px;
border-bottom: 1px solid #f1f5f9;
}
.pdc-header-left {
display: flex;
align-items: center;
gap: 6px;
font-size: 14px;
font-weight: 600;
color: #1e293b;
&::before {
content: '';
width: 2px;
height: 14px;
border-radius: 1px;
flex-shrink: 0;
}
&.green::before {
background: #10b981;
}
&.red::before {
background: #dc2626;
}
&.amber::before {
background: #d97706;
}
}
.pdc-header-amount {
font-size: 14px;
font-weight: 700;
margin-left: 4px;
&.green {
color: #059669;
}
&.red {
color: #dc2626;
}
&.amber {
color: #d97706;
}
}
.pdc-info-row {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 14px 20px;
margin-bottom: 12px;
}
.pdc-info-item {
display: flex;
flex-direction: column;
gap: 2px;
.info-label {
font-size: 11px;
color: #94a3b8;
}
.info-value {
font-size: 13px;
color: #1e293b;
font-weight: 500;
}
}
.pdc-attachments-row {
margin-bottom: 8px;
padding-top: 8px;
border-top: 1px dashed #e2e8f0;
display: flex;
flex-direction: column;
gap: 4px;
.data-label {
font-size: 11px;
color: #94a3b8;
font-weight: 500;
}
}
.flow-section {
margin-top: 12px;
}
.mini-flow {
display: flex;
align-items: center;
gap: 0;
margin: 12px 0;
padding: 10px 14px;
background: #f8fafc;
border-radius: 8px;
position: relative;
}
.mini-flow-step {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
flex: 1;
z-index: 1;
}
.mini-flow-dot {
width: 24px;
height: 24px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: 700;
z-index: 1;
&.done {
background: #10b981;
color: #fff;
box-shadow: 0 0 0 3px rgb(16 185 129 / 15%);
}
&.done-red {
background: #dc2626;
color: #fff;
box-shadow: 0 0 0 3px rgb(220 38 38 / 15%);
}
&.current-amber {
background: #fff;
border: 2px solid #d97706;
color: #d97706;
box-shadow: 0 0 0 3px rgb(217 119 6 / 15%);
}
&.pending-gray {
background: #f1f5f9;
color: #94a3b8;
border: 2px solid #e2e8f0;
}
}
.mini-flow-label {
font-size: 10px;
margin-top: 6px;
text-align: center;
max-width: 80px;
line-height: 1.3;
&.done {
color: #059669;
font-weight: 600;
}
&.done-red {
color: #dc2626;
font-weight: 600;
}
&.current-amber {
color: #d97706;
font-weight: 600;
}
&.pending-gray {
color: #94a3b8;
}
}
.mini-flow-connector {
position: absolute;
top: 22px;
height: 2px;
z-index: 0;
&.done {
background: #10b981;
}
&.done-red {
background: #dc2626;
}
&.pending-gray {
background: #e2e8f0;
}
}
.flow-detail-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 12px;
margin-top: 14px;
}
.flow-detail-card {
border: 1px solid #e2e8f0;
border-radius: 8px;
overflow: hidden;
&--current-amber {
border-color: #fde68a;
background: #fffbeb;
}
&--done-red {
border-left: 3px solid #dc2626;
background: #fff;
}
&--pending-gray {
border-style: dashed;
background: #f8fafc;
}
}
.flow-detail-card__header {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 14px;
border-bottom: 1px solid #f1f5f9;
background: #f8fafc;
.flow-detail-card--done-red & {
background: #fef2f2;
border-bottom-color: #fecaca;
}
.flow-detail-card--current-amber & {
background: #fffbeb;
border-bottom-color: #fde68a;
}
}
.flow-detail-card__dot {
width: 20px;
height: 20px;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 10px;
font-weight: 700;
flex-shrink: 0;
&.done {
background: #10b981;
color: #fff;
}
&.done-red {
background: #dc2626;
color: #fff;
}
&.current-amber {
background: #fff;
border: 2px solid #d97706;
color: #d97706;
}
&.pending-gray {
background: #f1f5f9;
border: 2px solid #e2e8f0;
color: #94a3b8;
}
}
.flow-detail-card__title {
font-size: 13px;
font-weight: 600;
color: #1e293b;
&.done {
color: #059669;
}
&.done-red {
color: #dc2626;
}
&.current-amber {
color: #d97706;
}
}
.flow-detail-card__body {
padding: 12px 14px;
display: flex;
flex-direction: column;
gap: 8px;
}
.flow-detail-card__kv {
display: flex;
flex-direction: column;
gap: 2px;
}
.flow-detail-card__label {
font-size: 11px;
color: #94a3b8;
}
.flow-detail-card__value {
font-size: 13px;
color: #1e293b;
font-weight: 500;
word-break: break-word;
&.red {
color: #dc2626;
}
&.amber {
color: #d97706;
}
&.green {
color: #059669;
}
}
@media (max-width: 768px) {
.pdc-info-row {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
</style>
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "label": "TaskExecutionDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "label": "RefundConfirmTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L1"}, {"id": "clinical_payment_confirm_refundconfirmtab_formatamount", "label": "formatAmount()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L397"}, {"id": "clinical_payment_confirm_refundconfirmtab_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L402"}, {"id": "clinical_payment_confirm_refundconfirmtab_isimageurl", "label": "isImageUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L408"}, {"id": "clinical_payment_confirm_refundconfirmtab_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L434"}, {"id": "clinical_payment_confirm_refundconfirmtab_handlestatustabchange", "label": "handleStatusTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L453"}, {"id": "clinical_payment_confirm_refundconfirmtab_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L458"}, {"id": "clinical_payment_confirm_refundconfirmtab_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L463"}, {"id": "clinical_payment_confirm_refundconfirmtab_openconfirm", "label": "openConfirm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L469"}, {"id": "clinical_payment_confirm_refundconfirmtab_openviewconfirm", "label": "openViewConfirm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L477"}, {"id": "clinical_payment_confirm_refundconfirmtab_handlerowdblclick", "label": "handleRowDblClick()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L482"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L347", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L348", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L359", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L364", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_payment_submit_readonly_index_vue", "relation": "imports_from", "confidence": "EXTRLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_workordertasksublist_vue", "label": "WorkOrderTaskSubList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/WorkOrderTaskSubList.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_infusion_schedule_management_scheduleviewdialog_vue", "label": "ScheduleViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleViewDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "label": "outbound-release-review.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L1"}, {"id": "api_outbound_release_review_fetchoutboundreleasereviewlist", "label": "fetchOutboundReleaseReviewList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L154"}, {"id": "api_outbound_release_review_fetchoutboundreleasereviewdetail", "label": "fetchOutboundReleaseReviewDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L170"}, {"id": "api_outbound_release_review_submitoutboundreleasereview", "label": "submitOutboundReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L176"}, {"id": "api_outbound_release_review_batchreviewoutboundrelease", "label": "batchReviewOutboundRelease()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L190"}, {"id": "api_outbound_release_review_fetchoutboundreleasematerial", "label": "fetchOutboundReleaseMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L202"}, {"id": "api_outbound_release_review_fetchreleasereviewlist", "label": "fetchReleaseReviewList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L208"}, {"id": "api_outbound_release_review_updatereleasereview", "label": "updateReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L214"}, {"id": "api_outbound_release_review_deletereleasereview", "label": "deleteReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L221"}, {"id": "api_outbound_release_review_saveoutboundreleasematerial", "label": "saveOutboundReleaseMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L227"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_fetchoutboundreleasereviewlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L154", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_fetchoutboundreleasereviewdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L170", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_submitoutboundreleasereview", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L176", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_batchreviewoutboundrelease", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L190", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_fetchoutboundreleasematerial", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L202", "wLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_qcmaterialusagetab_vue", "label": "QcMaterialUsageTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_dispatchtaskdialog_vue", "label": "DispatchTaskDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L1"}, {"id": "production_work_order_dispatchtaskdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L291"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_dispatchtaskdialog_vue", "target": "production_work_order_dispatchtaskdialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L291", "weight": 1.0}], "raw_calls": [{"caller_nid": "production_work_order_dispatchtaskdialog_if", "callee": "initEditor", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L295"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_checkupmanagementtab_vue", "label": "CheckupManagementTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L1"}, {"id": "pilot_application_checkupmanagementtab_isrowselectable", "label": "isRowSelectable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L319"}, {"id": "pilot_application_checkupmanagementtab_handleselectionchange", "label": "handleSelectionChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L321"}, {"id": "pilot_application_checkupmanagementtab_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L337"}, {"id": "pilot_application_checkupmanagementtab_loadinstitutions", "label": "loadInstitutions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L358"}, {"id": "pilot_application_checkupmanagementtab_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L368"}, {"id": "pilot_application_checkupmanagementtab_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L373"}, {"id": "pilot_application_checkupmanagementtab_canfillcheckupinfo", "label": "canFillCheckupInfo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L384"}, {"id": "pilot_application_checkupmanagementtab_canmarkchecked", "label": "canMarkChecked()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L388"}, {"id": "pilot_application_checkupmanagementtab_caneditcheckup", "label": "canEditCheckup()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L391"}, {"id": "pilot_application_checkupmanagementtab_hasprimarycheckupactions", "label": "hasPrimaryCheckupActions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L394"}, {"id": "pilot_application_checkupmanagementtab_hasmorecheckupactions", "label": "hasMoreCheckupActions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L398"}, {"id": "pilot_application_checkupmanagementtab_handledropdowncommand", "label": "handleDropdownCommand()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L405"}, {"id": "pilot_application_checkupmanagementtab_handlefill", "label": "handleFill()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L416"}, {"id": "pilot_application_checkupmanagementtab_handleedit", "label": "handleEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L423"}, {"id": "pilot_application_checkupmanagementtab_onfillsuccess", "label": "onFillSuccess()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L430"}, {"id": "pilot_application_checkupmanagementtab_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L435"}, {"id": "pilot_application_checkupmanagementtab_handlebatchreservefromlist", "label": "handleBatchReserveFromList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue", "source_location": "L440"}, {"id": "pilot_aLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_infusionscheduletab_vue", "label": "InfusionScheduleTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/InfusionScheduleTab.vue", "source_location": "L1"}, {"id": "pilot_application_infusionscheduletab_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/InfusionScheduleTab.vue", "source_location": "L582"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_infusionscheduletab_vue", "target": "pilot_application_infusionscheduletab_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/InfusionScheduleTab.vue", "source_location": "L582", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskinputenhancedtable_vue", "label": "TaskInputEnhancedTable.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskInputEnhancedTable.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_refund_confirm_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-refund-confirm/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_pilotapplicationtab_vue", "label": "PilotApplicationTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L1"}, {"id": "pilot_application_pilotapplicationtab_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L367"}, {"id": "pilot_application_pilotapplicationtab_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L390"}, {"id": "pilot_application_pilotapplicationtab_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L395"}, {"id": "pilot_application_pilotapplicationtab_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L407"}, {"id": "pilot_application_pilotapplicationtab_handlecreate", "label": "handleCreate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L416"}, {"id": "pilot_application_pilotapplicationtab_caneditapplication", "label": "canEditApplication()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L422"}, {"id": "pilot_application_pilotapplicationtab_canvoidapplication", "label": "canVoidApplication()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L425"}, {"id": "pilot_application_pilotapplicationtab_hasprimarystatusactions", "label": "hasPrimaryStatusActions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L428"}, {"id": "pilot_application_pilotapplicationtab_hasmoreactions", "label": "hasMoreActions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L432"}, {"id": "pilot_application_pilotapplicationtab_handledropdowncommand", "label": "handleDropdownCommand()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L434"}, {"id": "pilot_application_pilotapplicationtab_handleedit", "label": "handleEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L448"}, {"id": "pilot_application_pilotapplicationtab_onformsaved", "label": "onFormSaved()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L453"}, {"id": "pilot_application_pilotapplicationtab_handledelete", "label": "handleDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L458"}, {"id": "pilot_application_pilotapplicationtab_runbatchstatusaction", "label": "runBatchStatusAction()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L478"}, {"id": "pilot_application_pilotapplicationtab_handlebatchstart", "label": "handleBatchStart()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L546"}, {"id": "pilot_application_pilotapplicationtab_handlebatchcomplete", "label": "handleBatchComplete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L555"}, {"id": "pilot_application_pilotapplicationtab_handlebatchvoid", "label": "handleBatchVoid()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue", "source_location": "L564"}, {"id": "pilot_application_pilotapplicationtab_handlestart", "label": "handleStarLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_payment_submit_readonly_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-submit-readonly/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_qcworkordertasksublist_vue", "label": "QcWorkOrderTaskSubList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L1"}, {"id": "qc_work_order_qcworkordertasksublist_protocolstatuslabelbysource", "label": "protocolStatusLabelBySource()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L512"}, {"id": "qc_work_order_qcworkordertasksublist_protocolstatustagtypebysource", "label": "protocolStatusTagTypeBySource()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L517"}, {"id": "qc_work_order_qcworkordertasksublist_nextmaterialrowkey", "label": "nextMaterialRowKey()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L560"}, {"id": "qc_work_order_qcworkordertasksublist_canfillresult", "label": "canFillResult()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L570"}, {"id": "qc_work_order_qcworkordertasksublist_canstarttask", "label": "canStartTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L581"}, {"id": "qc_work_order_qcworkordertasksublist_hasprimarytaskactions", "label": "hasPrimaryTaskActions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L586"}, {"id": "qc_work_order_qcworkordertasksublist_candeletetask", "label": "canDeleteTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L591"}, {"id": "qc_work_order_qcworkordertasksublist_hasmoretaskactions", "label": "hasMoreTaskActions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L596"}, {"id": "qc_work_order_qcworkordertasksublist_handledropdowncommand", "label": "handleDropdownCommand()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L603"}, {"id": "qc_work_order_qcworkordertasksublist_clearmaterialrow", "label": "clearMaterialRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L626"}, {"id": "qc_work_order_qcworkordertasksublist_ismaterialoptiondisabled", "label": "isMaterialOptionDisabled()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L633"}, {"id": "qc_work_order_qcworkordertasksublist_isduplicatematerial", "label": "isDuplicateMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L638"}, {"id": "qc_work_order_qcworkordertasksublist_handlereceptionattachmentdownload", "label": "handleReceptionAttachmentDownload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L808"}, {"id": "qc_work_order_qcworkordertasksublist_normalizeresultparams", "label": "normalizeResultParams()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L812"}, {"id": "qc_work_order_qcworkordertasksublist_toresultnumber", "label": "toResultNumber()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L820"}, {"id": "qc_work_order_qcworkordertasksublist_setresultnumber", "label": "setResultNumber()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue", "source_location": "L826"}, {"id": "qc_work_order_qcworkordertasksublist_hasresultvalue", "label": "hasResultValue()", "file_type": "code", "source_file": "/UserLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L1"}, {"id": "production_work_order_index_protocolstatuslabelbysource", "label": "protocolStatusLabelBySource()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L557"}, {"id": "production_work_order_index_protocolstatustagtypebysource", "label": "protocolStatusTagTypeBySource()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L562"}, {"id": "production_work_order_index_shouldshowtempemptyfield", "label": "shouldShowTempEmptyField()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L569"}, {"id": "production_work_order_index_formattempemptyfield", "label": "formatTempEmptyField()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L572"}, {"id": "production_work_order_index_formatoutboundschedulesortno", "label": "formatOutboundScheduleSortNo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L576"}, {"id": "production_work_order_index_formatoutboundscheduletotalcount", "label": "formatOutboundScheduleTotalCount()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L582"}, {"id": "production_work_order_index_handleadd", "label": "handleAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L631"}, {"id": "production_work_order_index_handletypetabchange", "label": "handleTypeTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L640"}, {"id": "production_work_order_index_submitadd", "label": "submitAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L646"}, {"id": "production_work_order_index_handlereceptionattachmentpreview", "label": "handleReceptionAttachmentPreview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L911"}, {"id": "production_work_order_index_handlereceptionattachmentdownload", "label": "handleReceptionAttachmentDownload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L915"}, {"id": "production_work_order_index_appstatuslabel", "label": "appStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L1029"}, {"id": "production_work_order_index_appstatustagtype", "label": "appStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L1038"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L515", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L516", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L517", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order", "relation": "imports_from", "confidence": "EXTRACTLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L1"}, {"id": "outbound_release_review_index_handleselectionchange", "label": "handleSelectionChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L279"}, {"id": "outbound_release_review_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L285"}, {"id": "outbound_release_review_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L302"}, {"id": "outbound_release_review_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L307"}, {"id": "outbound_release_review_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L317"}, {"id": "outbound_release_review_index_openreviewdialog", "label": "openReviewDialog()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L325"}, {"id": "outbound_release_review_index_onreviewsubmitted", "label": "onReviewSubmitted()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L335"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_handleselectionchange", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L279", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_loaddata", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L285", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_handlesearch", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L302", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_handlereset", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L307", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_handleview", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L317", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_openreviewdialog", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L325", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_onreviewsubmitted", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L335", "weight": 1.0}, {"source": "outbound_release_review_index_handlesearch", "target": "outbound_release_review_index_loaddata", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_checkup_management_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationformdialog_vue", "label": "ApplicationFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1"}, {"id": "pilot_application_applicationformdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1067"}, {"id": "pilot_application_applicationformdialog_loadclinicalcellproductprices", "label": "loadClinicalCellProductPrices()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1928"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationformdialog_vue", "target": "pilot_application_applicationformdialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1067", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationformdialog_vue", "target": "pilot_application_applicationformdialog_loadclinicalcellproductprices", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1928", "weight": 1.0}], "raw_calls": [{"caller_nid": "pilot_application_applicationformdialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1068"}, {"caller_nid": "pilot_application_applicationformdialog_loadclinicalcellproductprices", "callee": "loadEditData", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue", "source_location": "L1931"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_router_guards_beforeeach_ts", "label": "beforeEach.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L1"}, {"id": "guards_beforeeach_getpendingloading", "label": "getPendingLoading()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L75"}, {"id": "guards_beforeeach_resetpendingloading", "label": "resetPendingLoading()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L82"}, {"id": "guards_beforeeach_getrouteinitfailed", "label": "getRouteInitFailed()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L89"}, {"id": "guards_beforeeach_resetrouteinitstate", "label": "resetRouteInitState()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L96"}, {"id": "guards_beforeeach_setupbeforeeachguard", "label": "setupBeforeEachGuard()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L104"}, {"id": "guards_beforeeach_closeloading", "label": "closeLoading()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L128"}, {"id": "guards_beforeeach_handlerouteguard", "label": "handleRouteGuard()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L140"}, {"id": "guards_beforeeach_handleloginstatus", "label": "handleLoginStatus()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L204"}, {"id": "guards_beforeeach_isstaticroute", "label": "isStaticRoute()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L232"}, {"id": "guards_beforeeach_handledynamicroutes", "label": "handleDynamicRoutes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L262"}, {"id": "guards_beforeeach_fetchuserinfo", "label": "fetchUserInfo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L376"}, {"id": "guards_beforeeach_resetrouterstate", "label": "resetRouterState()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L387"}, {"id": "guards_beforeeach_handlerootpathredirect", "label": "handleRootPathRedirect()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L405"}, {"id": "guards_beforeeach_isunauthorizederror", "label": "isUnauthorizedError()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L422"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_router_guards_beforeeach_ts", "target": "vue_router", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L38", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_router_guards_beforeeach_ts", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L39", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_router_guards_beforeeach_ts", "target": "nprogress", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L40", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_router_guards_beforeeach_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_setting", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L41", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_router_guards_beforeeach_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts", "source_location": "L42", "weight": 1.0}, {"source": "users_wuzilong_work_00Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_auth_login_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/auth/login/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "label": "RefundConfirmTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L1"}, {"id": "clinical_payment_confirm_refundconfirmtab_formatamount", "label": "formatAmount()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L396"}, {"id": "clinical_payment_confirm_refundconfirmtab_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L401"}, {"id": "clinical_payment_confirm_refundconfirmtab_isimageurl", "label": "isImageUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L407"}, {"id": "clinical_payment_confirm_refundconfirmtab_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L433"}, {"id": "clinical_payment_confirm_refundconfirmtab_handlestatustabchange", "label": "handleStatusTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L452"}, {"id": "clinical_payment_confirm_refundconfirmtab_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L457"}, {"id": "clinical_payment_confirm_refundconfirmtab_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L462"}, {"id": "clinical_payment_confirm_refundconfirmtab_openconfirm", "label": "openConfirm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L468"}, {"id": "clinical_payment_confirm_refundconfirmtab_openviewconfirm", "label": "openViewConfirm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L476"}, {"id": "clinical_payment_confirm_refundconfirmtab_handlerowdblclick", "label": "handleRowDblClick()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L481"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L347", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L348", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L358", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue", "source_location": "L363", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_refundconfirmtab_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_payment_submit_readonly_index_vue", "relation": "imports_from", "confidence": "EXTRLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "label": "user.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "pinia", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L15", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L16", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_enums_appenum", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L17", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_router", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L18", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_worktab", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L19", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_types_router", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L20", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_router_guards_beforeeach", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L21", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_menu", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L22", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_storage_storage_config", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L23", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_auth", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L24", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_router_routesalias", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L25", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_store_modules_user_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts", "source_location": "L26", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_payment_submit_readonly_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-submit-readonly/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_edittaskinfodialog_vue", "label": "EditTaskInfoDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L1"}, {"id": "production_work_order_edittaskinfodialog_loadtaskdetail", "label": "loadTaskDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L81"}, {"id": "production_work_order_edittaskinfodialog_handleclose", "label": "handleClose()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L93"}, {"id": "production_work_order_edittaskinfodialog_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L100"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_edittaskinfodialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L55", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_edittaskinfodialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L56", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_edittaskinfodialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L57", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_edittaskinfodialog_vue", "target": "production_work_order_edittaskinfodialog_loadtaskdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L81", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_edittaskinfodialog_vue", "target": "production_work_order_edittaskinfodialog_handleclose", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L93", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_edittaskinfodialog_vue", "target": "production_work_order_edittaskinfodialog_handlesubmit", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L100", "weight": 1.0}, {"source": "production_work_order_edittaskinfodialog_handlesubmit", "target": "production_work_order_edittaskinfodialog_handleclose", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L113", "weight": 1.0}], "raw_calls": [{"caller_nid": "production_work_order_edittaskinfodialog_loadtaskdetail", "callee": "fetchProductionTaskDetail", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L84"}, {"caller_nid": "production_work_order_edittaskinfodialog_handlesubmit", "callee": "validate", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L102"}, {"caller_nid": "production_work_order_edittaskinfodialog_handlesubmit", "callee": "fetchUpdateProductionTask", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L106"}, {"caller_nid": "production_work_order_edittaskinfodialog_handlesubmit", "callee": "success", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue", "source_location": "L111"}, {"caller_nid": "production_work_order_edittaskinfodialLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_task_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_cell_product_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_info_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L1"}, {"id": "clinical_payment_info_index_formatamount", "label": "formatAmount()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L622"}, {"id": "clinical_payment_info_index_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L627"}, {"id": "clinical_payment_info_index_isimageurl", "label": "isImageUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L633"}, {"id": "clinical_payment_info_index_handledownloadfile", "label": "handleDownloadFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L637"}, {"id": "clinical_payment_info_index_handleselectionchange", "label": "handleSelectionChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L643"}, {"id": "clinical_payment_info_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L647"}, {"id": "clinical_payment_info_index_handlestatustabchange", "label": "handleStatusTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L663"}, {"id": "clinical_payment_info_index_resetreceiptform", "label": "resetReceiptForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L669"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_info_index_vue", "target": "clinical_payment_info_index_formatamount", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L622", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_info_index_vue", "target": "clinical_payment_info_index_fullfileurl", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L627", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_info_index_vue", "target": "clinical_payment_info_index_isimageurl", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L633", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_info_index_vue", "target": "clinical_payment_info_index_handledownloadfile", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L637", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_info_index_vue", "target": "clinical_payment_info_index_handleselectionchange", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L643", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_info_index_vue", "target": "clinical_payment_info_index_loaddata", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L647", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_info_index_vue", "target": "clinical_payment_info_index_handlestatustabchange", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue", "source_location": "L663", "weight": 1.0}, {"source": "users_wuzilong_work_0Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_infusion_schedule_management_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskinputenhancedtable_vue", "label": "TaskInputEnhancedTable.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskInputEnhancedTable.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_router_modules_sqxp_ts", "label": "sqxp.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_router_modules_sqxp_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_types_router", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_clinical_payment_confirm_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskoutputproductdialog_vue", "label": "TaskOutputProductDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskOutputProductDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "label": "router.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L1"}, {"id": "utils_router_configurenprogress", "label": "configureNProgress()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L24"}, {"id": "utils_router_setpagetitle", "label": "setPageTitle()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L37"}, {"id": "utils_router_formatmenutitle", "label": "formatMenuTitle()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L51"}, {"id": "utils_router_resolvesaferedirecttarget", "label": "resolveSafeRedirectTarget()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L70"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "vue_router", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L8", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_config", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L9", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "nprogress", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "nprogress_css", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L11", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_locales", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L12", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_router_routesalias", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L13", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "utils_router_configurenprogress", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L24", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "utils_router_setpagetitle", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L37", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "utils_router_formatmenutitle", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L51", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_router_ts", "target": "utils_router_resolvesaferedirecttarget", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L70", "weight": 1.0}], "raw_calls": [{"caller_nid": "utils_router_configurenprogress", "callee": "configure", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L25"}, {"caller_nid": "utils_router_setpagetitle", "callee": "setTimeout", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L40"}, {"caller_nid": "utils_router_formatmenutitle", "callee": "startsWith", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L53"}, {"caller_nid": "utils_router_formatmenutitle", "callee": "te", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L55"}, {"caller_nid": "utils_router_formatmenutitle", "callee": "$t", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts", "source_location": "L56"}, {"caller_nid": "utils_router_formatmenutitle", "callee": "pop", "Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business_ts", "label": "business.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L1"}, {"id": "api_business_fetchorderlist", "label": "fetchOrderList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L7"}, {"id": "api_business_fetchorderdetail", "label": "fetchOrderDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L33"}, {"id": "api_business_fetchassigndelivery", "label": "fetchAssignDelivery()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L39"}, {"id": "api_business_fetchreviewcancel", "label": "fetchReviewCancel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L55"}, {"id": "api_business_fetchcancelorder", "label": "fetchCancelOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L62"}, {"id": "api_business_fetchorderadjusts", "label": "fetchOrderAdjusts()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L78"}, {"id": "api_business_fetchadjustorder", "label": "fetchAdjustOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L84"}, {"id": "api_business_fetchorderitems", "label": "fetchOrderItems()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L109"}, {"id": "api_business_fetchpriceversiondetail", "label": "fetchPriceVersionDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L115"}, {"id": "api_business_fetchuploadattachment", "label": "fetchUploadAttachment()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L121"}, {"id": "api_business_fetchattachmentdownloadurl", "label": "fetchAttachmentDownloadUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L135"}, {"id": "api_business_fetchuploadproductimage", "label": "fetchUploadProductImage()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L142"}, {"id": "api_business_fetchsystemconfig", "label": "fetchSystemConfig()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L149"}, {"id": "api_business_fetchclinicalpayments", "label": "fetchClinicalPayments()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L157"}, {"id": "api_business_fetchclinicalpaymentdetail", "label": "fetchClinicalPaymentDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L164"}, {"id": "api_business_submitclinicalreceipt", "label": "submitClinicalReceipt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L170"}, {"id": "api_business_batchsubmitclinicalreceipt", "label": "batchSubmitClinicalReceipt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L177"}, {"id": "api_business_confirmclinicalreceipt", "label": "confirmClinicalReceipt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L184"}, {"id": "api_business_submitclinicalrefund", "label": "submitClinicalRefund()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L191"}, {"id": "api_business_batchsubmitclinicalrefund", "label": "batchSubmitClinicalRefund()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L198"}, {"id": "api_business_confirmclinicalrefund", "label": "confirmClinicalRefund()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L205"}, {"id": "api_business_fetchclinicalreceiptpending", "label": "fetchClinicalReceiptPending()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts", "source_location": "L212"}, {"id": "api_business_fetchclinicalreceiptconfirmed", "label": "fetchClinicalReceiptConfirmed()", "file_type": "code", "source_file": "/Users/wuzilong/work/0Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1"}, {"id": "qc_work_order_index_formattempcellproductfield", "label": "formatTempCellProductField()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L839"}, {"id": "qc_work_order_index_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L862"}, {"id": "qc_work_order_index_handlereceptionattachmentpreview", "label": "handleReceptionAttachmentPreview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1212"}, {"id": "qc_work_order_index_handlereceptionattachmentdownload", "label": "handleReceptionAttachmentDownload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1217"}, {"id": "qc_work_order_index_taskattachmentfullurl", "label": "taskAttachmentFullUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1221"}, {"id": "qc_work_order_index_handletaskattachmentpreview", "label": "handleTaskAttachmentPreview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1228"}, {"id": "qc_work_order_index_handletaskattachmentdownload", "label": "handleTaskAttachmentDownload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1233"}, {"id": "qc_work_order_index_formatconfiguredlabitems", "label": "formatConfiguredLabItems()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1249"}, {"id": "qc_work_order_index_formatconfiguredthirditems", "label": "formatConfiguredThirdItems()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1255"}, {"id": "qc_work_order_index_buildtasktypesections", "label": "buildTaskTypeSections()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1266"}, {"id": "qc_work_order_index_buildconfiguredonlysection", "label": "buildConfiguredOnlySection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1355"}, {"id": "qc_work_order_index_formatdetectmethods", "label": "formatDetectMethods()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1373"}, {"id": "qc_work_order_index_formatmetric", "label": "formatMetric()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1380"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_formattempcellproductfield", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L839", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L862", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_handlereceptionattachmentpreview", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1212", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_handlereceptionattachmentdownload", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleaseviewdialog_vue", "label": "OutboundReleaseViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationviewdialog_vue", "label": "ApplicationViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L1"}, {"id": "pilot_application_applicationviewdialog_for", "label": "for()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L966"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationviewdialog_vue", "target": "pilot_application_applicationviewdialog_for", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L966", "weight": 1.0}], "raw_calls": [{"caller_nid": "pilot_application_applicationviewdialog_for", "callee": "trim", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L967"}, {"caller_nid": "pilot_application_applicationviewdialog_for", "callee": "Number", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L970"}, {"caller_nid": "pilot_application_applicationviewdialog_for", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L971"}, {"caller_nid": "pilot_application_applicationviewdialog_for", "callee": "set", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L973"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_router_modules_sqxp_ts", "label": "sqxp.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_router_modules_sqxp_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_types_router", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_schedule_payment_detail_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L1"}, {"id": "clinical_schedule_payment_detail_index_dash", "label": "dash()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L254"}, {"id": "clinical_schedule_payment_detail_index_fmtmoney", "label": "fmtMoney()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L259"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_schedule_payment_detail_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolattachmentreadonly_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L194", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_schedule_payment_detail_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_money_format", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L195", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_schedule_payment_detail_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_status_tag_registry", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L196", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_schedule_payment_detail_index_vue", "target": "clinical_schedule_payment_detail_index_dash", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L254", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_clinical_schedule_payment_detail_index_vue", "target": "clinical_schedule_payment_detail_index_fmtmoney", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L259", "weight": 1.0}], "raw_calls": [{"caller_nid": "clinical_schedule_payment_detail_index_dash", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L256"}, {"caller_nid": "clinical_schedule_payment_detail_index_fmtmoney", "callee": "formatMoneyDisplay", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue", "source_location": "L261"}]}
@@ -206,6 +206,12 @@ function handleLoginStatus(
userStore: ReturnType<typeof useUserStore>,
next: NavigationGuardNext
): boolean {
// 已登录用户访问登录页时,进入系统首页(由动态路由守卫解析具体落点)
if (userStore.isLogin && to.path === RoutesAlias.Login) {
next({ path: '/', replace: true })
return false
}
// 已登录或访问登录页或静态路由,直接放行
if (userStore.isLogin || to.path === RoutesAlias.Login || isStaticRoute(to.path)) {
return true
+18 -10
View File
@@ -40,7 +40,7 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
path: 'protocol-audit',
component: '/cell-storage/protocol-audit/index',
meta: {
title: '采集协议单管理',
title: '采集协议单',
keepAlive: true,
menuCode: 'biz:cellStorageProtocolAudit:list'
}
@@ -175,7 +175,7 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
path: 'audit',
component: '/research-donation/audit/index',
meta: {
title: '捐赠协议单管理',
title: '捐赠协议单',
keepAlive: true,
menuCode: 'biz:researchDonationAudit:list'
}
@@ -207,7 +207,8 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
title: '中试服务申请单',
keepAlive: true,
menuCode: 'pilot-service:pilot-application:list'
}
},
props: { bizType: 'pilot_service' }
},
{
id: 'PIL00000000000000000000000000002',
@@ -219,7 +220,8 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
keepAlive: false,
isHide: true,
menuCode: 'pilot-service:checkup-management:list'
}
},
props: { bizType: 'pilot_service' }
},
{
id: 'PIL00000000000000000000000000003',
@@ -231,7 +233,8 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
keepAlive: false,
isHide: true,
menuCode: 'pilot-service:infusion-schedule-management:list'
}
},
props: { bizType: 'pilot_service' }
},
{
id: 'PIL00000000000000000000000000004',
@@ -242,7 +245,8 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
title: '出库放行审核',
keepAlive: true,
menuCode: 'pilot-service:outbound-release-review:list'
}
},
props: { bizType: 'pilot_service' }
}
]
},
@@ -282,6 +286,7 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
meta: {
title: '体检管理',
keepAlive: true,
isHide: true,
menuCode: 'clinical-application:checkup-management:list'
},
props: { bizType: 'clinical_application' }
@@ -293,7 +298,8 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
component: '/pilot-service/infusion-schedule-management/index',
meta: {
title: '输注计划管理',
keepAlive: true,
keepAlive: false,
isHide: true,
menuCode: 'clinical-application:infusion-schedule-management:list'
},
props: { bizType: 'clinical_application' }
@@ -305,7 +311,8 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
component: '/pilot-service/clinical-payment-info/index',
meta: {
title: '缴费信息',
keepAlive: true,
keepAlive: false,
isHide: true,
menuCode: 'clinical-application:payment-info:list'
}
},
@@ -315,7 +322,7 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
path: 'clinical-payment-confirm',
component: '/pilot-service/clinical-payment-confirm/index',
meta: {
title: '缴费确认(财务)',
title: '缴退费财务确认',
keepAlive: true,
menuCode: 'clinical-application:payment-confirm:list'
}
@@ -327,7 +334,8 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
component: '/pilot-service/clinical-refund-confirm/index',
meta: {
title: '退费确认(财务)',
keepAlive: true,
keepAlive: false,
isHide: true,
menuCode: 'clinical-application:refund-confirm:list'
}
},
+6 -2
View File
@@ -18,11 +18,12 @@ import { LanguageEnum } from '@/enums/appEnum'
import { router } from '@/router'
import { useWorktabStore } from './worktab'
import { AppRouteRecord } from '@/types/router'
import { setPageTitle } from '@/utils/router'
import { resetRouterState } from '@/router/guards/beforeEach'
import { useMenuStore } from './menu'
import { StorageConfig } from '@/utils/storage/storage-config'
import { fetchLogout } from '@/api/auth'
import { RoutesAlias } from '@/router/routesAlias'
import { resolveSafeRedirectTarget } from '@/utils/router'
/**
* 用户状态管理
@@ -135,7 +136,10 @@ export const useUserStore = defineStore(
resetRouterState(500)
// 跳转到登录页,携带当前路由作为 redirect 参数
const currentRoute = router.currentRoute.value
const redirect = currentRoute.path !== '/login' ? currentRoute.fullPath : undefined
const redirect =
currentRoute.path !== RoutesAlias.Login
? resolveSafeRedirectTarget(currentRoute.fullPath, '')
: ''
router.push({
name: 'Login',
query: redirect ? { redirect } : undefined
+19
View File
@@ -10,6 +10,10 @@ import AppConfig from '@/config'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import i18n, { $t } from '@/locales'
import { RoutesAlias } from '@/router/routesAlias'
/** 历史遗留登录路径(与 RoutesAlias.Login 等价) */
const LEGACY_LOGIN_PATHS = new Set([RoutesAlias.Login, '/login'])
/** 扩展的路由配置类型 */
export type AppRouteRecordRaw = RouteRecordRaw & {
@@ -59,3 +63,18 @@ export const formatMenuTitle = (title: string): string => {
}
return ''
}
/**
* 解析登录后的安全跳转地址,避免 redirect 指回登录页导致无法进入系统
*/
export function resolveSafeRedirectTarget(redirect: unknown, fallback = '/'): string {
const raw = typeof redirect === 'string' ? redirect.trim() : ''
if (!raw) return fallback
const pathOnly = raw.split('?')[0].split('#')[0]
const normalized = pathOnly.startsWith('/') ? pathOnly : `/${pathOnly}`
if (LEGACY_LOGIN_PATHS.has(normalized)) {
return fallback
}
return raw
}
+6 -3
View File
@@ -86,6 +86,8 @@
<script setup lang="ts">
import { useUserStore } from '@/store/modules/user'
import { fetchLogin } from '@/api/auth'
import { resetRouteInitState } from '@/router/guards/beforeEach'
import { resolveSafeRedirectTarget } from '@/utils/router'
import { ElNotification, type FormInstance, type FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { User, Lock } from '@element-plus/icons-vue'
@@ -143,9 +145,10 @@
message: `欢迎回来,${userInfo.realName || userInfo.username}!`
})
// 获取 redirect 参数,如果存在则跳转到指定页面,否则跳转到首页
const redirect = route.query.redirect as string
router.push(redirect || '/')
// 避免 redirect 指回登录页(如登出时误写入 /auth/login)
resetRouteInitState()
const target = resolveSafeRedirectTarget(route.query.redirect)
await router.push(target)
} catch (error: any) {
ElMessage.error(error?.message || '登录失败,请稍后重试')
} finally {
@@ -6,7 +6,7 @@
<div class="panel-top">
<h2>体检记录</h2>
</div>
<CheckupManagementTab />
<CheckupManagementTab :biz-type="bizType" />
</section>
</div>
</template>
@@ -16,6 +16,7 @@
defineOptions({ name: 'CheckupManagement' })
const props = defineProps<{ bizType?: string }>()
const router = useRouter()
const route = useRoute()
const isPilotRedirect = computed(() => route.name === 'PilotCheckupManagement')
@@ -0,0 +1,701 @@
<!-- 缴退费财务确认 · 退费 Tab(临床应用) -->
<!-- eslint-disable vue/no-v-model-argument -->
<template>
<div class="refund-confirm-tab">
<el-tabs
v-model="activeTab"
class="work-order-type-tabs"
@tab-change="handleStatusTabChange"
>
<el-tab-pane label="待确认" name="pending" />
<el-tab-pane label="已确认" name="confirmed" />
</el-tabs>
<div class="refund-confirm-body">
<div class="filter-block">
<el-form :model="searchForm" class="filter-form" label-position="top" @submit.prevent>
<div class="filter-grid">
<el-form-item label="关键词">
<el-input
v-model="searchForm.keyword"
placeholder="申请单号/患者姓名"
clearable
@keyup.enter="handleSearch"
/>
</el-form-item>
</div>
<div class="filter-actions-row">
<span class="filter-hint">支持按申请单号、患者姓名模糊检索。</span>
<div class="filter-actions-end">
<el-button class="btn-ghost" @click="handleReset">
<el-icon><RefreshLeft /></el-icon>重置
</el-button>
<el-button class="btn-main" type="primary" @click="handleSearch">
<el-icon><Search /></el-icon>搜索
</el-button>
</div>
</div>
</el-form>
</div>
<div class="list-body list-wrap refund-confirm-table-wrap">
<el-table
class="list-table"
:data="tableData"
v-loading="loading"
stripe
row-key="id"
@row-dblclick="handleRowDblClick"
>
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
:index="(index) => (pagination.page - 1) * pagination.pageSize + index + 1"
/>
<el-table-column
prop="applicationNo"
label="申请单号"
min-width="140"
align="center"
header-align="center"
/>
<el-table-column
prop="patientName"
label="患者姓名"
min-width="100"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.patientName || '-' }}</template>
</el-table-column>
<el-table-column
prop="channelName"
label="渠道名称"
min-width="120"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.channelName || '-' }}</template>
</el-table-column>
<el-table-column
prop="cellTypeSpec"
label="细胞类型/规格"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.cellTypeSpec || '-' }}</template>
</el-table-column>
<el-table-column
prop="infusionTime"
label="输注时间"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.infusionTime || '-' }}</template>
</el-table-column>
<el-table-column
prop="paymentAmount"
label="缴费金额(元)"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">
<span class="amount-text">{{ formatAmount(row.paymentAmount) }}</span>
</template>
</el-table-column>
<el-table-column
prop="refundAmount"
label="退费金额(元)"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">
<span class="amount-text">{{ formatAmount(row.refundAmount) }}</span>
</template>
</el-table-column>
<el-table-column
prop="payStatus"
label="状态"
min-width="110"
align="center"
header-align="center"
>
<template #default>
<el-tag :type="activeTab === 'pending' ? 'warning' : 'success'" size="small">
{{ activeTab === 'pending' ? '退费确认中' : '已退费' }}
</el-tag>
</template>
</el-table-column>
<el-table-column
v-if="activeTab === 'confirmed'"
prop="updateTime"
label="确认时间"
min-width="170"
align="center"
header-align="center"
/>
<el-table-column
v-if="activeTab === 'confirmed'"
prop="refundFinanceRemark"
label="财务备注"
min-width="120"
align="center"
header-align="center"
show-overflow-tooltip
>
<template #default="{ row }">{{ row.refundFinanceRemark || '-' }}</template>
</el-table-column>
<el-table-column
v-if="activeTab === 'pending'"
prop="createTime"
label="创建时间"
min-width="170"
align="center"
header-align="center"
/>
<el-table-column
label="操作"
min-width="140"
fixed="right"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-button
v-if="activeTab === 'pending'"
class="btn-op-item primary"
@click="openConfirm(row)"
>
<el-icon><Check /></el-icon>确认退费
</el-button>
<el-button v-else class="btn-op-item" @click="openViewConfirm(row)">
<el-icon><View /></el-icon>查看确认信息
</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination list-pager-bar">
<el-pagination
:current-page="pagination.page"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[10, 20, 50]"
layout="total, sizes, prev, pager, next"
@size-change="(val) => ((pagination.page = 1), (pagination.pageSize = val), loadData())"
@current-change="(val) => ((pagination.page = val), loadData())"
/>
</div>
</div>
<!-- 确认退费弹窗 -->
<el-dialog
v-model="dialogVisible"
title="确认退费"
width="900px"
class="dialog-form-layout"
align-center
destroy-on-close
:close-on-click-modal="false"
>
<ClinicalPaymentSubmitReadonly
:detail="confirmRow"
mode="refund"
title="退费申请信息(请核对)"
@download="handleDownloadFile"
/>
<div class="form-section-divider" />
<h4 class="detail-section-title">财务确认</h4>
<el-form
ref="confirmFormRef"
:model="confirmForm"
label-position="top"
class="biz-dialog-form"
>
<div class="form-grid-2">
<el-form-item label="财务确认退费备注" class="form-col-span-2">
<el-input
v-model="confirmForm.financeRemark"
type="textarea"
:rows="3"
placeholder="选填"
/>
</el-form-item>
<el-form-item label="附件" class="form-col-span-2">
<div class="attachment-upload">
<div class="attachment-list">
<el-upload
:auto-upload="false"
:show-file-list="false"
:multiple="true"
accept="image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar"
@change="handleConfirmAttachmentChange"
>
<div class="upload-card">
<el-icon :size="22" color="#10b981"><Plus /></el-icon>
<span class="upload-card-text">上传附件</span>
</div>
</el-upload>
<div
v-for="(file, fIdx) in confirmForm.attachments"
:key="file.id || fIdx"
class="attachment-item"
:class="{ 'is-uploading': file._uploading }"
>
<div class="attachment-preview">
<template v-if="file.fileUrl && isImageUrl(file.fileUrl)">
<img :src="fullFileUrl(file.fileUrl)" :alt="file.fileName" />
</template>
<template v-else>
<div class="attachment-preview__icon attachment-preview__icon--doc">
<el-icon :size="28"><Document /></el-icon>
</div>
</template>
</div>
<div class="attachment-footer">
<span class="attachment-name" :title="file.fileName">{{
file.fileName
}}</span>
<el-icon
class="action-btn"
title="删除"
@click="removeConfirmAttachment(fIdx)"
>
<Delete />
</el-icon>
</div>
</div>
</div>
<p class="form-tip">支持图片、文档等,多个附件将一并提交。</p>
</div>
</el-form-item>
</div>
</el-form>
<template #footer>
<el-button class="btn-ghost" @click="dialogVisible = false">
<el-icon><Close /></el-icon>
取消
</el-button>
<el-button
class="btn-main"
type="primary"
:loading="submitLoading"
@click="submitConfirm"
>
<el-icon><Check /></el-icon>
确认
</el-button>
</template>
</el-dialog>
<!-- 查看确认信息弹窗 -->
<el-dialog
v-model="viewDialogVisible"
title="确认退费信息"
width="900px"
class="dialog-form-layout"
align-center
destroy-on-close
>
<ClinicalPaymentSubmitReadonly
:detail="viewRow"
mode="refund"
title="退费申请信息"
@download="handleDownloadFile"
/>
<div class="form-section-divider" />
<h4 class="detail-section-title">财务确认信息</h4>
<el-form label-position="top" class="biz-dialog-form view-confirm-form">
<div class="form-grid-2">
<el-form-item label="确认时间" class="form-col-span-2">
<span class="view-field-text">{{
viewRow?.refundFinanceConfirmTime || viewRow?.updateTime || '—'
}}</span>
</el-form-item>
<el-form-item label="财务备注" class="form-col-span-2">
<span class="view-field-text view-field-text--multiline">{{
viewRow?.refundFinanceRemark || '—'
}}</span>
</el-form-item>
<el-form-item label="财务确认附件" class="form-col-span-2">
<ProtocolAttachmentReadonly
:files="viewAttachmentFiles"
@download="handleDownloadFile"
/>
</el-form-item>
</div>
</el-form>
<template #footer>
<el-button class="btn-ghost" @click="viewDialogVisible = false">
<el-icon><Close /></el-icon>
关闭
</el-button>
</template>
</el-dialog>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage } from 'element-plus'
import {
Close,
Check,
RefreshLeft,
Search,
View,
Plus,
Document,
Delete
} from '@element-plus/icons-vue'
import {
confirmClinicalRefund,
fetchClinicalRefundPending,
fetchClinicalRefundConfirmed
} from '@/api/business'
import { fetchUploadAttachment } from '@/api/business'
import ClinicalPaymentSubmitReadonly from '@/components/business/clinical-payment-submit-readonly/index.vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
defineOptions({ name: 'ClinicalRefundConfirmTab' })
const activeTab = ref('pending')
const searchForm = reactive({ keyword: '' })
const tableData = ref<Record<string, unknown>[]>([])
const loading = ref(false)
const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
const dialogVisible = ref(false)
const viewDialogVisible = ref(false)
const submitLoading = ref(false)
const currentDetailId = ref<string | null>(null)
const confirmRow = ref<Record<string, unknown> | null>(null)
const viewRow = ref<Record<string, unknown> | null>(null)
const confirmFormRef = ref()
const confirmForm = reactive({
financeRemark: '',
attachments: [] as Array<{
id: string
fileName: string
fileUrl: string
_uploading?: boolean
}>
})
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
function formatAmount(v: unknown): string {
if (v == null || v === '') return '-'
return '¥' + formatMoneyDisplay(v)
}
function fullFileUrl(url: string) {
if (!url) return ''
if (/^https?:\/\//i.test(url)) return url
return minioBaseUrl ? `${minioBaseUrl}/${url.replace(/^\//, '')}` : url
}
function isImageUrl(url: string) {
return /\.(png|jpe?g|gif|webp|bmp|svg)(\?.*)?$/i.test(url)
}
const viewAttachmentFiles = computed(() => {
const row = viewRow.value
if (!row) return []
const urls = String(row.refundFinanceConfirmAttachments || '')
if (!urls.trim()) return []
return urls
.split(',')
.map((u, i) => {
const url = u.trim()
if (!url) return null
const name = url.includes('/') ? url.split('/').pop() || `附件${i + 1}` : url
return { id: `url_${i}`, fileUrl: url, fileName: name }
})
.filter(Boolean) as Array<Record<string, unknown>>
})
function handleDownloadFile(file: Record<string, unknown>) {
const url = String(file.fileUrl || '')
if (!url) return
window.open(fullFileUrl(url), '_blank')
}
async function loadData() {
loading.value = true
try {
const params = {
page: pagination.page,
pageSize: pagination.pageSize,
keyword: searchForm.keyword || undefined
}
const res =
activeTab.value === 'pending'
? await fetchClinicalRefundPending(params)
: await fetchClinicalRefundConfirmed(params)
tableData.value = res.list || []
pagination.total = res.total ?? 0
} finally {
loading.value = false
}
}
function handleStatusTabChange() {
pagination.page = 1
loadData()
}
function handleSearch() {
pagination.page = 1
loadData()
}
function handleReset() {
searchForm.keyword = ''
pagination.page = 1
loadData()
}
function openConfirm(row: Record<string, unknown>) {
currentDetailId.value = String(row.id)
confirmRow.value = row
confirmForm.financeRemark = ''
confirmForm.attachments = []
dialogVisible.value = true
}
function openViewConfirm(row: Record<string, unknown>) {
viewRow.value = row
viewDialogVisible.value = true
}
function handleRowDblClick(row: Record<string, unknown>) {
if (activeTab.value !== 'pending') openViewConfirm(row)
}
async function handleConfirmAttachmentChange(uploadFile: { raw?: File }) {
const file = uploadFile.raw
if (!file) return
const tempId = `temp_${Date.now()}`
confirmForm.attachments.push({
id: tempId,
fileName: file.name,
fileUrl: '',
_uploading: true
})
const idx = confirmForm.attachments.length - 1
try {
const fd = new FormData()
fd.append('folder', 'clinical-finance-refund')
fd.append('file', file)
const res = await fetchUploadAttachment(fd)
confirmForm.attachments[idx] = {
id: res.id || tempId,
fileName: file.name || res.fileName,
fileUrl: res.fileUrl,
_uploading: false
}
} catch {
ElMessage.error('文件上传失败')
confirmForm.attachments.splice(idx, 1)
}
}
function removeConfirmAttachment(index: number) {
confirmForm.attachments.splice(index, 1)
}
function confirmAttachmentsToUrls() {
return confirmForm.attachments
.filter((f) => f.fileUrl && !f._uploading)
.map((f) => f.fileUrl)
.join(',')
}
async function submitConfirm() {
if (!currentDetailId.value) return
if (confirmForm.attachments.some((f) => f._uploading)) {
ElMessage.warning('附件上传中,请稍候')
return
}
submitLoading.value = true
try {
await confirmClinicalRefund(currentDetailId.value, {
refundFinanceConfirmAttachments: confirmAttachmentsToUrls() || undefined,
refundFinanceRemark: confirmForm.financeRemark.trim() || undefined
})
dialogVisible.value = false
loadData()
} finally {
submitLoading.value = false
}
}
watchDebounced(
[searchForm],
() => {
pagination.page = 1
loadData()
},
{ debounce: 300, deep: true }
)
onMounted(() => {
loadData()
})
</script>
<style scoped lang="scss">
.work-order-type-tabs {
padding: 0 16px;
margin-bottom: 4px;
}
.filter-form :deep(.el-form-item) {
margin-bottom: 0;
min-width: 0;
}
.filter-form :deep(.el-form-item__label) {
font-size: 13px;
font-weight: 500;
color: var(--mint-text-muted, #64748b);
padding: 0 0 4px;
line-height: 1.2;
}
.refund-confirm-table-wrap {
overflow-x: auto;
}
.form-section-divider {
height: 1px;
margin: 20px 0;
background: var(--mint-border, #e2e8f0);
}
.detail-section-title {
margin: 0 0 16px;
font-size: 14px;
font-weight: 600;
color: var(--mint-text, #334155);
line-height: 1.4;
}
.attachment-upload {
width: 100%;
}
.attachment-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.upload-card {
width: 120px;
height: 96px;
border: 1px dashed #a7f3d0;
border-radius: 8px;
background: #f0fdf4;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
cursor: pointer;
&:hover {
border-color: #10b981;
background: #ecfdf5;
}
}
.upload-card-text {
font-size: 12px;
color: #10b981;
font-weight: 500;
}
.attachment-item {
width: 120px;
border: 1px solid var(--mint-border, #e2e8f0);
border-radius: 8px;
overflow: hidden;
background: #fff;
&.is-uploading {
opacity: 0.6;
pointer-events: none;
}
}
.attachment-preview {
height: 96px;
display: flex;
align-items: center;
justify-content: center;
background: #f8fafc;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.attachment-preview__icon--doc {
color: #64748b;
}
.attachment-footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 4px;
padding: 6px 8px;
font-size: 12px;
}
.attachment-name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.action-btn {
cursor: pointer;
color: #94a3b8;
&:hover {
color: #ef4444;
}
}
.view-confirm-form :deep(.el-form-item) {
margin-bottom: 0;
}
.view-field-text {
display: block;
font-size: 14px;
color: var(--mint-text, #334155);
line-height: 1.5;
word-break: break-word;
&--multiline {
white-space: pre-wrap;
}
}
</style>
@@ -1,28 +1,49 @@
<!-- 缴费确认(财务)- 临床应用 -->
<!-- 缴退费财务确认 - 临床应用:缴费确认 + 退费确认 -->
<!-- eslint-disable vue/no-v-model-argument -->
<template>
<div class="page-container">
<div class="region-tabs region-tab-strip">
<div class="tab-button-group region-tab-group">
<el-button
v-for="tab in tabs"
:key="tab.key"
class="region-tab-btn"
:type="activeTab === tab.key ? 'primary' : 'default'"
@click="switchTab(tab.key)"
>
<span class="region-tab-inner">
<span class="region-tab-name">{{ tab.label }}</span>
</span>
</el-button>
</div>
</div>
<section class="panel">
<div class="panel-top">
<h2>缴费确认列表</h2>
<div class="panel-entity-switch" role="tablist" aria-label="视图类型">
<button
type="button"
class="entity-switch-card"
:class="{ 'is-active': mainTab === 'payment' }"
role="tab"
:aria-selected="mainTab === 'payment'"
@click="mainTab = 'payment'"
>
<span class="entity-switch-card__icon"><el-icon><Wallet /></el-icon></span>
<span class="entity-switch-card__main">
<span class="entity-switch-card__title">缴费确认</span>
<span class="entity-switch-card__desc">缴费记录确认与附件审核</span>
</span>
</button>
<button
type="button"
class="entity-switch-card"
:class="{ 'is-active': mainTab === 'refund' }"
role="tab"
:aria-selected="mainTab === 'refund'"
@click="mainTab = 'refund'"
>
<span class="entity-switch-card__icon"><el-icon><Refresh /></el-icon></span>
<span class="entity-switch-card__main">
<span class="entity-switch-card__title">退费确认</span>
<span class="entity-switch-card__desc">退费记录确认与附件审核</span>
</span>
</button>
</div>
<div v-show="mainTab === 'payment'" class="panel-entity-body">
<el-tabs
v-model="activeTab"
class="work-order-type-tabs"
@tab-change="handleStatusTabChange"
>
<el-tab-pane label="待确认" name="pending" />
<el-tab-pane label="已确认" name="confirmed" />
</el-tabs>
<div class="filter-block">
<el-form :model="searchForm" class="filter-form" label-position="top" @submit.prevent>
<div class="filter-grid">
@@ -49,7 +70,7 @@
</el-form>
</div>
<div class="list-body list-wrap">
<div class="list-body list-wrap payment-confirm-table-wrap">
<el-table
class="list-table"
:data="tableData"
@@ -122,19 +143,27 @@
</el-table-column>
<el-table-column
prop="payStatus"
label="缴费状态"
min-width="120"
label="状态"
min-width="110"
align="center"
header-align="center"
>
<template #default>
<el-tag :type="activeTab === 'jfqrz' ? 'warning' : 'success'" size="small">
{{ activeTab === 'jfqrz' ? '缴费确认中' : '已缴费' }}
<el-tag :type="activeTab === 'pending' ? 'warning' : 'success'" size="small">
{{ activeTab === 'pending' ? '缴费确认中' : '已缴费' }}
</el-tag>
</template>
</el-table-column>
<el-table-column
v-if="activeTab === 'yjf'"
v-if="activeTab === 'confirmed'"
prop="updateTime"
label="确认时间"
min-width="170"
align="center"
header-align="center"
/>
<el-table-column
v-if="activeTab === 'confirmed'"
prop="financeRemark"
label="财务备注"
min-width="120"
@@ -145,9 +174,9 @@
<template #default="{ row }">{{ row.financeRemark || '-' }}</template>
</el-table-column>
<el-table-column
v-if="activeTab === 'yjf'"
prop="updateTime"
label="确认时间"
v-if="activeTab === 'pending'"
prop="createTime"
label="创建时间"
min-width="170"
align="center"
header-align="center"
@@ -161,7 +190,7 @@
>
<template #default="{ row }">
<el-button
v-if="activeTab === 'jfqrz'"
v-if="activeTab === 'pending'"
class="btn-op-item primary"
@click="openConfirm(row)"
>
@@ -190,12 +219,20 @@
<el-dialog
v-model="dialogVisible"
title="确认收款"
width="640px"
class="dialog-form-layout"
width="900px"
class="dialog-form-layout payment-confirm-dialog"
align-center
destroy-on-close
:close-on-click-modal="false"
>
<ClinicalPaymentSubmitReadonly
:detail="confirmRow"
mode="receipt"
title="缴费明细(请核对)"
@download="handleDownloadFile"
/>
<div class="form-section-divider" />
<h4 class="detail-section-title">财务确认</h4>
<el-form
ref="confirmFormRef"
:model="confirmForm"
@@ -283,24 +320,25 @@
<el-dialog
v-model="viewDialogVisible"
title="确认收款信息"
width="640px"
class="dialog-form-layout"
width="900px"
class="dialog-form-layout payment-confirm-dialog"
align-center
destroy-on-close
>
<ClinicalPaymentSubmitReadonly
:detail="viewRow"
mode="receipt"
title="缴费明细"
@download="handleDownloadFile"
/>
<div class="form-section-divider" />
<h4 class="detail-section-title">财务确认信息</h4>
<el-form label-position="top" class="biz-dialog-form view-confirm-form">
<div class="form-grid-2">
<el-form-item label="申请单号" class="form-col-span-2">
<span class="view-field-text">{{ viewRow?.applicationNo || '-' }}</span>
</el-form-item>
<el-form-item label="患者姓名">
<span class="view-field-text">{{ viewRow?.patientName || '-' }}</span>
</el-form-item>
<el-form-item label="缴费金额(元)">
<span class="view-field-text">{{ formatAmount(viewRow?.paymentAmount) }}</span>
</el-form-item>
<el-form-item label="确认时间" class="form-col-span-2">
<span class="view-field-text">{{ viewRow?.updateTime || '-' }}</span>
<span class="view-field-text">{{
viewRow?.financeConfirmTime || viewRow?.updateTime || '—'
}}</span>
</el-form-item>
<el-form-item label="财务备注" class="form-col-span-2">
<span class="view-field-text view-field-text--multiline">{{
@@ -308,40 +346,10 @@
}}</span>
</el-form-item>
<el-form-item label="财务确认附件" class="form-col-span-2">
<div v-if="viewAttachmentFiles.length" class="attachment-list">
<div
v-for="(file, fIdx) in viewAttachmentFiles"
:key="fIdx"
class="attachment-item"
>
<div class="attachment-preview">
<template v-if="isImageUrl(String(file.fileUrl || ''))">
<img
:src="fullFileUrl(String(file.fileUrl || ''))"
:alt="String(file.fileName || '')"
/>
</template>
<template v-else>
<div class="attachment-preview__icon attachment-preview__icon--doc">
<el-icon :size="28"><Document /></el-icon>
</div>
</template>
</div>
<div class="attachment-footer">
<span class="attachment-name" :title="String(file.fileName || '')">{{
file.fileName
}}</span>
<el-icon
class="action-btn"
title="下载"
@click="handleDownloadFile(file)"
>
<Download />
</el-icon>
</div>
</div>
</div>
<span v-else class="view-field-text">—</span>
<ProtocolAttachmentReadonly
:files="viewAttachmentFiles"
@download="handleDownloadFile"
/>
</el-form-item>
</div>
</el-form>
@@ -352,6 +360,9 @@
</el-button>
</template>
</el-dialog>
</div>
<RefundConfirmTab v-if="mainTab === 'refund'" />
</section>
</div>
</template>
@@ -368,10 +379,13 @@
Plus,
Document,
Delete,
Download
Wallet,
Refresh
} from '@element-plus/icons-vue'
import RefundConfirmTab from './RefundConfirmTab.vue'
import ClinicalPaymentSubmitReadonly from '@/components/business/clinical-payment-submit-readonly/index.vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import {
fetchClinicalPayments,
confirmClinicalReceipt,
fetchClinicalReceiptPending,
fetchClinicalReceiptConfirmed
@@ -381,12 +395,10 @@
defineOptions({ name: 'ClinicalPaymentConfirm' })
const tabs = [
{ key: 'jfqrz', label: '待确认' },
{ key: 'yjf', label: '已确认' }
]
const route = useRoute()
const mainTab = ref<'payment' | 'refund'>('payment')
const activeTab = ref('jfqrz')
const activeTab = ref('pending')
const searchForm = reactive({ keyword: '' })
const tableData = ref<Record<string, unknown>[]>([])
const loading = ref(false)
@@ -396,6 +408,7 @@
const viewDialogVisible = ref(false)
const submitLoading = ref(false)
const currentDetailId = ref<string | null>(null)
const confirmRow = ref<Record<string, unknown> | null>(null)
const viewRow = ref<Record<string, unknown> | null>(null)
const confirmFormRef = ref()
@@ -458,7 +471,7 @@
keyword: searchForm.keyword || undefined
}
const res =
activeTab.value === 'jfqrz'
activeTab.value === 'pending'
? await fetchClinicalReceiptPending(params)
: await fetchClinicalReceiptConfirmed(params)
tableData.value = res.list || []
@@ -468,9 +481,7 @@
}
}
function switchTab(key: string) {
if (activeTab.value === key) return
activeTab.value = key
function handleStatusTabChange() {
pagination.page = 1
loadData()
}
@@ -488,6 +499,7 @@
function openConfirm(row: Record<string, unknown>) {
currentDetailId.value = String(row.id)
confirmRow.value = row
confirmForm.financeRemark = ''
confirmForm.attachments = []
dialogVisible.value = true
@@ -499,7 +511,7 @@
}
function handleRowDblClick(row: Record<string, unknown>) {
if (activeTab.value !== 'jfqrz') openViewConfirm(row)
if (activeTab.value !== 'pending') openViewConfirm(row)
}
async function handleConfirmAttachmentChange(uploadFile: { raw?: File }) {
@@ -570,37 +582,108 @@
)
onMounted(() => {
loadData()
const tab = String(route.query.tab || '')
if (tab === 'refund') {
mainTab.value = 'refund'
} else {
loadData()
}
})
watch(mainTab, (tab) => {
if (tab === 'payment') {
loadData()
}
})
</script>
<style scoped lang="scss">
.region-tabs {
margin-bottom: 16px;
.panel-entity-switch {
display: flex;
justify-content: center;
gap: 12px;
padding: 16px 16px 12px;
}
.region-tab-btn {
position: relative;
min-width: 108px;
padding: 0 12px;
.entity-switch-card {
display: flex;
align-items: center;
gap: 12px;
min-width: 220px;
max-width: 280px;
flex: 1;
padding: 14px 18px;
border: 1px solid var(--mint-border, #d9e8e2);
border-radius: 10px;
background: var(--surface, #fff);
cursor: pointer;
text-align: left;
transition:
border-color 0.2s ease,
background-color 0.2s ease,
box-shadow 0.2s ease;
:deep(.el-icon) {
display: none;
&:hover:not(.is-active) {
border-color: #a7f3d0;
background: #f8fafc;
}
&.is-active {
border-color: var(--primary, #10b981);
background: var(--primary-bg, #ecfdf5);
box-shadow: 0 0 0 1px rgb(16 185 129 / 12%);
}
}
.region-tab-btn.el-button > :deep(span) {
position: static !important;
display: inline-flex;
width: 100%;
justify-content: center;
}
.region-tab-inner {
display: inline-flex;
.entity-switch-card__icon {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
width: 40px;
height: 40px;
flex-shrink: 0;
border-radius: 8px;
background: #f1f5f9;
color: #64748b;
font-size: 20px;
.entity-switch-card.is-active & {
background: #fff;
color: var(--primary-dark, #059669);
}
}
.entity-switch-card__main {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.entity-switch-card__title {
font-size: 14px;
font-weight: 600;
color: var(--text, #1e293b);
line-height: 1.4;
.entity-switch-card.is-active & {
color: var(--primary-dark, #059669);
}
}
.entity-switch-card__desc {
font-size: 12px;
color: var(--mint-text-muted, #64748b);
line-height: 1.4;
}
.panel-entity-body {
min-width: 0;
}
.work-order-type-tabs {
padding: 0 16px;
margin-bottom: 4px;
}
.filter-form :deep(.el-form-item) {
@@ -616,6 +699,16 @@
line-height: 1.2;
}
.payment-confirm-table-wrap {
overflow-x: auto;
}
.payment-confirm-dialog {
:deep(.el-dialog__body) {
padding-top: 16px;
}
}
.attachment-upload {
width: 100%;
}
@@ -723,4 +816,18 @@
white-space: pre-wrap;
}
}
.form-section-divider {
height: 1px;
margin: 20px 0;
background: var(--mint-border, #e2e8f0);
}
.detail-section-title {
margin: 0 0 16px;
font-size: 14px;
font-weight: 600;
color: var(--mint-text, #334155);
line-height: 1.4;
}
</style>
@@ -1,707 +1,18 @@
<!-- 缴费信息(临床应用) -->
<!-- eslint-disable vue/no-v-model-argument -->
<!-- 旧「缴费信息」菜单入口:重定向至临床申请单 · 缴费信息 Tab -->
<template>
<div class="page-container">
<div class="region-tabs region-tab-strip">
<div class="tab-button-group region-tab-group">
<el-button
v-for="tab in tabs"
:key="tab.key"
class="region-tab-btn"
:type="activeTab === tab.key ? 'primary' : 'default'"
@click="switchTab(tab.key)"
>
<span class="region-tab-inner">
<span class="region-tab-name">{{ tab.label }}</span>
</span>
</el-button>
</div>
</div>
<section class="panel">
<div class="panel-top">
<h2>缴费信息列表</h2>
</div>
<div class="filter-block">
<el-form :model="searchForm" class="filter-form" label-position="top" @submit.prevent>
<div class="filter-grid">
<el-form-item label="关键词">
<el-input
v-model="searchForm.keyword"
placeholder="申请单号"
clearable
@keyup.enter="handleSearch"
/>
</el-form-item>
<el-form-item label="缴费状态">
<el-select v-model="searchForm.payStatus" placeholder="全部" clearable>
<el-option label="全部" value="" />
<el-option label="待缴费" value="dfj" />
<el-option label="缴费确认中" value="jfqrz" />
<el-option label="已缴费" value="yjf" />
<el-option label="退费确认中" value="tfqrz" />
<el-option label="已退费" value="ytf" />
</el-select>
</el-form-item>
</div>
<div class="filter-actions-row">
<span class="filter-hint">支持按申请单号模糊检索。</span>
<div class="filter-actions-end">
<el-button class="btn-ghost" @click="handleReset">
<el-icon><RefreshLeft /></el-icon>重置
</el-button>
<el-button class="btn-main" type="primary" @click="handleSearch">
<el-icon><Search /></el-icon>搜索
</el-button>
</div>
</div>
</el-form>
</div>
<div class="list-toolbar">
<div class="list-toolbar-row">
<div class="list-toolbar-selected">
已选 <span class="sel-num">{{ selectedRows.length }}</span> 项
</div>
<el-button
v-if="activeTab === 'dfj'"
class="btn-main"
type="primary"
:disabled="!selectedRows.length"
@click="handleBatchSubmitReceipt"
>
<el-icon><Check /></el-icon>批量缴费确认
</el-button>
<el-button
v-if="activeTab === 'yjf'"
class="btn-main"
type="primary"
:disabled="!selectedRows.length"
@click="handleBatchRefund"
>
<el-icon><RefreshLeft /></el-icon>批量退费确认
</el-button>
</div>
</div>
<div class="list-body list-wrap">
<el-table
class="list-table"
:data="tableData"
v-loading="loading"
stripe
row-key="id"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" min-width="55" align="center" header-align="center" />
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
:index="(index) => (pagination.page - 1) * pagination.pageSize + index + 1"
/>
<el-table-column
prop="applicationNo"
label="申请单号"
min-width="140"
align="center"
header-align="center"
/>
<el-table-column
prop="patientName"
label="患者姓名"
min-width="100"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.patientName || '-' }}</template>
</el-table-column>
<el-table-column
prop="channelName"
label="渠道名称"
min-width="120"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.channelName || '-' }}</template>
</el-table-column>
<el-table-column
prop="cellTypeSpec"
label="细胞类型/规格"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.cellTypeSpec || '-' }}</template>
</el-table-column>
<el-table-column
prop="infusionTime"
label="输注时间"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.infusionTime || '-' }}</template>
</el-table-column>
<el-table-column
prop="paymentAmount"
label="缴费金额(元)"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">
<span class="amount-text">{{ formatAmount(row.paymentAmount) }}</span>
</template>
</el-table-column>
<el-table-column
prop="payStatus"
label="缴费状态"
min-width="120"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-tag :type="payStatusTagType(String(row.payStatus || ''))" size="small">
{{ payStatusLabel(String(row.payStatus || '')) }}
</el-tag>
</template>
</el-table-column>
<el-table-column
label="操作"
min-width="260"
fixed="right"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-button
v-if="activeTab === 'dfj'"
class="btn-op-item primary"
@click="handleSubmitReceipt(row)"
>
<el-icon><Check /></el-icon>缴费确认
</el-button>
<el-button
v-if="activeTab === 'yjf'"
class="btn-op-item primary"
@click="openRefundDialog(row)"
>
<el-icon><RefreshLeft /></el-icon>退费确认
</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination list-pager-bar">
<el-pagination
:current-page="pagination.page"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[10, 20, 50]"
layout="total, sizes, prev, pager, next"
@size-change="(val) => ((pagination.page = 1), (pagination.pageSize = val), loadData())"
@current-change="(val) => ((pagination.page = val), loadData())"
/>
</div>
</div>
<el-dialog
v-model="refundDialogVisible"
title="退费确认"
width="640px"
class="dialog-form-layout"
align-center
destroy-on-close
:close-on-click-modal="false"
>
<el-form
ref="refundFormRef"
:model="refundForm"
:rules="refundFormRules"
label-position="top"
class="biz-dialog-form"
>
<div class="form-grid-2">
<el-form-item label="退费金额(元)" prop="refundAmount" class="form-col-span-2">
<el-input-number
v-model="refundForm.refundAmount"
:min="0.01"
:step="100"
:precision="2"
controls-position="right"
placeholder="请输入退费金额"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="退费备注" prop="refundRemark" class="form-col-span-2">
<el-input
v-model="refundForm.refundRemark"
type="textarea"
:rows="3"
placeholder="选填"
/>
</el-form-item>
<el-form-item label="退费附件" class="form-col-span-2">
<div class="attachment-upload">
<div class="attachment-list">
<el-upload
:auto-upload="false"
:show-file-list="false"
:multiple="true"
accept="image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar"
@change="handleRefundAttachmentChange"
>
<div class="upload-card">
<el-icon :size="22" color="#10b981"><Plus /></el-icon>
<span class="upload-card-text">上传附件</span>
</div>
</el-upload>
<div
v-for="(file, fIdx) in refundForm.attachments"
:key="file.id || fIdx"
class="attachment-item"
:class="{ 'is-uploading': file._uploading }"
>
<div class="attachment-preview">
<template v-if="file.fileUrl && isImageUrl(file.fileUrl)">
<img :src="fullFileUrl(file.fileUrl)" :alt="file.fileName" />
</template>
<template v-else>
<div class="attachment-preview__icon attachment-preview__icon--doc">
<el-icon :size="28"><Document /></el-icon>
</div>
</template>
</div>
<div class="attachment-footer">
<span class="attachment-name" :title="file.fileName">{{
file.fileName
}}</span>
<el-icon
class="action-btn"
title="删除"
@click="removeRefundAttachment(fIdx)"
>
<Delete />
</el-icon>
</div>
</div>
</div>
<p class="form-tip">支持图片、文档等,多个附件将一并提交。</p>
</div>
</el-form-item>
</div>
</el-form>
<template #footer>
<el-button class="btn-ghost" @click="refundDialogVisible = false">
<el-icon><Close /></el-icon>
取消
</el-button>
<el-button
class="btn-main"
type="primary"
:loading="refundSubmitLoading"
@click="submitRefund"
>
<el-icon><Check /></el-icon>
确认提交
</el-button>
</template>
</el-dialog>
</section>
</div>
<div />
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
import {
RefreshLeft,
Search,
Plus,
Document,
Delete,
Close,
Check
} from '@element-plus/icons-vue'
import {
fetchClinicalPayments,
submitClinicalReceipt,
batchSubmitClinicalReceipt,
submitClinicalRefund,
batchSubmitClinicalRefund
} from '@/api/business'
import { fetchUploadAttachment } from '@/api/business'
import { formatMoneyDisplay } from '@/utils/money-format'
import { payStatusLabel, payStatusTagType } from '@/utils/status-tag-registry'
defineOptions({ name: 'ClinicalPaymentInfo' })
const tabs = [
{ key: 'dfj', label: '待缴费' },
{ key: 'yjf', label: '已缴费' }
]
const activeTab = ref('dfj')
const searchForm = reactive({ keyword: '', payStatus: '' })
const tableData = ref<Record<string, unknown>[]>([])
const selectedRows = ref<Record<string, unknown>[]>([])
const loading = ref(false)
const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
const refundDialogVisible = ref(false)
const refundSubmitLoading = ref(false)
const refundTargetIds = ref<string[]>([])
const refundFormRef = ref<FormInstance>()
const refundForm = reactive({
refundAmount: null as number | null,
refundRemark: '',
attachments: [] as Array<{
id: string
fileName: string
fileUrl: string
_uploading?: boolean
}>
})
const refundFormRules: FormRules = {
refundAmount: [{ required: true, message: '请填写退费金额', trigger: 'blur' }]
}
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
function formatAmount(v: unknown): string {
if (v == null || v === '') return '-'
return '¥' + formatMoneyDisplay(v)
}
function fullFileUrl(url: string) {
if (!url) return ''
if (/^https?:\/\//i.test(url)) return url
return minioBaseUrl ? `${minioBaseUrl}/${url.replace(/^\//, '')}` : url
}
function isImageUrl(url: string) {
return /\.(png|jpe?g|gif|webp|bmp|svg)(\?.*)?$/i.test(url)
}
function handleSelectionChange(rows: Record<string, unknown>[]) {
selectedRows.value = rows
}
async function loadData() {
loading.value = true
try {
const res = await fetchClinicalPayments({
page: pagination.page,
pageSize: pagination.pageSize,
payStatus: activeTab.value,
keyword: searchForm.keyword || undefined
})
tableData.value = res.list || []
pagination.total = res.total ?? 0
} finally {
loading.value = false
}
}
function switchTab(key: string) {
if (activeTab.value === key) return
activeTab.value = key
selectedRows.value = []
pagination.page = 1
loadData()
}
async function handleSubmitReceipt(row: Record<string, unknown>) {
const id = String(row.id || '')
if (!id) return
try {
await ElMessageBox.confirm(
'确认对该缴费明细进行缴费确认?提交后状态变为「缴费确认中」。',
'缴费确认',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
await submitClinicalReceipt(id)
loadData()
} catch {
/* cancel */
}
}
async function handleBatchSubmitReceipt() {
if (!selectedRows.value.length) return
const ids = selectedRows.value.map((r) => String(r.id || '')).filter(Boolean)
if (!ids.length) return
try {
await ElMessageBox.confirm(
`确认将选中的 ${ids.length} 条待缴费明细批量缴费确认?`,
'批量缴费确认',
{ confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }
)
await batchSubmitClinicalReceipt(ids)
selectedRows.value = []
loadData()
} catch {
/* cancel */
}
}
function resetRefundForm(defaultAmount?: number) {
refundForm.refundAmount = defaultAmount ?? null
refundForm.refundRemark = ''
refundForm.attachments = []
refundFormRef.value?.clearValidate()
}
function openRefundDialog(row?: Record<string, unknown>, batchIds?: string[]) {
const ids = batchIds?.length ? batchIds : row?.id ? [String(row.id)] : []
if (!ids.length) return
refundTargetIds.value = ids
const defaultAmount =
!batchIds?.length && row?.paymentAmount != null ? Number(row.paymentAmount) : undefined
resetRefundForm(
defaultAmount != null && !Number.isNaN(defaultAmount) ? defaultAmount : undefined
)
refundDialogVisible.value = true
}
function handleBatchRefund() {
if (!selectedRows.value.length) return
const ids = selectedRows.value.map((r) => String(r.id || '')).filter(Boolean)
if (!ids.length) return
openRefundDialog(undefined, ids)
}
function refundAttachmentsToUrls() {
return refundForm.attachments
.filter((f) => f.fileUrl && !f._uploading)
.map((f) => f.fileUrl)
.join(',')
}
async function handleRefundAttachmentChange(uploadFile: { raw?: File }) {
const file = uploadFile.raw
if (!file) return
const tempId = `temp_${Date.now()}`
refundForm.attachments.push({
id: tempId,
fileName: file.name,
fileUrl: '',
_uploading: true
})
const idx = refundForm.attachments.length - 1
try {
const fd = new FormData()
fd.append('folder', 'clinical-payment-refund')
fd.append('file', file)
const res = await fetchUploadAttachment(fd)
refundForm.attachments[idx] = {
id: res.id || tempId,
fileName: file.name || res.fileName,
fileUrl: res.fileUrl,
_uploading: false
}
} catch {
ElMessage.error('文件上传失败')
refundForm.attachments.splice(idx, 1)
}
}
function removeRefundAttachment(index: number) {
refundForm.attachments.splice(index, 1)
}
async function submitRefund() {
if (!refundTargetIds.value.length) return
const valid = await refundFormRef.value?.validate().catch(() => false)
if (!valid) return
if (refundForm.attachments.some((f) => f._uploading)) {
ElMessage.warning('附件上传中,请稍候')
return
}
const payload = {
refundAmount: Number(refundForm.refundAmount),
refundRemark: refundForm.refundRemark?.trim() || undefined,
refundAttachments: refundAttachmentsToUrls() || undefined
}
refundSubmitLoading.value = true
try {
if (refundTargetIds.value.length === 1) {
await submitClinicalRefund(refundTargetIds.value[0], payload)
} else {
await batchSubmitClinicalRefund(refundTargetIds.value, payload)
}
refundDialogVisible.value = false
selectedRows.value = []
loadData()
} finally {
refundSubmitLoading.value = false
}
}
function handleSearch() {
pagination.page = 1
loadData()
}
function handleReset() {
searchForm.keyword = ''
searchForm.payStatus = ''
pagination.page = 1
loadData()
}
watchDebounced(
[searchForm],
() => {
pagination.page = 1
loadData()
},
{ debounce: 300, deep: true }
)
const router = useRouter()
const route = useRoute()
onMounted(() => {
loadData()
router.replace({
name: 'ClinicalApplicationList',
query: { ...route.query, tab: 'payment' }
})
})
</script>
<style scoped lang="scss">
.region-tabs {
margin-bottom: 16px;
}
.region-tab-btn {
position: relative;
min-width: 108px;
padding: 0 12px;
:deep(.el-icon) {
display: none;
}
}
.region-tab-btn.el-button > :deep(span) {
position: static !important;
display: inline-flex;
width: 100%;
justify-content: center;
}
.region-tab-inner {
display: inline-flex;
align-items: center;
justify-content: center;
width: 100%;
}
.filter-form :deep(.el-form-item) {
margin-bottom: 0;
min-width: 0;
}
.filter-form :deep(.el-form-item__label) {
font-size: 13px;
font-weight: 500;
color: var(--mint-text-muted, #64748b);
padding: 0 0 4px;
line-height: 1.2;
}
.attachment-upload {
width: 100%;
}
.attachment-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.upload-card {
width: 120px;
height: 96px;
border: 1px dashed #a7f3d0;
border-radius: 8px;
background: #f0fdf4;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
cursor: pointer;
&:hover {
border-color: #10b981;
background: #ecfdf5;
}
}
.upload-card-text {
font-size: 12px;
color: #10b981;
font-weight: 500;
}
.attachment-item {
width: 120px;
border: 1px solid var(--mint-border, #e2e8f0);
border-radius: 8px;
overflow: hidden;
background: #fff;
&.is-uploading {
opacity: 0.6;
pointer-events: none;
}
}
.attachment-preview {
height: 96px;
display: flex;
align-items: center;
justify-content: center;
background: #f8fafc;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.attachment-preview__icon--doc {
color: #64748b;
}
.attachment-footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 4px;
padding: 6px 8px;
font-size: 12px;
}
.attachment-name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.action-btn {
cursor: pointer;
color: #94a3b8;
&:hover {
color: #ef4444;
}
}
</style>
@@ -1,804 +1,18 @@
<!-- 退费确认(财务)- 临床应用 -->
<!-- eslint-disable vue/no-v-model-argument -->
<!-- 退费确认已融入「缴退费财务确认」页内 Tab,本路由仅做重定向 -->
<template>
<div class="page-container">
<div class="region-tabs region-tab-strip">
<div class="tab-button-group region-tab-group">
<el-button
v-for="tab in tabs"
:key="tab.key"
class="region-tab-btn"
:type="activeTab === tab.key ? 'primary' : 'default'"
@click="switchTab(tab.key)"
>
<span class="region-tab-inner">
<span class="region-tab-name">{{ tab.label }}</span>
</span>
</el-button>
</div>
</div>
<section class="panel">
<div class="panel-top">
<h2>退费确认列表</h2>
</div>
<div class="filter-block">
<el-form :model="searchForm" class="filter-form" label-position="top" @submit.prevent>
<div class="filter-grid">
<el-form-item label="关键词">
<el-input
v-model="searchForm.keyword"
placeholder="申请单号/患者姓名"
clearable
@keyup.enter="handleSearch"
/>
</el-form-item>
</div>
<div class="filter-actions-row">
<span class="filter-hint">支持按申请单号、患者姓名模糊检索。</span>
<div class="filter-actions-end">
<el-button class="btn-ghost" @click="handleReset">
<el-icon><RefreshLeft /></el-icon>重置
</el-button>
<el-button class="btn-main" type="primary" @click="handleSearch">
<el-icon><Search /></el-icon>搜索
</el-button>
</div>
</div>
</el-form>
</div>
<div class="list-body list-wrap">
<el-table
class="list-table"
:data="tableData"
v-loading="loading"
stripe
row-key="id"
@row-dblclick="handleRowDblClick"
>
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
:index="(index) => (pagination.page - 1) * pagination.pageSize + index + 1"
/>
<el-table-column
prop="applicationNo"
label="申请单号"
min-width="140"
align="center"
header-align="center"
/>
<el-table-column
prop="patientName"
label="患者姓名"
min-width="100"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.patientName || '-' }}</template>
</el-table-column>
<el-table-column
prop="channelName"
label="渠道名称"
min-width="120"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.channelName || '-' }}</template>
</el-table-column>
<el-table-column
prop="cellTypeSpec"
label="细胞类型/规格"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.cellTypeSpec || '-' }}</template>
</el-table-column>
<el-table-column
prop="infusionTime"
label="输注时间"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.infusionTime || '-' }}</template>
</el-table-column>
<el-table-column
prop="paymentAmount"
label="缴费金额(元)"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">
<span class="amount-text">{{ formatAmount(row.paymentAmount) }}</span>
</template>
</el-table-column>
<el-table-column
prop="refundAmount"
label="退费金额(元)"
min-width="130"
align="center"
header-align="center"
>
<template #default="{ row }">
<span class="amount-text">{{ formatAmount(row.refundAmount) }}</span>
</template>
</el-table-column>
<el-table-column
prop="payStatus"
label="缴费状态"
min-width="120"
align="center"
header-align="center"
>
<template #default>
<el-tag :type="activeTab === 'tfqrz' ? 'warning' : 'danger'" size="small">
{{ activeTab === 'tfqrz' ? '退费确认中' : '已退费' }}
</el-tag>
</template>
</el-table-column>
<el-table-column
v-if="activeTab === 'tfqrz'"
prop="refundRemark"
label="退费备注"
min-width="120"
align="center"
header-align="center"
show-overflow-tooltip
>
<template #default="{ row }">{{ row.refundRemark || '-' }}</template>
</el-table-column>
<el-table-column
v-if="activeTab === 'ytf'"
prop="refundFinanceRemark"
label="财务备注"
min-width="120"
align="center"
header-align="center"
show-overflow-tooltip
>
<template #default="{ row }">{{ row.refundFinanceRemark || '-' }}</template>
</el-table-column>
<el-table-column
v-if="activeTab === 'ytf'"
prop="updateTime"
label="确认时间"
min-width="170"
align="center"
header-align="center"
/>
<el-table-column
label="操作"
min-width="140"
fixed="right"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-button
v-if="activeTab === 'tfqrz'"
class="btn-op-item primary"
@click="openConfirm(row)"
>
<el-icon><Check /></el-icon>确认退费
</el-button>
<el-button v-else class="btn-op-item" @click="openViewConfirm(row)">
<el-icon><View /></el-icon>查看确认信息
</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination list-pager-bar">
<el-pagination
:current-page="pagination.page"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[10, 20, 50]"
layout="total, sizes, prev, pager, next"
@size-change="(val) => ((pagination.page = 1), (pagination.pageSize = val), loadData())"
@current-change="(val) => ((pagination.page = val), loadData())"
/>
</div>
</div>
<!-- 确认退费弹窗 -->
<el-dialog
v-model="dialogVisible"
title="确认退费"
width="640px"
class="dialog-form-layout"
align-center
destroy-on-close
:close-on-click-modal="false"
>
<div class="refund-apply-section">
<h4 class="detail-section-title">退费申请信息</h4>
<el-form label-position="top" class="biz-dialog-form view-confirm-form">
<div class="form-grid-2">
<el-form-item label="申请单号">
<span class="view-field-text">{{ confirmRow?.applicationNo || '-' }}</span>
</el-form-item>
<el-form-item label="患者姓名">
<span class="view-field-text">{{ confirmRow?.patientName || '-' }}</span>
</el-form-item>
<el-form-item label="缴费金额(元)">
<span class="view-field-text">{{ formatAmount(confirmRow?.paymentAmount) }}</span>
</el-form-item>
<el-form-item label="退费金额(元)">
<span class="view-field-text">{{ formatAmount(confirmRow?.refundAmount) }}</span>
</el-form-item>
<el-form-item label="退费备注" class="form-col-span-2">
<span class="view-field-text view-field-text--multiline">{{
confirmRow?.refundRemark || '—'
}}</span>
</el-form-item>
</div>
</el-form>
</div>
<div class="form-section-divider" />
<h4 class="detail-section-title">财务确认</h4>
<el-form
ref="confirmFormRef"
:model="confirmForm"
label-position="top"
class="biz-dialog-form"
>
<div class="form-grid-2">
<el-form-item label="财务确认退费备注" class="form-col-span-2">
<el-input
v-model="confirmForm.financeRemark"
type="textarea"
:rows="3"
placeholder="选填"
/>
</el-form-item>
<el-form-item label="附件" class="form-col-span-2">
<div class="attachment-upload">
<div class="attachment-list">
<el-upload
:auto-upload="false"
:show-file-list="false"
:multiple="true"
accept="image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar"
@change="handleConfirmAttachmentChange"
>
<div class="upload-card">
<el-icon :size="22" color="#10b981"><Plus /></el-icon>
<span class="upload-card-text">上传附件</span>
</div>
</el-upload>
<div
v-for="(file, fIdx) in confirmForm.attachments"
:key="file.id || fIdx"
class="attachment-item"
:class="{ 'is-uploading': file._uploading }"
>
<div class="attachment-preview">
<template v-if="file.fileUrl && isImageUrl(file.fileUrl)">
<img :src="fullFileUrl(file.fileUrl)" :alt="file.fileName" />
</template>
<template v-else>
<div class="attachment-preview__icon attachment-preview__icon--doc">
<el-icon :size="28"><Document /></el-icon>
</div>
</template>
</div>
<div class="attachment-footer">
<span class="attachment-name" :title="file.fileName">{{
file.fileName
}}</span>
<el-icon
class="action-btn"
title="删除"
@click="removeConfirmAttachment(fIdx)"
>
<Delete />
</el-icon>
</div>
</div>
</div>
<p class="form-tip">支持图片、文档等,多个附件将一并提交。</p>
</div>
</el-form-item>
</div>
</el-form>
<template #footer>
<el-button class="btn-ghost" @click="dialogVisible = false">
<el-icon><Close /></el-icon>
取消
</el-button>
<el-button
class="btn-main"
type="primary"
:loading="submitLoading"
@click="submitConfirm"
>
<el-icon><Check /></el-icon>
确认
</el-button>
</template>
</el-dialog>
<!-- 查看确认信息弹窗 -->
<el-dialog
v-model="viewDialogVisible"
title="确认退费信息"
width="640px"
class="dialog-form-layout"
align-center
destroy-on-close
>
<div class="refund-apply-section">
<h4 class="detail-section-title">退费申请信息</h4>
<el-form label-position="top" class="biz-dialog-form view-confirm-form">
<div class="form-grid-2">
<el-form-item label="申请单号">
<span class="view-field-text">{{ viewRow?.applicationNo || '-' }}</span>
</el-form-item>
<el-form-item label="患者姓名">
<span class="view-field-text">{{ viewRow?.patientName || '-' }}</span>
</el-form-item>
<el-form-item label="缴费金额(元)">
<span class="view-field-text">{{ formatAmount(viewRow?.paymentAmount) }}</span>
</el-form-item>
<el-form-item label="退费金额(元)">
<span class="view-field-text">{{ formatAmount(viewRow?.refundAmount) }}</span>
</el-form-item>
<el-form-item label="退费备注" class="form-col-span-2">
<span class="view-field-text view-field-text--multiline">{{
viewRow?.refundRemark || '—'
}}</span>
</el-form-item>
</div>
</el-form>
</div>
<div class="form-section-divider" />
<h4 class="detail-section-title">财务确认信息</h4>
<el-form label-position="top" class="biz-dialog-form view-confirm-form">
<div class="form-grid-2">
<el-form-item label="确认时间" class="form-col-span-2">
<span class="view-field-text">{{ viewRow?.updateTime || '-' }}</span>
</el-form-item>
<el-form-item label="财务备注" class="form-col-span-2">
<span class="view-field-text view-field-text--multiline">{{
viewRow?.refundFinanceRemark || '—'
}}</span>
</el-form-item>
<el-form-item label="财务确认附件" class="form-col-span-2">
<div v-if="viewAttachmentFiles.length" class="attachment-list">
<div
v-for="(file, fIdx) in viewAttachmentFiles"
:key="fIdx"
class="attachment-item"
>
<div class="attachment-preview">
<template v-if="isImageUrl(String(file.fileUrl || ''))">
<img
:src="fullFileUrl(String(file.fileUrl || ''))"
:alt="String(file.fileName || '')"
/>
</template>
<template v-else>
<div class="attachment-preview__icon attachment-preview__icon--doc">
<el-icon :size="28"><Document /></el-icon>
</div>
</template>
</div>
<div class="attachment-footer">
<span class="attachment-name" :title="String(file.fileName || '')">{{
file.fileName
}}</span>
<el-icon
class="action-btn"
title="下载"
@click="handleDownloadFile(file)"
>
<Download />
</el-icon>
</div>
</div>
</div>
<span v-else class="view-field-text">—</span>
</el-form-item>
</div>
</el-form>
<template #footer>
<el-button class="btn-ghost" @click="viewDialogVisible = false">
<el-icon><Close /></el-icon>
关闭
</el-button>
</template>
</el-dialog>
</section>
</div>
<div />
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage } from 'element-plus'
import {
Close,
Check,
RefreshLeft,
Search,
View,
Plus,
Document,
Delete,
Download
} from '@element-plus/icons-vue'
import {
confirmClinicalRefund,
fetchClinicalRefundPending,
fetchClinicalRefundConfirmed
} from '@/api/business'
import { fetchUploadAttachment } from '@/api/business'
import { formatMoneyDisplay } from '@/utils/money-format'
defineOptions({ name: 'ClinicalRefundConfirmRedirect' })
defineOptions({ name: 'ClinicalRefundConfirm' })
const tabs = [
{ key: 'tfqrz', label: '待确认' },
{ key: 'ytf', label: '已确认' }
]
const activeTab = ref('tfqrz')
const searchForm = reactive({ keyword: '' })
const tableData = ref<Record<string, unknown>[]>([])
const loading = ref(false)
const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
const dialogVisible = ref(false)
const viewDialogVisible = ref(false)
const submitLoading = ref(false)
const currentDetailId = ref<string | null>(null)
const confirmRow = ref<Record<string, unknown> | null>(null)
const viewRow = ref<Record<string, unknown> | null>(null)
const confirmFormRef = ref()
const confirmForm = reactive({
financeRemark: '',
attachments: [] as Array<{
id: string
fileName: string
fileUrl: string
_uploading?: boolean
}>
})
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
function formatAmount(v: unknown): string {
if (v == null || v === '') return '-'
return '¥' + formatMoneyDisplay(v)
}
function fullFileUrl(url: string) {
if (!url) return ''
if (/^https?:\/\//i.test(url)) return url
return minioBaseUrl ? `${minioBaseUrl}/${url.replace(/^\//, '')}` : url
}
function isImageUrl(url: string) {
return /\.(png|jpe?g|gif|webp|bmp|svg)(\?.*)?$/i.test(url)
}
const viewAttachmentFiles = computed(() => {
const row = viewRow.value
if (!row) return []
const urls = String(row.refundFinanceConfirmAttachments || '')
if (!urls.trim()) return []
return urls
.split(',')
.map((u, i) => {
const url = u.trim()
if (!url) return null
const name = url.includes('/') ? url.split('/').pop() || `附件${i + 1}` : url
return { id: `url_${i}`, fileUrl: url, fileName: name }
})
.filter(Boolean) as Array<Record<string, unknown>>
})
function handleDownloadFile(file: Record<string, unknown>) {
const url = String(file.fileUrl || '')
if (!url) return
window.open(fullFileUrl(url), '_blank')
}
async function loadData() {
loading.value = true
try {
const params = {
page: pagination.page,
pageSize: pagination.pageSize,
keyword: searchForm.keyword || undefined
}
const res =
activeTab.value === 'tfqrz'
? await fetchClinicalRefundPending(params)
: await fetchClinicalRefundConfirmed(params)
tableData.value = res.list || []
pagination.total = res.total ?? 0
} finally {
loading.value = false
}
}
function switchTab(key: string) {
if (activeTab.value === key) return
activeTab.value = key
pagination.page = 1
loadData()
}
function handleSearch() {
pagination.page = 1
loadData()
}
function handleReset() {
searchForm.keyword = ''
pagination.page = 1
loadData()
}
function openConfirm(row: Record<string, unknown>) {
currentDetailId.value = String(row.id)
confirmRow.value = row
confirmForm.financeRemark = ''
confirmForm.attachments = []
dialogVisible.value = true
}
function openViewConfirm(row: Record<string, unknown>) {
viewRow.value = row
viewDialogVisible.value = true
}
function handleRowDblClick(row: Record<string, unknown>) {
if (activeTab.value !== 'tfqrz') openViewConfirm(row)
}
async function handleConfirmAttachmentChange(uploadFile: { raw?: File }) {
const file = uploadFile.raw
if (!file) return
const tempId = `temp_${Date.now()}`
confirmForm.attachments.push({
id: tempId,
fileName: file.name,
fileUrl: '',
_uploading: true
})
const idx = confirmForm.attachments.length - 1
try {
const fd = new FormData()
fd.append('folder', 'clinical-finance-refund')
fd.append('file', file)
const res = await fetchUploadAttachment(fd)
confirmForm.attachments[idx] = {
id: res.id || tempId,
fileName: file.name || res.fileName,
fileUrl: res.fileUrl,
_uploading: false
}
} catch {
ElMessage.error('文件上传失败')
confirmForm.attachments.splice(idx, 1)
}
}
function removeConfirmAttachment(index: number) {
confirmForm.attachments.splice(index, 1)
}
function confirmAttachmentsToUrls() {
return confirmForm.attachments
.filter((f) => f.fileUrl && !f._uploading)
.map((f) => f.fileUrl)
.join(',')
}
async function submitConfirm() {
if (!currentDetailId.value) return
if (confirmForm.attachments.some((f) => f._uploading)) {
ElMessage.warning('附件上传中,请稍候')
return
}
submitLoading.value = true
try {
await confirmClinicalRefund(currentDetailId.value, {
refundFinanceConfirmAttachments: confirmAttachmentsToUrls() || undefined,
refundFinanceRemark: confirmForm.financeRemark.trim() || undefined
})
dialogVisible.value = false
loadData()
} finally {
submitLoading.value = false
}
}
watchDebounced(
[searchForm],
() => {
pagination.page = 1
loadData()
},
{ debounce: 300, deep: true }
)
const router = useRouter()
const route = useRoute()
onMounted(() => {
loadData()
router.replace({
name: 'ClinicalPaymentConfirm',
query: { ...route.query, tab: 'refund' }
})
})
</script>
<style scoped lang="scss">
.region-tabs {
margin-bottom: 16px;
}
.region-tab-btn {
position: relative;
min-width: 108px;
padding: 0 12px;
:deep(.el-icon) {
display: none;
}
}
.region-tab-btn.el-button > :deep(span) {
position: static !important;
display: inline-flex;
width: 100%;
justify-content: center;
}
.region-tab-inner {
display: inline-flex;
align-items: center;
justify-content: center;
width: 100%;
}
.filter-form :deep(.el-form-item) {
margin-bottom: 0;
min-width: 0;
}
.filter-form :deep(.el-form-item__label) {
font-size: 13px;
font-weight: 500;
color: var(--mint-text-muted, #64748b);
padding: 0 0 4px;
line-height: 1.2;
}
.form-section-divider {
height: 1px;
margin: 20px 0;
background: var(--mint-border, #e2e8f0);
}
.detail-section-title {
margin: 0 0 16px;
font-size: 14px;
font-weight: 600;
color: var(--mint-text, #334155);
line-height: 1.4;
}
.attachment-upload {
width: 100%;
}
.attachment-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.upload-card {
width: 120px;
height: 96px;
border: 1px dashed #a7f3d0;
border-radius: 8px;
background: #f0fdf4;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
cursor: pointer;
&:hover {
border-color: #10b981;
background: #ecfdf5;
}
}
.upload-card-text {
font-size: 12px;
color: #10b981;
font-weight: 500;
}
.attachment-item {
width: 120px;
border: 1px solid var(--mint-border, #e2e8f0);
border-radius: 8px;
overflow: hidden;
background: #fff;
&.is-uploading {
opacity: 0.6;
pointer-events: none;
}
}
.attachment-preview {
height: 96px;
display: flex;
align-items: center;
justify-content: center;
background: #f8fafc;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.attachment-preview__icon--doc {
color: #64748b;
}
.attachment-footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 4px;
padding: 6px 8px;
font-size: 12px;
}
.attachment-name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.action-btn {
cursor: pointer;
color: #94a3b8;
&:hover {
color: #ef4444;
}
}
.view-confirm-form :deep(.el-form-item) {
margin-bottom: 0;
}
.view-field-text {
display: block;
font-size: 14px;
color: var(--mint-text, #334155);
line-height: 1.5;
word-break: break-word;
&--multiline {
white-space: pre-wrap;
}
}
</style>
@@ -141,6 +141,18 @@
</div>
</template>
<template #payment-info>
<div class="view-section-slot payment-info-view">
<ClinicalSchedulePaymentDetailView
v-if="detail?.payment"
:payment="detail.payment"
@preview="handleAttachmentPreview"
@download="handleAttachmentDownload"
/>
<el-empty v-else description="暂无缴费记录" :image-size="48" />
</div>
</template>
<template #review-attachments>
<div class="view-section-slot">
<ProtocolAttachmentReadonly
@@ -188,6 +200,7 @@
import SampleProductionInfoCards from '@/components/business/sample-production-info-cards/index.vue'
import SampleQcInfoCards from '@/components/business/sample-qc-info-cards/index.vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import ClinicalSchedulePaymentDetailView from '@/components/business/clinical-schedule-payment-detail/index.vue'
import { fetchInfusionScheduleMgmtDetail } from '@/api/admin'
import {
applicationStatusLabel,
@@ -251,6 +264,12 @@
const products = computed(() => detail.value?.products || [])
const isClinicalApplication = computed(
() =>
detail.value?.application?.bizType === 'clinical_application' ||
detail.value?.bizType === 'clinical_application'
)
const outboundMaterial = computed(() => detail.value?.outboundMaterial || null)
const outboundMaterialCells = computed(() => outboundMaterial.value?.cells || [])
const outboundMaterialQcRows = computed(() => outboundMaterial.value?.qcMaterials || [])
@@ -473,6 +492,15 @@
fields: [],
slot: 'products'
},
...(isClinicalApplication.value
? [
{
title: '缴费明细',
fields: [],
slot: 'payment-info'
}
]
: []),
{
title: '出库生产工单 + 任务',
slot: 'production-info',
@@ -626,6 +654,10 @@
</script>
<style lang="scss" scoped>
.payment-info-view {
width: 100%;
}
.view-inner-table-wrap.list-body.list-wrap {
margin-top: 4px;
border: 1px solid var(--mint-border, #e2e8f0);
@@ -1,6 +1,6 @@
<!-- 输注计划管理(临床独立页 / 中试重定向) -->
<template>
<div v-if="isPilotRedirect" />
<div v-if="isPilotRedirect || isClinicalRedirect" />
<div v-else class="page-container">
<section class="panel">
<div class="panel-top">
@@ -21,12 +21,21 @@
const router = useRouter()
const route = useRoute()
const isPilotRedirect = computed(() => route.name === 'PilotInfusionSchedule')
const isClinicalRedirect = computed(() => route.name === 'ClinicalInfusionSchedule')
onMounted(() => {
if (!isPilotRedirect.value) return
router.replace({
name: 'PilotApplication',
query: { ...route.query, tab: 'infusion' }
})
if (isPilotRedirect.value) {
router.replace({
name: 'PilotApplication',
query: { ...route.query, tab: 'infusion' }
})
return
}
if (isClinicalRedirect.value) {
router.replace({
name: 'ClinicalApplicationList',
query: { ...route.query, tab: 'infusion' }
})
}
})
</script>
@@ -253,6 +253,15 @@
defineOptions({ name: 'PilotServiceOutboundReleaseReview' })
const props = defineProps<{
/** 路由传入:仅列出对应业务线的申请单关联输注计划 */
bizType?: string
}>()
const isClinical = computed(() => props.bizType === 'clinical_application')
const effectiveBizType = computed(
() => props.bizType || (isClinical.value ? 'clinical_application' : 'pilot_service')
)
const reviewConclusionOptions = [
{ value: 'tg', label: '通过' },
{ value: 'btg', label: '不通过' }
@@ -280,7 +289,8 @@
page: pagination.page,
pageSize: pagination.pageSize,
reviewConclusion: searchForm.reviewConclusion || undefined,
keyword: searchForm.keyword || undefined
keyword: searchForm.keyword || undefined,
bizType: effectiveBizType.value
})
tableData.value = res.list || []
pagination.total = res.total ?? 0
@@ -37,7 +37,10 @@
<div class="section-title">
<div class="section-title-left"><h3>申请单信息</h3></div>
</div>
<div class="form-grid form-grid--col4">
<div
class="form-grid form-grid--col4"
:class="{ 'clinical-application-info-grid': isClinical }"
>
<el-form-item label="申请单名称" prop="applicationName">
<el-input v-model="formData.applicationName" placeholder="请输入申请单名称" />
</el-form-item>
@@ -59,6 +62,18 @@
/>
</el-select>
</el-form-item>
<el-form-item
v-if="isClinical"
label="备注"
class="clinical-application-remark"
>
<el-input
v-model="formData.remark"
type="textarea"
placeholder="请输入备注"
:rows="2"
/>
</el-form-item>
<el-form-item
v-if="!isClinical"
label="服务订单"
@@ -92,7 +107,7 @@
</el-button>
</div>
</el-form-item>
<el-form-item label="备注" class="form-col-full">
<el-form-item v-if="!isClinical" label="备注" class="form-col-full">
<el-input
v-model="formData.remark"
type="textarea"
@@ -173,7 +188,12 @@
<el-form-item label="紧急联系人电话" prop="emergencyPhone">
<el-input v-model="patientForm.emergencyPhone" placeholder="请输入紧急联系人电话" />
</el-form-item>
<el-form-item label="是否需要体检" prop="needCheckup" class="patient-checkup-field">
<el-form-item
v-if="!isClinical"
label="是否需要体检"
prop="needCheckup"
class="patient-checkup-field"
>
<el-switch
v-model="patientForm.needCheckup"
:active-value="1"
@@ -266,7 +286,7 @@
请先在「申请单信息」中选择渠道与服务订单,系统将按订单类型加载协议与可选细胞产品。
</p>
<p v-if="isClinical" class="section-title-hint">
请先在「申请单信息」中选择渠道,系统将加载可选细胞产品。
请先选择渠道并添加输注计划;细胞项目从「细胞价格体系」加载(与渠道协议无关)。
</p>
</div>
</div>
@@ -479,7 +499,11 @@
</el-table-column>
<el-table-column prop="cellTypeName" label="细胞类型" min-width="100" />
<el-table-column prop="specText" label="规格" min-width="100" />
<el-table-column label="协议单价(元)" min-width="130" align="right">
<el-table-column
:label="isClinical ? '参考单价(元)' : '协议单价(元)'"
min-width="130"
align="right"
>
<template #default="{ row }">
<span class="cell-product-price-text">
¥{{ formatOrderBalance(row.agreementPrice) }}
@@ -799,6 +823,7 @@
fetchPilotPatient,
fetchChannelAgreements,
fetchChannelAgreementPrices,
fetchCellProductPriceList,
fetchDictDataOptions,
fetchCustomerList,
fetchCreateCustomer
@@ -935,15 +960,20 @@
const onChannelChange = async (channelId: string) => {
formData.channelServiceOrderId = ''
serviceOrderOptions.value = []
resetInfusionOrderContext()
if (!channelId) return
if (isClinical.value) {
// 临床模式:直接加载渠道协议,无需服务订单
await loadAgreements(channelId)
// 临床:价格池与渠道无关;切换渠道时勿清空 agreementPriceOptions(否则「添加细胞产品」会失效)
clearScheduleCellProducts()
if (!channelId) return
if (!agreementPriceOptions.value.length) {
await loadClinicalCellProductPrices()
}
return
}
resetInfusionOrderContext()
if (!channelId) return
serviceOrderLoading.value = true
try {
serviceOrderOptions.value = await fetchAllPagedRecords((page, pageSize) =>
@@ -1089,7 +1119,6 @@
const canAddCellProduct = computed(() => {
if (isClinical.value) {
// 临床模式:需要渠道和协议价格
return !!formData.channelId && agreementPriceOptions.value.length > 0
}
return !!selectedServiceOrder.value && agreementPriceOptions.value.length > 0
@@ -1662,6 +1691,41 @@
}))
}
const normalizeCellProductPriceRows = (rows: any[]) => {
return (Array.isArray(rows) ? rows : []).map((p) => ({
priceId: p.id,
projectCode: p.projectCode || '',
projectName: p.projectName || '',
cellTypeCode: p.cellTypeCode || '',
cellTypeName: p.cellTypeName || '',
specText: p.specText || '',
unitPrice: p.unitPrice ?? 0,
source: 'cell_price' as const
}))
}
/** 临床申请单:从细胞价格体系(biz_cell_product_price)加载可选项目 */
const loadClinicalCellProductPrices = async () => {
agreementPriceLoading.value = true
try {
const rows = await fetchAllPagedRecords(async (page, pageSize) => {
const data: any = await fetchCellProductPriceList({ page, pageSize })
return {
list: data?.list ?? [],
total: data?.total ?? 0
}
})
agreementPriceOptions.value = normalizeCellProductPriceRows(rows)
if (!agreementPriceOptions.value.length) {
ElMessage.warning('细胞价格体系暂无数据,请先在「细胞产品基础信息」中维护价格')
}
} catch {
agreementPriceOptions.value = []
} finally {
agreementPriceLoading.value = false
}
}
// 疗程数变化 → 自动增减输注计划 + 自动计算输注时间
const computeScheduleTime = (index: number): string => {
if (!infusionPlan.infusionStartDate || !infusionPlan.courseInterval) return ''
@@ -1860,6 +1924,9 @@
loadChannels()
loadInfusionMethodOptions()
remoteSearchCustomers('')
if (isClinical.value) {
loadClinicalCellProductPrices()
}
if (isEdit.value && props.editId) {
loadEditData(props.editId)
}
@@ -2002,10 +2069,12 @@
}))
}))
}
if (formData.channelId) {
if (formData.channelId && !isClinical.value) {
await loadAgreements(formData.channelId)
}
if (!isClinical.value && formData.channelServiceOrderId) {
if (isClinical.value) {
await loadClinicalCellProductPrices()
} else if (formData.channelServiceOrderId) {
await onServiceOrderChange(formData.channelServiceOrderId, { preserveCellProducts: true })
} else if (infusionPlan.channelAgreementId) {
await onAgreementChange(infusionPlan.channelAgreementId)
@@ -2031,7 +2100,10 @@
try {
const payload: Record<string, any> = {
applicationName: formData.applicationName || undefined,
channelServiceOrderId: formData.channelServiceOrderId || undefined,
channelId: formData.channelId || undefined,
channelServiceOrderId: isClinical.value
? undefined
: formData.channelServiceOrderId || undefined,
remark: formData.remark || undefined,
bizType: props.bizType || undefined,
patient: {
@@ -2049,7 +2121,7 @@
.map((f) => f.fileUrl)
.filter(Boolean)
.join(',') || undefined,
needCheckup: patientForm.needCheckup
needCheckup: isClinical.value ? 0 : patientForm.needCheckup
},
infusionPlan: {
id: infusionPlan.id || undefined,
@@ -2154,6 +2226,10 @@
grid-column: span 2;
}
.clinical-application-remark {
grid-column: span 2;
}
:deep(.el-form-item) {
margin-bottom: 0;
}
@@ -558,15 +558,26 @@
</el-table>
</div>
<el-empty v-else description="暂无细胞产品" :image-size="32" />
<div
v-if="isYfkOrder && schedule.cellProducts?.length"
class="schedule-amount-summary"
>
本次输注计划金额:
<span class="schedule-amount-summary__value">
¥{{ formatOrderBalance(calcScheduleAmount(schedule)) }}
</span>
</div>
<div
v-if="isYfkOrder && schedule.cellProducts?.length"
class="schedule-amount-summary"
>
本次输注计划金额:
<span class="schedule-amount-summary__value">
¥{{ formatOrderBalance(calcScheduleAmount(schedule)) }}
</span>
</div>
</div>
<div v-if="isClinicalApplication" class="schedule-payment-block">
<div class="section-subtitle">缴费明细</div>
<ClinicalSchedulePaymentDetailView
v-if="schedule.payment"
:payment="schedule.payment"
@preview="openPreview"
@download="downloadFile"
/>
<el-empty v-else description="暂无缴费记录" :image-size="32" />
</div>
<InfusionScheduleOutboundChainView
@@ -773,6 +784,7 @@
} from '@/components/business/system-view-dialog/index.vue'
import ServiceOrderTxnTable from '@/views/pilot-service/channel-service-order/ServiceOrderTxnTable.vue'
import InfusionScheduleOutboundChainView from '@/components/business/infusion-schedule-outbound-chain-view/index.vue'
import ClinicalSchedulePaymentDetailView from '@/components/business/clinical-schedule-payment-detail/index.vue'
import {
fetchPilotApplicationDetail,
fetchPilotPatient,
@@ -874,6 +886,9 @@
const isYfkOrder = computed(() => serviceOrderDetail.value?.orderType === 'yfk')
const isGmcpOrder = computed(() => serviceOrderDetail.value?.orderType === 'gmcp')
const isClinicalApplication = computed(
() => applicationDetail.value?.bizType === 'clinical_application'
)
const settlementModeLabel = computed(() => {
const t = serviceOrderDetail.value?.orderType
@@ -1582,6 +1597,12 @@
gap: 8px;
}
.schedule-payment-block {
margin-top: 16px;
padding-top: 16px;
border-top: 1px dashed #e2e8f0;
}
.checkup-block-gap {
height: 16px;
}
@@ -296,6 +296,9 @@
defineOptions({ name: 'CheckupManagementTab' })
const props = defineProps<{ bizType?: string }>()
const isClinical = computed(() => props.bizType === 'clinical_application')
// ── 搜索 ─────────────────────────────
const searchForm = reactive({
keyword: '',
@@ -339,7 +342,9 @@
pageSize: pagination.pageSize,
keyword: searchForm.keyword || undefined,
checkupStatus: searchForm.checkupStatus || undefined,
checkupInstitutionId: searchForm.checkupInstitutionId || undefined
checkupInstitutionId: searchForm.checkupInstitutionId || undefined,
bizType:
props.bizType || (isClinical.value ? 'clinical_application' : 'pilot_service')
})
tableData.value = res?.list ?? []
pagination.total = res?.pagination?.total ?? 0
File diff suppressed because it is too large. Load diff
@@ -453,7 +453,8 @@
keyword: searchForm.keyword || undefined,
infusionStatus: searchForm.infusionStatus || undefined,
qcStatus: searchForm.qcStatus || undefined,
bizType: props.bizType || undefined
bizType:
props.bizType || (isClinical.value ? 'clinical_application' : 'pilot_service')
}
if (searchForm.infusionTimeRange?.length === 2) {
params.infusionTimeStart = searchForm.infusionTimeRange[0]
@@ -374,7 +374,8 @@
if (searchForm.keyword) params.keyword = searchForm.keyword
if (searchForm.channelId) params.channelId = searchForm.channelId
if (searchForm.applicationStatus) params.applicationStatus = searchForm.applicationStatus
if (props.bizType) params.bizType = props.bizType
params.bizType =
props.bizType || (isClinical.value ? 'clinical_application' : 'pilot_service')
const res: any = await fetchPilotApplicationList(params)
tableData.value = res?.list ?? res?.records ?? []
@@ -1,12 +1,56 @@
<!-- 中试服务申请单(申请单 / 体检 / 输注计划) -->
<!-- 中试服务申请单(申请单 / 体检 / 输注计划);临床申请单(申请单 / 输注计划 / 缴费信息) -->
<template>
<div class="page-container">
<section class="panel">
<template v-if="isClinical">
<div class="panel-top">
<h2 class="title-bar-heading">临床申请单</h2>
<div class="panel-entity-switch" role="tablist" aria-label="视图类型">
<button
type="button"
class="entity-switch-card"
:class="{ 'is-active': activeTab === 'application' }"
role="tab"
:aria-selected="activeTab === 'application'"
@click="activeTab = 'application'"
>
<span class="entity-switch-card__icon"><el-icon><Document /></el-icon></span>
<span class="entity-switch-card__main">
<span class="entity-switch-card__title">临床申请单</span>
<span class="entity-switch-card__desc">申请单录入、审核与跟踪</span>
</span>
</button>
<button
type="button"
class="entity-switch-card"
:class="{ 'is-active': activeTab === 'infusion' }"
role="tab"
:aria-selected="activeTab === 'infusion'"
@click="activeTab = 'infusion'"
>
<span class="entity-switch-card__icon"><el-icon><Operation /></el-icon></span>
<span class="entity-switch-card__main">
<span class="entity-switch-card__title">输注计划管理</span>
<span class="entity-switch-card__desc">输注计划安排与执行</span>
</span>
</button>
<button
type="button"
class="entity-switch-card"
:class="{ 'is-active': activeTab === 'payment' }"
role="tab"
:aria-selected="activeTab === 'payment'"
@click="activeTab = 'payment'"
>
<span class="entity-switch-card__icon"><el-icon><Wallet /></el-icon></span>
<span class="entity-switch-card__main">
<span class="entity-switch-card__title">缴费信息</span>
<span class="entity-switch-card__desc">缴费提交与状态跟踪</span>
</span>
</button>
</div>
<PilotApplicationTab :biz-type="bizType" />
<PilotApplicationTab v-if="activeTab === 'application'" :biz-type="effectiveBizType" />
<InfusionScheduleTab v-else-if="activeTab === 'infusion'" :biz-type="effectiveBizType" />
<ClinicalPaymentTab v-else-if="activeTab === 'payment'" />
</template>
<template v-else>
@@ -55,36 +99,49 @@
</button>
</div>
<PilotApplicationTab v-if="activeTab === 'application'" />
<CheckupManagementTab v-else-if="activeTab === 'checkup'" />
<InfusionScheduleTab v-else-if="activeTab === 'infusion'" />
<PilotApplicationTab v-if="activeTab === 'application'" :biz-type="effectiveBizType" />
<CheckupManagementTab v-else-if="activeTab === 'checkup'" :biz-type="effectiveBizType" />
<InfusionScheduleTab v-else-if="activeTab === 'infusion'" :biz-type="effectiveBizType" />
</template>
</section>
</div>
</template>
<script setup lang="ts">
import { Document, Calendar, Operation } from '@element-plus/icons-vue'
import { Document, Calendar, Operation, Wallet } from '@element-plus/icons-vue'
import PilotApplicationTab from './PilotApplicationTab.vue'
import CheckupManagementTab from './CheckupManagementTab.vue'
import InfusionScheduleTab from './InfusionScheduleTab.vue'
import ClinicalPaymentTab from './ClinicalPaymentTab.vue'
defineOptions({ name: 'PilotApplicationManagement' })
const props = defineProps<{ bizType?: string }>()
const isClinical = computed(() => props.bizType === 'clinical_application')
/** 中试菜单固定 pilot_service;临床由路由传入 clinical_application */
const effectiveBizType = computed(
() => props.bizType || (isClinical.value ? 'clinical_application' : 'pilot_service')
)
const VALID_TABS = ['application', 'checkup', 'infusion'] as const
type EntityTabKey = (typeof VALID_TABS)[number]
const PILOT_TABS = ['application', 'checkup', 'infusion'] as const
const CLINICAL_TABS = ['application', 'infusion', 'payment'] as const
type PilotTabKey = (typeof PILOT_TABS)[number]
type ClinicalTabKey = (typeof CLINICAL_TABS)[number]
type EntityTabKey = PilotTabKey | ClinicalTabKey
const route = useRoute()
const activeTab = ref<EntityTabKey>('application')
onMounted(() => {
if (isClinical.value) return
const tab = String(route.query.tab || '')
if (VALID_TABS.includes(tab as EntityTabKey)) {
activeTab.value = tab as EntityTabKey
if (isClinical.value) {
if (CLINICAL_TABS.includes(tab as ClinicalTabKey)) {
activeTab.value = tab as ClinicalTabKey
}
return
}
if (PILOT_TABS.includes(tab as PilotTabKey)) {
activeTab.value = tab as PilotTabKey
}
})
</script>
File diff suppressed because it is too large. Load diff