This commit is contained in:
zlwu committed 2026-07-14 13:55:11 +08:00
1 parent f90726927e
commit 6eea13370c
103 files changed
+38401 -32231

No files matched your search

@@ -0,0 +1,43 @@
import request from '@/utils/http'
export type QcMaterialAmountAuthUser = {
id: string
userId: string
userNo: string
nickName: string
phoneNo: string
deptName: string
status: string
grantTime: string
}
export function fetchQcMaterialAmountAuthUsers(params?: {
page?: number
pageSize?: number
keyword?: string
}) {
return request.get<Api.Common.PageList<QcMaterialAmountAuthUser>>({
url: '/web/admin/qc-material-amount-auth/users',
params
})
}
export function fetchGrantQcMaterialAmountAuth(userId: string) {
return request.post<{ created: boolean }>({
url: '/web/admin/qc-material-amount-auth/users',
data: { userId }
})
}
export function fetchRevokeQcMaterialAmountAuth(userId: string) {
return request.delete({
url: `/web/admin/qc-material-amount-auth/users/${userId}`
})
}
export function fetchBatchRevokeQcMaterialAmountAuth(userIds: string[]) {
return request.post<{ count: number }>({
url: '/web/admin/qc-material-amount-auth/users/batch-revoke',
data: { userIds }
})
}
@@ -0,0 +1,222 @@
<!-- 协议附件 — 迷你缩略图只读(卡片列表用) -->
<template>
<div class="protocol-attachment-mini">
<div v-if="label" class="protocol-attachment-mini__label">{{ label }}</div>
<span v-if="!files.length" class="protocol-attachment-mini__empty">{{ emptyText }}</span>
<div v-else class="protocol-attachment-mini__list">
<div
v-for="(file, index) in files"
:key="String(file.id || file.fileUrl || index)"
class="protocol-attachment-mini__item"
>
<div
class="protocol-attachment-mini__preview"
:class="{ 'is-clickable': isImageFile(file) && file.fileUrl }"
@click="isImageFile(file) && file.fileUrl ? emit('preview', file) : undefined"
>
<template v-if="isImageFile(file) && file.fileUrl">
<img
:src="resolveFileUrl(String(file.fileUrl || ''))"
:alt="String(file.fileName || '')"
/>
</template>
<template v-else-if="isVideoFile(file)">
<div class="protocol-attachment-mini__icon protocol-attachment-mini__icon--video">
<el-icon :size="20"><VideoPlay /></el-icon>
</div>
</template>
<template v-else>
<div class="protocol-attachment-mini__icon protocol-attachment-mini__icon--doc">
<el-icon :size="20"><Document /></el-icon>
</div>
</template>
</div>
<div class="protocol-attachment-mini__footer">
<span class="protocol-attachment-mini__name" :title="String(file.fileName || '')">{{
file.fileName || '未命名'
}}</span>
<el-icon
class="protocol-attachment-mini__download"
title="下载"
@click.stop="emit('download', file)"
>
<Download />
</el-icon>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { Document, Download, VideoPlay } from '@element-plus/icons-vue'
import { attachmentFullUrl } from '@/composables/useAttachmentActions'
defineOptions({ name: 'ProtocolAttachmentMiniReadonly' })
withDefaults(
defineProps<{
label?: string
files: Array<Record<string, unknown>>
emptyText?: string
}>(),
{
label: '',
emptyText: '无'
}
)
const emit = defineEmits<{
preview: [file: Record<string, unknown>]
download: [file: Record<string, unknown>]
}>()
function resolveFileUrl(suffix: string) {
return attachmentFullUrl(suffix)
}
function isImageFile(file: Record<string, unknown>) {
const url = String(file.fileUrl || '').toLowerCase()
const name = String(file.fileName || '').toLowerCase()
return (
/\.(jpg|jpeg|png|gif|bmp|webp|svg)(\?|$)/.test(url) ||
/\.(jpg|jpeg|png|gif|bmp|webp|svg)$/.test(name) ||
String(file.fileType || '').startsWith('image/')
)
}
function isVideoFile(file: Record<string, unknown>) {
const url = String(file.fileUrl || '').toLowerCase()
const name = String(file.fileName || '').toLowerCase()
return (
/\.(mp4|webm|ogg|mov|avi)(\?|$)/.test(url) ||
/\.(mp4|webm|ogg|mov|avi)$/.test(name) ||
String(file.fileType || '').startsWith('video/')
)
}
</script>
<style scoped lang="scss">
.protocol-attachment-mini {
min-width: 0;
}
.protocol-attachment-mini__label {
margin-bottom: 3px;
font-size: 10px;
line-height: 1.35;
color: var(--mint-text-muted, #64748b);
}
.protocol-attachment-mini__empty {
font-size: 11px;
line-height: 1.35;
color: var(--mint-text-muted, #64748b);
}
.protocol-attachment-mini__list {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.protocol-attachment-mini__item {
width: 80px;
display: flex;
flex-direction: column;
border: 1px solid #e2e8f0;
border-radius: 6px;
background: #fff;
overflow: hidden;
transition:
border-color 0.15s,
box-shadow 0.15s;
&:hover {
border-color: #047857;
box-shadow: 0 2px 6px rgb(4 120 87 / 10%);
}
}
.protocol-attachment-mini__preview {
width: 100%;
height: 56px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
background: #f8fafc;
overflow: hidden;
&.is-clickable {
cursor: pointer;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}
.protocol-attachment-mini__icon {
width: 32px;
height: 32px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
&--video {
background: #ede9fe;
color: #7c3aed;
}
&--doc {
background: #e0f2fe;
color: #0284c7;
}
}
.protocol-attachment-mini__footer {
display: flex;
align-items: center;
gap: 2px;
padding: 3px 4px;
min-width: 0;
}
.protocol-attachment-mini__name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 10px;
line-height: 1.3;
color: #334155;
}
.protocol-attachment-mini__download {
flex-shrink: 0;
width: 18px;
height: 18px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
color: var(--mint-text-muted, #64748b);
cursor: pointer;
background: #f1f5f9;
transition:
background 0.15s,
color 0.15s;
&:hover {
background: #047857;
color: #fff;
}
}
</style>
@@ -1,10 +1,9 @@
<!-- 样本编码 + 特殊样本警示(列表场景:编码与说明均为红色加粗) -->
<!-- 样本编码 + 特殊样本警示(特殊样本以 danger Tag 展示) -->
<template>
<span
class="sample-code-with-special"
:class="[
`sample-code-with-special--${layout}`,
{ 'sample-code-with-special--danger': isSpecial },
{ 'sample-code-with-special--mono': monospace }
]"
>
@@ -14,6 +13,7 @@
:is-special="isSpecial"
:special-remark="specialRemark"
:layout="layout"
:size="tagSize"
/>
</span>
</template>
@@ -32,6 +32,7 @@
fallback?: string
showCode?: boolean
monospace?: boolean
tagSize?: 'large' | 'default' | 'small'
}>(),
{
sampleCode: '',
@@ -40,7 +41,8 @@
layout: 'inline',
fallback: '—',
showCode: true,
monospace: false
monospace: false,
tagSize: 'small'
}
)
@@ -53,20 +55,21 @@
<style scoped lang="scss">
.sample-code-with-special {
&.sample-code-with-special--inline {
display: inline;
display: inline-flex;
align-items: center;
flex-wrap: wrap;
gap: 6px;
vertical-align: middle;
}
&.sample-code-with-special--block {
display: block;
min-width: 0;
max-width: 100%;
}
}
.sample-code-with-special--mono .sample-code-with-special__code {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}
.sample-code-with-special--danger .sample-code-with-special__code {
color: var(--el-color-danger);
font-weight: 700;
}
</style>
@@ -1,8 +1,7 @@
<!-- 特殊样本警示展示(红色加粗) -->
<!-- 特殊样本警示展示(danger Tag) -->
<template>
<span v-if="isSpecial" class="special-sample-display" :class="`special-sample-display--${layout}`">
<span class="special-sample-mark">【特殊样本】</span>
<span v-if="displayRemark" class="special-sample-remark">{{ displayRemark }}</span>
<el-tag type="danger" :size="size">{{ tagText }}</el-tag>
</span>
</template>
@@ -14,35 +13,46 @@
isSpecial?: boolean
specialRemark?: string
layout?: 'inline' | 'block'
size?: 'large' | 'default' | 'small'
}>(),
{
isSpecial: false,
specialRemark: '',
layout: 'inline'
layout: 'inline',
size: 'small'
}
)
const displayRemark = computed(() => String(props.specialRemark || '').trim())
const tagText = computed(() => {
if (displayRemark.value) return `特殊样本:${displayRemark.value}`
return '特殊样本'
})
</script>
<style scoped lang="scss">
.special-sample-display {
&.special-sample-display--inline {
display: inline;
display: inline-flex;
vertical-align: middle;
}
&.special-sample-display--block {
display: block;
margin-top: 4px;
min-width: 0;
max-width: 100%;
:deep(.el-tag) {
display: inline-block;
max-width: 100%;
height: auto !important;
white-space: normal;
word-break: break-word;
line-height: 1.4;
text-align: left;
}
}
}
.special-sample-mark,
.special-sample-remark {
color: var(--el-color-danger);
font-weight: 700;
}
.special-sample-remark {
margin-left: 4px;
}
</style>
@@ -0,0 +1,28 @@
import { downloadAttachmentFile } from '@/utils/download-attachment'
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
export function attachmentFullUrl(url: string) {
const u = String(url || '').trim()
if (!u) return ''
if (/^https?:\/\//i.test(u)) return u
return minioBaseUrl ? `${minioBaseUrl}/${u.replace(/^\//, '')}` : u
}
export function useAttachmentActions() {
function handleAttachmentPreview(file: Record<string, unknown>) {
const url = attachmentFullUrl(String(file.fileUrl || ''))
if (url) window.open(url, '_blank')
}
function handleAttachmentDownload(file: Record<string, unknown>) {
downloadAttachmentFile(file, {
fullFileUrl: (u: string) => attachmentFullUrl(u)
})
}
return {
handleAttachmentPreview,
handleAttachmentDownload
}
}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "label": "DonationFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1"}, {"id": "list_donationformdialog_createemptytransport", "label": "createEmptyTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L881"}, {"id": "list_donationformdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L899"}, {"id": "list_donationformdialog_loadethnicoptions", "label": "loadEthnicOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L906"}, {"id": "list_donationformdialog_ensureethnicoptioninlist", "label": "ensureEthnicOptionInList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L917"}, {"id": "list_donationformdialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1019"}, {"id": "list_donationformdialog_scrolltosection", "label": "scrollToSection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1079"}, {"id": "list_donationformdialog_normalizesamplerow", "label": "normalizeSampleRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1087"}, {"id": "list_donationformdialog_handleopenforadd", "label": "handleOpenForAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1111"}, {"id": "list_donationformdialog_applydonationbundletoform", "label": "applyDonationBundleToForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1158"}, {"id": "list_donationformdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L2344"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_transport_form_section_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L772", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L773", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L774", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_research_donation", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L785", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_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/research-donation/list/DonationFormDialog.vue", "source_location": "L791", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentdropzone", "relation": "imports_from", "Line 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_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_sample_code_with_special_display_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-code-with-special-display/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_material_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1"}, {"id": "qc_material_index_ensuretabmounted", "label": "ensureTabMounted()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1274"}, {"id": "qc_material_index_handletabchange", "label": "handleTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1279"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1211", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1212", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_system_view_dialog_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1227", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_common_amount_input_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1228", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_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/views/quality-inspection/qc-material/index.vue", "source_location": "L1229", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_material_ui", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1230", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_admin", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1231", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1232", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1245", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_usage", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1246", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_constants_material_discard", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/qualityLine 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_composables_useattachmentactions_ts", "label": "useAttachmentActions.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L1"}, {"id": "composables_useattachmentactions_attachmentfullurl", "label": "attachmentFullUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L5"}, {"id": "composables_useattachmentactions_useattachmentactions", "label": "useAttachmentActions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L12"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentactions_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_download_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentactions_ts", "target": "composables_useattachmentactions_attachmentfullurl", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentactions_ts", "target": "composables_useattachmentactions_useattachmentactions", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L12", "weight": 1.0}], "raw_calls": [{"caller_nid": "composables_useattachmentactions_attachmentfullurl", "callee": "trim", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L6"}, {"caller_nid": "composables_useattachmentactions_attachmentfullurl", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L6"}, {"caller_nid": "composables_useattachmentactions_attachmentfullurl", "callee": "test", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L8"}, {"caller_nid": "composables_useattachmentactions_attachmentfullurl", "callee": "replace", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts", "source_location": "L9"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolviewdialog_vue", "label": "ProtocolViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1"}, {"id": "protocol_protocolviewdialog_financeconfirmattachmentfiles", "label": "financeConfirmAttachmentFiles()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1692"}, {"id": "protocol_protocolviewdialog_refundattachmentfiles", "label": "refundAttachmentFiles()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1699"}, {"id": "protocol_protocolviewdialog_refundfinanceconfirmattachmentfiles", "label": "refundFinanceConfirmAttachmentFiles()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1706"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolviewdialog_vue", "target": "protocol_protocolviewdialog_financeconfirmattachmentfiles", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1692", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolviewdialog_vue", "target": "protocol_protocolviewdialog_refundattachmentfiles", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1699", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolviewdialog_vue", "target": "protocol_protocolviewdialog_refundfinanceconfirmattachmentfiles", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1706", "weight": 1.0}], "raw_calls": [{"caller_nid": "protocol_protocolviewdialog_financeconfirmattachmentfiles", "callee": "isArray", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1693"}, {"caller_nid": "protocol_protocolviewdialog_financeconfirmattachmentfiles", "callee": "urlsToAttachmentFiles", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1696"}, {"caller_nid": "protocol_protocolviewdialog_financeconfirmattachmentfiles", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1696"}, {"caller_nid": "protocol_protocolviewdialog_refundattachmentfiles", "callee": "isArray", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1700"}, {"caller_nid": "protocol_protocolviewdialog_refundattachmentfiles", "callee": "urlsToAttachmentFiles", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1703"}, {"caller_nid": "protocol_protocolviewdialog_refundattachmentfiles", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1703"}, {"caller_nid": "protocol_protocolviewdialog_refundfinanceconfirmattachmentfiles", "callee": "isArray", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1707"}, {"caller_nid": "protocol_protocolviewdialog_refundfinanceconfirmattachmentfiles", "callee": "urlsToAttachmentFiles", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1710"}, {"caller_nid": "protocol_protocolviewdialog_refundfinanceconfirmattachmentfiles", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1710"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_amount_auth_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material-amount-auth/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_cell_storage_material_materialusagetab_vue", "label": "MaterialUsageTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/MaterialUsageTab.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_sample_reception_samplereceptioncardlist_vue", "label": "SampleReceptionCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/SampleReceptionCardList.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "label": "PreTransitProtocolCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L440", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L441", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_pre_transit_sample", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L442", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L443", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L455", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_code_with_special_display_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L456", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_protocol_attachment_mini_readonly_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L457", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_source_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L458", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentactions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L459", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "label": "PreTransitProtocolCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L1"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_attachmentmeta", "label": "attachmentMeta()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L585"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_rowkey", "label": "rowKey()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L589"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_isexpanded", "label": "isExpanded()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L594"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_toggleexpand", "label": "toggleExpand()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L598"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_startofday", "label": "startOfDay()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L603"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_parseflexibledate", "label": "parseFlexibleDate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L607"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_iswithinnext3days", "label": "isWithinNext3Days()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L619"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_isurgentcard", "label": "isUrgentCard()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L628"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_getintransitetalines", "label": "getInTransitEtaLines()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L638"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_formatintransitetatitle", "label": "formatInTransitEtaTitle()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L647"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_getgroupexpandeditem", "label": "getGroupExpandedItem()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L653"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_statuslabel", "label": "statusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L658"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_statustagtype", "label": "statusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L666"}, {"id": "pre_transit_sample_pretransitprotocolcardlist_sourcetypetagtype", "label": "sourceTypeTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L673"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "pre_transit_sample_pretransitprotocolcardlist_attachmentmeta", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L585", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitproLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_sample_reception_samplereceptioncardlist_vue", "label": "SampleReceptionCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/SampleReceptionCardList.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_protocol_attachment_mini_readonly_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-attachment-mini-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_material_productionmaterialusagetab_vue", "label": "ProductionMaterialUsageTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialUsageTab.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "label": "PreTransitProtocolCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L454", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L455", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_pre_transit_sample", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L456", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L457", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L469", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_code_with_special_display_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L470", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_protocol_attachment_mini_readonly_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L471", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_source_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L472", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentactions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L473", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "label": "PreTransitProtocolCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L455", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L456", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_pre_transit_sample", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L457", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L458", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L470", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_code_with_special_display_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L471", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_protocol_attachment_mini_readonly_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L472", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_source_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L473", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentactions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L474", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "label": "PreTransitProtocolCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L457", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L458", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_pre_transit_sample", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L459", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L460", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L472", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_code_with_special_display_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L473", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_protocol_attachment_mini_readonly_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L474", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_source_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L475", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentactions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L476", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_source_attachment_ts", "label": "protocol-source-attachment.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L1"}, {"id": "utils_protocol_source_attachment_normalizeattachmentfiles", "label": "normalizeAttachmentFiles()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L6"}, {"id": "utils_protocol_source_attachment_getsourceprotocolattachment", "label": "getSourceProtocolAttachment()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L12"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_source_attachment_ts", "target": "utils_protocol_source_attachment_normalizeattachmentfiles", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L6", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_source_attachment_ts", "target": "utils_protocol_source_attachment_getsourceprotocolattachment", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L12", "weight": 1.0}, {"source": "utils_protocol_source_attachment_getsourceprotocolattachment", "target": "utils_protocol_source_attachment_normalizeattachmentfiles", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L19", "weight": 1.0}], "raw_calls": [{"caller_nid": "utils_protocol_source_attachment_normalizeattachmentfiles", "callee": "isArray", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L7"}, {"caller_nid": "utils_protocol_source_attachment_normalizeattachmentfiles", "callee": "filter", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L8"}, {"caller_nid": "utils_protocol_source_attachment_getsourceprotocolattachment", "callee": "trim", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L15"}, {"caller_nid": "utils_protocol_source_attachment_getsourceprotocolattachment", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts", "source_location": "L15"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_special_sample_display_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/special-sample-display/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_cell_storage_protocol_protocolformdialog_vue", "label": "ProtocolFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1"}, {"id": "protocol_protocolformdialog_ensuretransfertypeoptions", "label": "ensureTransferTypeOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1146"}, {"id": "protocol_protocolformdialog_fmtmoney", "label": "fmtMoney()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1152"}, {"id": "protocol_protocolformdialog_haslockedpaymentdetails", "label": "hasLockedPaymentDetails()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1173"}, {"id": "protocol_protocolformdialog_createemptytransport", "label": "createEmptyTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1244"}, {"id": "protocol_protocolformdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1262"}, {"id": "protocol_protocolformdialog_loadethnicoptions", "label": "loadEthnicOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1269"}, {"id": "protocol_protocolformdialog_ensureethnicoptioninlist", "label": "ensureEthnicOptionInList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1280"}, {"id": "protocol_protocolformdialog_initpaymentdetailexpandflags", "label": "initPaymentDetailExpandFlags()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1311"}, {"id": "protocol_protocolformdialog_paymentdetailsummary", "label": "paymentDetailSummary()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1317"}, {"id": "protocol_protocolformdialog_togglepaymentdetailexpand", "label": "togglePaymentDetailExpand()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1344"}, {"id": "protocol_protocolformdialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1457"}, {"id": "protocol_protocolformdialog_scrolltosection", "label": "scrollToSection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1537"}, {"id": "protocol_protocolformdialog_normalizesamplerow", "label": "normalizeSampleRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1548"}, {"id": "protocol_protocolformdialog_removepaymentdetail", "label": "removePaymentDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1571"}, {"id": "protocol_protocolformdialog_addpaymentdetail", "label": "addPaymentDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1578"}, {"id": "protocol_protocolformdialog_defaultinstallmentstartdateymd", "label": "defaultInstallmentStartDateYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1608"}, {"id": "protocol_protocolformdialog_datetimetoymd", "label": "datetimeToYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1618"}, {"id": "protocol_protocolformdialog_isfqnumericfieldempty", "label": "isFqNumericFieldEmpty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1626"}, {"id": "protocol_protocolformdialog_appLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "label": "ProtocolFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1"}, {"id": "protocol_protocolformdialog_ensuretransfertypeoptions", "label": "ensureTransferTypeOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1147"}, {"id": "protocol_protocolformdialog_fmtmoney", "label": "fmtMoney()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1153"}, {"id": "protocol_protocolformdialog_haslockedpaymentdetails", "label": "hasLockedPaymentDetails()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1174"}, {"id": "protocol_protocolformdialog_createemptytransport", "label": "createEmptyTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1245"}, {"id": "protocol_protocolformdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1263"}, {"id": "protocol_protocolformdialog_loadethnicoptions", "label": "loadEthnicOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1270"}, {"id": "protocol_protocolformdialog_ensureethnicoptioninlist", "label": "ensureEthnicOptionInList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1281"}, {"id": "protocol_protocolformdialog_initpaymentdetailexpandflags", "label": "initPaymentDetailExpandFlags()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1312"}, {"id": "protocol_protocolformdialog_paymentdetailsummary", "label": "paymentDetailSummary()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1318"}, {"id": "protocol_protocolformdialog_togglepaymentdetailexpand", "label": "togglePaymentDetailExpand()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1345"}, {"id": "protocol_protocolformdialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1458"}, {"id": "protocol_protocolformdialog_scrolltosection", "label": "scrollToSection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1538"}, {"id": "protocol_protocolformdialog_normalizesamplerow", "label": "normalizeSampleRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1549"}, {"id": "protocol_protocolformdialog_removepaymentdetail", "label": "removePaymentDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1572"}, {"id": "protocol_protocolformdialog_addpaymentdetail", "label": "addPaymentDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1579"}, {"id": "protocol_protocolformdialog_defaultinstallmentstartdateymd", "label": "defaultInstallmentStartDateYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1609"}, {"id": "protocol_protocolformdialog_datetimetoymd", "label": "datetimeToYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1619"}, {"id": "protocol_protocolformdialog_isfqnumericfieldempty", "label": "isFqNumericFieldEmpty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1627"}, {"id": "protocol_protocolformdialog_appLine 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_components_business_sample_code_with_special_display_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-code-with-special-display/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_special_sample_display_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/special-sample-display/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_amount_auth_ts", "label": "qc-material-amount-auth.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L1"}, {"id": "api_qc_material_amount_auth_fetchqcmaterialamountauthusers", "label": "fetchQcMaterialAmountAuthUsers()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L14"}, {"id": "api_qc_material_amount_auth_fetchgrantqcmaterialamountauth", "label": "fetchGrantQcMaterialAmountAuth()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L25"}, {"id": "api_qc_material_amount_auth_fetchrevokeqcmaterialamountauth", "label": "fetchRevokeQcMaterialAmountAuth()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L32"}, {"id": "api_qc_material_amount_auth_fetchbatchrevokeqcmaterialamountauth", "label": "fetchBatchRevokeQcMaterialAmountAuth()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L38"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_amount_auth_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/qc-material-amount-auth.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_amount_auth_ts", "target": "api_qc_material_amount_auth_fetchqcmaterialamountauthusers", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L14", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_amount_auth_ts", "target": "api_qc_material_amount_auth_fetchgrantqcmaterialamountauth", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L25", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_amount_auth_ts", "target": "api_qc_material_amount_auth_fetchrevokeqcmaterialamountauth", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L32", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_amount_auth_ts", "target": "api_qc_material_amount_auth_fetchbatchrevokeqcmaterialamountauth", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L38", "weight": 1.0}], "raw_calls": [{"caller_nid": "api_qc_material_amount_auth_fetchqcmaterialamountauthusers", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L19"}, {"caller_nid": "api_qc_material_amount_auth_fetchgrantqcmaterialamountauth", "callee": "post", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L26"}, {"caller_nid": "api_qc_material_amount_auth_fetchrevokeqcmaterialamountauth", "callee": "delete", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L33"}, {"caller_nid": "api_qc_material_amount_auth_fetchbatchrevokeqcmaterialamountauth", "callee": "post", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-amount-auth.ts", "source_location": "L39"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_sample_reception_samplereceptioncardlist_vue", "label": "SampleReceptionCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/SampleReceptionCardList.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_amount_auth_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material-amount-auth/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_research_donation_list_donationviewdialog_vue", "label": "DonationViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L1"}, {"id": "list_donationviewdialog_dash", "label": "dash()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L738"}, {"id": "list_donationviewdialog_formatmetric", "label": "formatMetric()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L742"}, {"id": "list_donationviewdialog_formatymd", "label": "formatYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L748"}, {"id": "list_donationviewdialog_formatym", "label": "formatYm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L754"}, {"id": "list_donationviewdialog_auditordisplay", "label": "auditorDisplay()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L760"}, {"id": "list_donationviewdialog_sampletypename", "label": "sampleTypeName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L766"}, {"id": "list_donationviewdialog_unitname", "label": "unitName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L770"}, {"id": "list_donationviewdialog_ensureunitsinoptions", "label": "ensureUnitsInOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L778"}, {"id": "list_donationviewdialog_sitename", "label": "siteName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L796"}, {"id": "list_donationviewdialog_expressname", "label": "expressName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L800"}, {"id": "list_donationviewdialog_samplereceptionchecklist", "label": "sampleReceptionCheckList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L804"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_vue", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L552", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_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/views/research-donation/list/DonationViewDialog.vue", "source_location": "L553", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L554", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_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/views/research-donation/list/DonationViewDialog.vue", "source_location": "L555", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_qc_info_grouped_panel_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L556", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "label": "ProtocolFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1"}, {"id": "protocol_protocolformdialog_ensuretransfertypeoptions", "label": "ensureTransferTypeOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1147"}, {"id": "protocol_protocolformdialog_fmtmoney", "label": "fmtMoney()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1153"}, {"id": "protocol_protocolformdialog_haslockedpaymentdetails", "label": "hasLockedPaymentDetails()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1174"}, {"id": "protocol_protocolformdialog_createemptytransport", "label": "createEmptyTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1245"}, {"id": "protocol_protocolformdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1263"}, {"id": "protocol_protocolformdialog_loadethnicoptions", "label": "loadEthnicOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1270"}, {"id": "protocol_protocolformdialog_ensureethnicoptioninlist", "label": "ensureEthnicOptionInList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1281"}, {"id": "protocol_protocolformdialog_initpaymentdetailexpandflags", "label": "initPaymentDetailExpandFlags()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1312"}, {"id": "protocol_protocolformdialog_paymentdetailsummary", "label": "paymentDetailSummary()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1318"}, {"id": "protocol_protocolformdialog_togglepaymentdetailexpand", "label": "togglePaymentDetailExpand()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1345"}, {"id": "protocol_protocolformdialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1458"}, {"id": "protocol_protocolformdialog_scrolltosection", "label": "scrollToSection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1538"}, {"id": "protocol_protocolformdialog_normalizesamplerow", "label": "normalizeSampleRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1549"}, {"id": "protocol_protocolformdialog_removepaymentdetail", "label": "removePaymentDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1572"}, {"id": "protocol_protocolformdialog_addpaymentdetail", "label": "addPaymentDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1579"}, {"id": "protocol_protocolformdialog_defaultinstallmentstartdateymd", "label": "defaultInstallmentStartDateYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1609"}, {"id": "protocol_protocolformdialog_datetimetoymd", "label": "datetimeToYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1619"}, {"id": "protocol_protocolformdialog_isfqnumericfieldempty", "label": "isFqNumericFieldEmpty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1627"}, {"id": "protocol_protocolformdialog_appLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "label": "PreTransitProtocolCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L452", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L453", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_pre_transit_sample", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L454", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L455", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_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/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L467", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_code_with_special_display_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L468", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_protocol_attachment_mini_readonly_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L469", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_source_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L470", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_pre_transit_sample_pretransitprotocolcardlist_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentactions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue", "source_location": "L471", "weight": 1.0}], "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_quality_inspection_qc_material_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1"}, {"id": "qc_material_index_ensuretabmounted", "label": "ensureTabMounted()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1274"}, {"id": "qc_material_index_handletabchange", "label": "handleTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1279"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1211", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1212", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_system_view_dialog_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1227", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_common_amount_input_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1228", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_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/views/quality-inspection/qc-material/index.vue", "source_location": "L1229", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_material_ui", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1230", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_admin", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1231", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1232", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1245", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_usage", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1246", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_constants_material_discard", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/qualityLine 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"}, {"id": "qc_material_qcmaterialusagetab_ismanualoutrow", "label": "isManualOutRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L436"}, {"id": "qc_material_qcmaterialusagetab_isdiscardrow", "label": "isDiscardRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L442"}, {"id": "qc_material_qcmaterialusagetab_parsefromremark", "label": "parseFromRemark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L446"}, {"id": "qc_material_qcmaterialusagetab_displayreceiver", "label": "displayReceiver()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L455"}, {"id": "qc_material_qcmaterialusagetab_displaypurpose", "label": "displayPurpose()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L461"}, {"id": "qc_material_qcmaterialusagetab_displayusetime", "label": "displayUseTime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L467"}, {"id": "qc_material_qcmaterialusagetab_displayusageqty", "label": "displayUsageQty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L473"}, {"id": "qc_material_qcmaterialusagetab_displaytaskusageqty", "label": "displayTaskUsageQty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L479"}, {"id": "qc_material_qcmaterialusagetab_displayqctaskno", "label": "displayQcTaskNo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L483"}, {"id": "qc_material_qcmaterialusagetab_displaystockbefore", "label": "displayStockBefore()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L488"}, {"id": "qc_material_qcmaterialusagetab_getchangetypelabel", "label": "getChangeTypeLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L495"}, {"id": "qc_material_qcmaterialusagetab_getchangetypetagtype", "label": "getChangeTypeTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L503"}, {"id": "qc_material_qcmaterialusagetab_getsourcetagtype", "label": "getSourceTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L511"}, {"id": "qc_material_qcmaterialusagetab_getsourcelabel", "label": "getSourceLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L521"}, {"id": "qc_material_qcmaterialusagetab_canmarkfullyused", "label": "canMarkFullyUsed()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L533"}, {"id": "qc_material_qcmaterialusagetab_handlemarkfullyused", "label": "handleMarkFullyUsed()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L537"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_qcmaterialusagetab_vue", "target": "qc_material_qcmaterialusagetab_ismanualoutrow", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L436", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admiLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_protocol_attachment_mini_readonly_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-attachment-mini-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_sample_reception_samplereceptioncardlist_vue", "label": "SampleReceptionCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/SampleReceptionCardList.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
+11
View File
@@ -1097,6 +1097,17 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
menuCode: 'biz:qcMaterial:list'
}
},
{
id: '95100000000000000000000000000001',
name: 'QualityInspectionQcMaterialAmountAuth',
path: 'qc-material-amount-auth',
component: '/quality-inspection/qc-material-amount-auth/index',
meta: {
title: '质检物料金额查看授权',
keepAlive: true,
menuCode: 'biz:qcMaterialAmountAuth:list'
}
},
{
id: '70000000000000000000000000000010',
name: 'QualityInspectionQcMaterialUsage',
@@ -0,0 +1,26 @@
export type ProtocolSourceAttachmentMeta = {
label: string
files: Array<Record<string, unknown>>
}
function normalizeAttachmentFiles(raw: unknown): Array<Record<string, unknown>> {
if (!Array.isArray(raw)) return []
return raw.filter((item) => item && typeof item === 'object') as Array<Record<string, unknown>>
}
/** 按来源返回协议级附件标签与文件列表(细胞存储=孕妇健康调查表,科研捐赠=传染病检测报告) */
export function getSourceProtocolAttachment(
row: Record<string, unknown>
): ProtocolSourceAttachmentMeta {
const source = String(row.sourceType || 'cell_storage').trim()
if (source === 'research_donation') {
return {
label: '传染病检测报告',
files: normalizeAttachmentFiles(row.infectiousDiseaseReportAttachmentFiles)
}
}
return {
label: '孕妇健康调查表',
files: normalizeAttachmentFiles(row.healthSurveyAttachmentFiles)
}
}
@@ -44,11 +44,12 @@
<div class="section-title">
<div class="section-title-left"><h3>一键导入</h3></div>
</div>
<el-form-item label="标准信息">
<el-form-item label="标准信息" class="import-textarea-item">
<el-input
v-model="standardImportText"
type="textarea"
:rows="12"
:rows="28"
class="import-standard-textarea"
placeholder="请粘贴标准格式信息,点击「一键导入」填充各 Tab 字段"
/>
</el-form-item>
@@ -198,6 +199,164 @@
</div>
</el-form-item>
</div>
<div class="form-grid form-grid--attachment">
<el-form-item label="知情同意书">
<div
class="attachment-upload"
:class="{ 'is-dragover': isConsentAttachDragover }"
v-bind="consentAttachDropHandlers"
>
<div class="attachment-list">
<el-upload
ref="consentAttachmentUploadRef"
:auto-upload="false"
:show-file-list="false"
:multiple="true"
accept="image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar"
@change="handleConsentAttachmentChange"
>
<div class="upload-card">
<el-icon :size="28" color="#047857"><Plus /></el-icon>
<span class="upload-card-text">上传附件</span>
</div>
</el-upload>
<div
v-for="(file, index) in formData.consentAttachments"
:key="file.id || index"
class="attachment-item"
:class="{ 'is-uploading': file._uploading }"
>
<div
class="attachment-preview"
@click="
isImageFile(file) && file.fileUrl
? handlePreviewAttachment(file)
: undefined
"
>
<template v-if="isImageFile(file) && file.fileUrl">
<img :src="fullFileUrl(file.fileUrl)" :alt="file.fileName" />
</template>
<template v-else-if="isImageFile(file) && !file.fileUrl">
<el-icon :size="24" color="#94a3b8"><Loading /></el-icon>
</template>
<template v-else-if="isVideoFile(file)">
<div class="attachment-preview__icon attachment-preview__icon--video">
<el-icon :size="28"><VideoPlay /></el-icon>
</div>
</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>
<div class="attachment-actions">
<el-icon
class="action-btn"
title="下载"
@click="handleDownloadAttachment(file)"
><Download
/></el-icon>
<el-icon
class="action-btn action-btn--danger"
title="删除"
@click="removeConsentAttachment(index)"
><Delete
/></el-icon>
</div>
</div>
</div>
</div>
<span class="upload-hint"
>支持拖拽或点击上传图片、视频、PDF、Word、Excel等文件,单文件不超过 20MB</span
>
</div>
</el-form-item>
</div>
<div class="form-grid form-grid--attachment">
<el-form-item label="孕妇健康调查表">
<div
class="attachment-upload"
:class="{ 'is-dragover': isHealthSurveyAttachDragover }"
v-bind="healthSurveyAttachDropHandlers"
>
<div class="attachment-list">
<el-upload
ref="healthSurveyAttachmentUploadRef"
:auto-upload="false"
:show-file-list="false"
:multiple="true"
accept="image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar"
@change="handleHealthSurveyAttachmentChange"
>
<div class="upload-card">
<el-icon :size="28" color="#047857"><Plus /></el-icon>
<span class="upload-card-text">上传附件</span>
</div>
</el-upload>
<div
v-for="(file, index) in formData.healthSurveyAttachments"
:key="file.id || index"
class="attachment-item"
:class="{ 'is-uploading': file._uploading }"
>
<div
class="attachment-preview"
@click="
isImageFile(file) && file.fileUrl
? handlePreviewAttachment(file)
: undefined
"
>
<template v-if="isImageFile(file) && file.fileUrl">
<img :src="fullFileUrl(file.fileUrl)" :alt="file.fileName" />
</template>
<template v-else-if="isImageFile(file) && !file.fileUrl">
<el-icon :size="24" color="#94a3b8"><Loading /></el-icon>
</template>
<template v-else-if="isVideoFile(file)">
<div class="attachment-preview__icon attachment-preview__icon--video">
<el-icon :size="28"><VideoPlay /></el-icon>
</div>
</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>
<div class="attachment-actions">
<el-icon
class="action-btn"
title="下载"
@click="handleDownloadAttachment(file)"
><Download
/></el-icon>
<el-icon
class="action-btn action-btn--danger"
title="删除"
@click="removeHealthSurveyAttachment(index)"
><Delete
/></el-icon>
</div>
</div>
</div>
</div>
<span class="upload-hint"
>支持拖拽或点击上传图片、视频、PDF、Word、Excel等文件,单文件不超过 20MB</span
>
</div>
</el-form-item>
</div>
</div>
</div>
@@ -1218,6 +1377,8 @@
registerDate: '',
collectorUserId: '',
protocolAttachments: '',
consentFormUrls: '',
healthSurveyFormUrls: '',
remark: '',
attachments: [] as Array<{
id?: string
@@ -1228,6 +1389,24 @@
fileType?: string
_uploading?: boolean
}>,
consentAttachments: [] as Array<{
id?: string
fileName: string
fileUrl: string
fileSize: number
fileSizeDisplay?: string
fileType?: string
_uploading?: boolean
}>,
healthSurveyAttachments: [] as Array<{
id?: string
fileName: string
fileUrl: string
fileSize: number
fileSizeDisplay?: string
fileType?: string
_uploading?: boolean
}>,
// Party Customer
customerId: '' as string,
motherName: '',
@@ -1284,7 +1463,11 @@
registerDate: '',
collectorUserId: '',
protocolAttachments: '',
consentFormUrls: '',
healthSurveyFormUrls: '',
attachments: [],
consentAttachments: [],
healthSurveyAttachments: [],
remark: '',
customerId: '',
motherName: '',
@@ -1875,6 +2058,16 @@
if (att && att.length) {
formData.attachments = att.map((a) => ({ ...a })) as any
}
const consentAtt = (bundle as any).consentAttachmentFiles as Array<Record<string, any>> | null
if (consentAtt && consentAtt.length) {
formData.consentAttachments = consentAtt.map((a) => ({ ...a })) as any
}
const healthSurveyAtt = (bundle as any).healthSurveyAttachmentFiles as
| Array<Record<string, any>>
| null
if (healthSurveyAtt && healthSurveyAtt.length) {
formData.healthSurveyAttachments = healthSurveyAtt.map((a) => ({ ...a })) as any
}
}
async function handleOpenForEdit() {
@@ -1891,6 +2084,8 @@
formData.registerDate = String(row.registerDate || '')
formData.collectorUserId = String(row.collectorUserId || '')
formData.protocolAttachments = String((row as any).protocolAttachments || '')
formData.consentFormUrls = String((row as any).consentFormUrls || '')
formData.healthSurveyFormUrls = String((row as any).healthSurveyFormUrls || '')
formData.remark = String(row.remark || '')
dialogFormLoading.value = true
@@ -1979,11 +2174,22 @@
.map((a) => a.fileUrl)
.filter(Boolean)
.join(',')
const consentAttachmentUrls = formData.consentAttachments
.map((a) => a.fileUrl)
.filter(Boolean)
.join(',')
const healthSurveyAttachmentUrls = formData.healthSurveyAttachments
.map((a) => a.fileUrl)
.filter(Boolean)
.join(',')
const payload: Record<string, unknown> = {
protocolStatus: formData.protocolStatus,
registerDate: formData.registerDate || undefined,
collectorUserId: formData.collectorUserId || undefined,
protocolAttachments: protocolAttachmentUrls || formData.protocolAttachments || undefined,
consentFormUrls: consentAttachmentUrls || formData.consentFormUrls || undefined,
healthSurveyFormUrls:
healthSurveyAttachmentUrls || formData.healthSurveyFormUrls || undefined,
attachments: formData.attachments.map((a) => ({
id: a.id,
fileName: a.fileName,
@@ -1992,6 +2198,22 @@
fileSizeDisplay: a.fileSizeDisplay,
fileType: a.fileType
})),
consentAttachments: formData.consentAttachments.map((a) => ({
id: a.id,
fileName: a.fileName,
fileUrl: a.fileUrl,
fileSize: a.fileSize,
fileSizeDisplay: a.fileSizeDisplay,
fileType: a.fileType
})),
healthSurveyAttachments: formData.healthSurveyAttachments.map((a) => ({
id: a.id,
fileName: a.fileName,
fileUrl: a.fileUrl,
fileSize: a.fileSize,
fileSizeDisplay: a.fileSizeDisplay,
fileType: a.fileType
})),
remark: formData.remark || undefined,
partyCustomer: {
customerId: formData.customerId || undefined,
@@ -3294,6 +3516,62 @@
/* ====== 附件上传 ====== */
const attachmentUploadRef = ref()
const consentAttachmentUploadRef = ref()
const healthSurveyAttachmentUploadRef = ref()
type ProtocolAttachmentItem = {
id?: string
fileName: string
fileUrl: string
fileSize: number
fileSizeDisplay?: string
fileType?: string
_uploading?: boolean
}
async function uploadProtocolAttachmentFile(
uploadFile: any,
list: ProtocolAttachmentItem[],
folder: string,
uploadRef: { value?: { clearFiles?: () => void } | null }
) {
const file = uploadFile.raw || uploadFile
if (!file) return
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
list.push({
id: tempId,
fileName: file.name,
fileUrl: '',
fileSize: file.size,
fileSizeDisplay: `${(file.size / 1024).toFixed(1)} KB`,
fileType: file.type || '',
_uploading: true
})
const idx = list.length - 1
try {
const fd = new FormData()
fd.append('folder', folder)
fd.append('file', file)
const res = await fetchUploadAttachment(fd)
list[idx] = {
...list[idx],
id: res.id || tempId,
fileName: file.name || res.fileName,
fileUrl: res.fileUrl,
fileSize: res.fileSize || file.size,
fileSizeDisplay: res.fileSizeDisplay || `${(file.size / 1024).toFixed(1)} KB`,
fileType: res.fileType || file.type || '',
_uploading: false
}
} catch {
ElMessage.error('文件上传失败')
list.splice(idx, 1)
} finally {
nextTick(() => uploadRef.value?.clearFiles())
}
}
function isImageFile(file: any) {
const url = (file.fileUrl || '').toLowerCase()
@@ -3316,48 +3594,44 @@
}
async function handleAttachmentChange(uploadFile: any) {
const file = uploadFile.raw || uploadFile
if (!file) return
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
formData.attachments.push({
id: tempId,
fileName: file.name,
fileUrl: '',
fileSize: file.size,
fileSizeDisplay: `${(file.size / 1024).toFixed(1)} KB`,
fileType: file.type || '',
_uploading: true
})
const idx = formData.attachments.length - 1
try {
const fd = new FormData()
fd.append('folder', 'protocol')
fd.append('file', file)
const res = await fetchUploadAttachment(fd)
formData.attachments[idx] = {
...formData.attachments[idx],
id: res.id || tempId,
fileName: file.name || res.fileName,
fileUrl: res.fileUrl,
fileSize: res.fileSize || file.size,
fileSizeDisplay: res.fileSizeDisplay || `${(file.size / 1024).toFixed(1)} KB`,
fileType: res.fileType || file.type || '',
_uploading: false
}
} catch {
ElMessage.error('文件上传失败')
formData.attachments.splice(idx, 1)
} finally {
nextTick(() => attachmentUploadRef.value?.clearFiles())
}
await uploadProtocolAttachmentFile(
uploadFile,
formData.attachments,
'protocol',
attachmentUploadRef
)
}
function removeAttachment(index: number) {
formData.attachments.splice(index, 1)
}
async function handleConsentAttachmentChange(uploadFile: any) {
await uploadProtocolAttachmentFile(
uploadFile,
formData.consentAttachments,
'protocol-consent',
consentAttachmentUploadRef
)
}
function removeConsentAttachment(index: number) {
formData.consentAttachments.splice(index, 1)
}
async function handleHealthSurveyAttachmentChange(uploadFile: any) {
await uploadProtocolAttachmentFile(
uploadFile,
formData.healthSurveyAttachments,
'protocol-health-survey',
healthSurveyAttachmentUploadRef
)
}
function removeHealthSurveyAttachment(index: number) {
formData.healthSurveyAttachments.splice(index, 1)
}
const { isDragover: isProtocolAttachDragover, dropZoneHandlers: protocolAttachDropHandlers } =
useAttachmentDropZone({
onFiles: (files) => {
@@ -3367,6 +3641,26 @@
}
})
const { isDragover: isConsentAttachDragover, dropZoneHandlers: consentAttachDropHandlers } =
useAttachmentDropZone({
onFiles: (files) => {
for (const file of files) {
void handleConsentAttachmentChange({ raw: file })
}
}
})
const {
isDragover: isHealthSurveyAttachDragover,
dropZoneHandlers: healthSurveyAttachDropHandlers
} = useAttachmentDropZone({
onFiles: (files) => {
for (const file of files) {
void handleHealthSurveyAttachmentChange({ raw: file })
}
}
})
const { isDragover: isPaymentDetailDragover, handlersFor: paymentDetailDropHandlers } =
useIndexedAttachmentDropZone({
onFiles: (detailIndex, files) => {
@@ -3507,11 +3801,20 @@
&--import {
margin-bottom: 0;
.import-textarea-item {
margin-bottom: 12px;
:deep(.el-textarea__inner) {
min-height: 560px;
}
}
}
}
.import-actions {
display: flex;
flex-shrink: 0;
justify-content: flex-end;
padding: 0 0 8px;
}
@@ -118,12 +118,15 @@
</template>
</div>
</div>
<!-- 协议附件、备注同一行 -->
<!-- 协议附件 / 知情同意书 / 孕妇健康调查表 / 备注 -->
<div
v-if="
protocolAttachments.length || (protocol?.remark && String(protocol.remark).trim())
protocolAttachments.length ||
consentAttachments.length ||
healthSurveyAttachments.length ||
(protocol?.remark && String(protocol.remark).trim())
"
class="data-grid data-grid--2 protocol-attach-remark-row"
class="protocol-basic-attachments-block"
>
<div class="data-item protocol-attachments-item">
<div class="data-label">协议附件</div>
@@ -135,7 +138,27 @@
/>
</div>
</div>
<div class="data-item">
<div class="data-item protocol-attachments-item">
<div class="data-label">知情同意书</div>
<div class="data-value protocol-attachments-value">
<ProtocolAttachmentReadonly
:files="consentAttachments"
@preview="openPreview"
@download="downloadFile"
/>
</div>
</div>
<div class="data-item protocol-attachments-item">
<div class="data-label">孕妇健康调查表</div>
<div class="data-value protocol-attachments-value">
<ProtocolAttachmentReadonly
:files="healthSurveyAttachments"
@preview="openPreview"
@download="downloadFile"
/>
</div>
</div>
<div v-if="protocol?.remark && String(protocol.remark).trim()" class="data-item">
<div class="data-label">备注</div>
<div class="data-value data-value--muted">{{ dash(protocol?.remark) }}</div>
</div>
@@ -1205,6 +1228,16 @@
return Array.isArray(list) ? list : []
})
const consentAttachments = computed(() => {
const list = bundle.value?.consentAttachmentFiles
return Array.isArray(list) ? list : []
})
const healthSurveyAttachments = computed(() => {
const list = bundle.value?.healthSurveyAttachmentFiles
return Array.isArray(list) ? list : []
})
const storageCertInfo = computed(() => {
const sc = bundle.value?.storageCert as Record<string, any> | undefined | null
if (sc) return sc
@@ -2063,9 +2096,12 @@
}
}
/* 协议附件、备注同一行 */
.protocol-attach-remark-row {
/* 协议附件 / 知情同意书 / 孕妇健康调查表 / 备注(三行堆叠) */
.protocol-basic-attachments-block {
margin-top: 14px;
display: flex;
flex-direction: column;
gap: 14px;
}
.protocol-attachments-item {
@@ -38,25 +38,26 @@
{{ statusLabel(row) }}
</el-tag>
</div>
<div
v-if="getSpecialSampleItems(row).length"
class="protocol-card-compact__special"
>
<div class="protocol-card-compact__scroll">
<div
v-for="(item, si) in getSpecialSampleItems(row)"
:key="si"
class="protocol-card-compact__special-line"
v-if="getSpecialSampleItems(row).length"
class="protocol-card-compact__special"
>
<SampleCodeWithSpecialDisplay
:sample-code="item.sampleCode"
:is-special="true"
:special-remark="item.specialRemark"
layout="block"
monospace
/>
<div
v-for="(item, si) in getSpecialSampleItems(row)"
:key="si"
class="protocol-card-compact__special-line"
>
<SampleCodeWithSpecialDisplay
:sample-code="item.sampleCode"
:is-special="true"
:special-remark="item.specialRemark"
layout="block"
monospace
/>
</div>
</div>
</div>
<div class="protocol-card-compact__body">
<div class="protocol-card-compact__body">
<template v-if="mode === 'in_transit'">
<div class="protocol-card-compact__field">
<label>预计到达</label>
@@ -83,32 +84,44 @@
</div>
<span v-else class="protocol-card__kv-value">—</span>
</div>
<div class="protocol-card-compact__field">
<label>预产期</label>
<span
class="protocol-card__kv-value protocol-card__kv-value--danger"
:title="String(row.expectedDeliveryDate || '')"
>
{{ formatDisplayOrDash(row.expectedDeliveryDate) }}
</span>
<div class="protocol-card-compact__field protocol-card-compact__field--split-row">
<div class="protocol-card-compact__field-col">
<label>预产期</label>
<span
class="protocol-card__kv-value protocol-card__kv-value--danger"
:title="String(row.expectedDeliveryDate || '')"
>
{{ formatDisplayOrDash(row.expectedDeliveryDate) }}
</span>
</div>
<div class="protocol-card-compact__field-col">
<label>样本采集时间</label>
<span
class="protocol-card__kv-value"
:title="String(row.sampleCollectTime || '')"
>
{{ formatDisplayOrDash(row.sampleCollectTime) }}
</span>
</div>
</div>
<div class="protocol-card-compact__field">
<label>母血采集</label>
<span
class="protocol-card__kv-value"
:title="String(row.maternalBloodCollectTime || '')"
>
{{ formatDisplayOrDash(row.maternalBloodCollectTime) }}
</span>
</div>
<div class="protocol-card-compact__field">
<label>样本采集</label>
<span
class="protocol-card__kv-value"
:title="String(row.sampleCollectTime || '')"
>
{{ formatDisplayOrDash(row.sampleCollectTime) }}
</span>
<div class="protocol-card-compact__field protocol-card-compact__field--split-row">
<div class="protocol-card-compact__field-col">
<label>母血采集</label>
<span
class="protocol-card__kv-value"
:title="String(row.maternalBloodCollectTime || '')"
>
{{ formatDisplayOrDash(row.maternalBloodCollectTime) }}
</span>
</div>
<div class="protocol-card-compact__field-col protocol-card-compact__field-col--attachment">
<ProtocolAttachmentMiniReadonly
:label="attachmentMeta(row).label"
:files="attachmentMeta(row).files"
@preview="handleAttachmentPreview"
@download="handleAttachmentDownload"
/>
</div>
</div>
</template>
<template v-else>
@@ -121,44 +134,53 @@
{{ row.etaTimeSummary || '—' }}
</span>
</div>
<div class="protocol-card-compact__field">
<label>预产期</label>
<span
class="protocol-card__kv-value protocol-card__kv-value--danger"
:title="String(row.expectedDeliveryDate || '')"
>
{{ formatDisplayOrDash(row.expectedDeliveryDate) }}
</span>
<div class="protocol-card-compact__field protocol-card-compact__field--split-row">
<div class="protocol-card-compact__field-col">
<label>预产期</label>
<span
class="protocol-card__kv-value protocol-card__kv-value--danger"
:title="String(row.expectedDeliveryDate || '')"
>
{{ formatDisplayOrDash(row.expectedDeliveryDate) }}
</span>
</div>
<div class="protocol-card-compact__field-col">
<label>样本采集时间</label>
<span
class="protocol-card__kv-value"
:title="String(row.sampleCollectTime || '')"
>
{{ formatDisplayOrDash(row.sampleCollectTime) }}
</span>
</div>
</div>
<div class="protocol-card-compact__field">
<label>样本采集</label>
<span
class="protocol-card-compact__sample"
:title="String(row.sampleCollectSummary || '')"
>
{{ row.sampleCollectSummary || '—' }}
</span>
<div class="protocol-card-compact__field protocol-card-compact__field--attachment-only">
<ProtocolAttachmentMiniReadonly
:label="attachmentMeta(row).label"
:files="attachmentMeta(row).files"
@preview="handleAttachmentPreview"
@download="handleAttachmentDownload"
/>
</div>
</template>
</div>
</div>
<div class="protocol-card-compact__foot">
<el-button
class="btn-ghost protocol-card-compact__toggle"
<button
type="button"
class="protocol-card-compact__toggle"
:title="isExpanded(row) ? '收起详情' : '展开详情'"
@click.stop="toggleExpand(row)"
>
<el-icon><ArrowUp v-if="isExpanded(row)" /><ArrowDown v-else /></el-icon>
</el-button>
</button>
</div>
</div>
</article>
</div>
<div v-if="getGroupExpandedItem(group)" class="protocol-card-detail">
<article
v-if="getGroupExpandedItem(group)"
class="protocol-card protocol-card--detail"
>
<article v-if="getGroupExpandedItem(group)" class="protocol-card protocol-card--detail">
<div class="protocol-card__aside">
<div class="protocol-card__name-row">
<span class="protocol-card__index">{{
@@ -229,9 +251,7 @@
</div>
<div class="protocol-card__kv">
<label>样本采集时间</label>
<span>{{
getGroupExpandedItem(group)!.row.sampleCollectTime || '—'
}}</span>
<span>{{ getGroupExpandedItem(group)!.row.sampleCollectTime || '—' }}</span>
</div>
<div class="protocol-card__kv">
<label>母血采集时间</label>
@@ -240,7 +260,10 @@
}}</span>
</div>
<div
v-if="mode === 'in_transit' && getInTransitEtaLines(getGroupExpandedItem(group)!.row).length"
v-if="
mode === 'in_transit' &&
getInTransitEtaLines(getGroupExpandedItem(group)!.row).length
"
class="protocol-card__kv protocol-card__kv--stack"
>
<label>预计到达</label>
@@ -253,9 +276,7 @@
class="protocol-card__eta-line"
>
<span>{{ line.sampleTypeName || '样本' }}</span>
<span
class="protocol-card__kv-value protocol-card__kv-value--danger"
>
<span class="protocol-card__kv-value protocol-card__kv-value--danger">
{{ line.etaTime || '—' }}
</span>
</div>
@@ -282,6 +303,16 @@
<label>预产类型</label>
<span>{{ getGroupExpandedItem(group)!.row.preDeliveryKindLabel }}</span>
</div>
<div
class="protocol-card__kv protocol-card__kv--stack protocol-card__kv--attachment"
>
<label>{{ attachmentMeta(getGroupExpandedItem(group)!.row).label }}</label>
<ProtocolAttachmentMiniReadonly
:files="attachmentMeta(getGroupExpandedItem(group)!.row).files"
@preview="handleAttachmentPreview"
@download="handleAttachmentDownload"
/>
</div>
</div>
</section>
@@ -308,9 +339,7 @@
</div>
<div class="protocol-card__kv">
<label>分娩时间</label>
<span>{{
getGroupExpandedItem(group)!.row.newbornDeliveryTime || '—'
}}</span>
<span>{{ getGroupExpandedItem(group)!.row.newbornDeliveryTime || '—' }}</span>
</div>
</div>
</section>
@@ -352,7 +381,9 @@
</div>
<div class="protocol-card__sample-line">
<span class="protocol-card__sample-label">编码</span>
<span class="protocol-card__sample-value protocol-card__sample-value--code">
<span
class="protocol-card__sample-value protocol-card__sample-value--code"
>
<SampleCodeWithSpecialDisplay
:sample-code="item.sampleCode"
:is-special="!!item.isSpecial"
@@ -440,6 +471,9 @@
} from '@/utils/status-tag-registry'
import type { TagType } from '@/utils/status-tag-registry'
import SampleCodeWithSpecialDisplay from '@/components/business/sample-code-with-special-display/index.vue'
import ProtocolAttachmentMiniReadonly from '@/components/business/protocol-attachment-mini-readonly/index.vue'
import { getSourceProtocolAttachment } from '@/utils/protocol-source-attachment'
import { useAttachmentActions } from '@/composables/useAttachmentActions'
defineOptions({ name: 'PreTransitProtocolCardList' })
@@ -512,10 +546,7 @@
if (!el) return
const innerWidth = Math.max(0, el.clientWidth - LIST_PADDING)
const { cardWidth, gap } = compactCardLayoutForViewport()
columnsPerRow.value = Math.max(
1,
Math.floor((innerWidth + gap) / (cardWidth + gap))
)
columnsPerRow.value = Math.max(1, Math.floor((innerWidth + gap) / (cardWidth + gap)))
}
const groupedRows = computed<CardRowGroup[]>(() => {
@@ -561,6 +592,12 @@
window.removeEventListener('resize', updateColumnsPerRow)
})
const { handleAttachmentPreview, handleAttachmentDownload } = useAttachmentActions()
function attachmentMeta(row: PreTransitProtocolRow) {
return getSourceProtocolAttachment(row as Record<string, unknown>)
}
function rowKey(row: PreTransitProtocolRow) {
const id = String(row.collectionProtocolId || row.researchDonationId || row.id || '')
return `${String(row.sourceType || '')}:${id}`
@@ -755,6 +792,7 @@
align-items: stretch;
border-radius: 8px;
cursor: pointer;
overflow: hidden;
}
&.is-compact.has-special-sample {
@@ -819,6 +857,33 @@
}
}
.protocol-card-compact__scroll {
flex: 1;
min-height: 0;
overflow-x: hidden;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 4px;
margin-right: -2px;
padding-right: 2px;
scrollbar-width: thin;
scrollbar-color: #cbd5e1 transparent;
&::-webkit-scrollbar {
width: 4px;
}
&::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
}
.protocol-card-compact__special {
display: flex;
flex-direction: column;
@@ -838,12 +903,11 @@
}
.protocol-card-compact__body {
flex: 1;
flex: 0 0 auto;
display: flex;
flex-direction: column;
gap: 4px;
min-height: 0;
overflow: hidden;
}
.protocol-card-compact__field {
@@ -876,14 +940,37 @@
}
}
.protocol-card-compact__field--split-row {
flex-direction: row;
align-items: flex-start;
gap: 8px;
}
.protocol-card-compact__field-col {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1px;
}
.protocol-card-compact__field-col--attachment {
flex: 1.1;
min-width: 84px;
}
.protocol-card-compact__field--attachment-only {
flex-shrink: 0;
min-width: 0;
}
.protocol-card-compact__eta-list {
display: flex;
flex-direction: column;
gap: 6px;
width: 100%;
min-width: 0;
max-height: 72px;
overflow: hidden;
}
.protocol-card-compact__eta-line {
@@ -914,17 +1001,13 @@
white-space: nowrap;
}
.protocol-card-compact__eta-line.protocol-card__kv-value--danger .protocol-card-compact__eta-time {
.protocol-card-compact__eta-line.protocol-card__kv-value--danger
.protocol-card-compact__eta-time {
color: #dc2626;
font-weight: 500;
}
.protocol-card-compact__sample {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-clamp: 2;
overflow: hidden;
white-space: normal !important;
word-break: break-all;
}
@@ -932,14 +1015,38 @@
.protocol-card-compact__foot {
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
margin-top: auto;
padding-top: 2px;
padding-top: 0;
min-height: 16px;
}
.protocol-card-compact__toggle {
min-width: 30px;
height: 26px;
padding: 0 7px;
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
padding: 0;
border: none;
border-radius: 4px;
background: transparent;
color: var(--mint-text-muted, #94a3b8);
cursor: pointer;
line-height: 1;
transition:
color 0.15s,
background 0.15s;
&:hover {
color: var(--primary, #10b981);
background: var(--primary-bg, #ecfdf5);
}
:deep(.el-icon) {
font-size: 12px;
}
}
.protocol-card__kv-value--danger {
@@ -948,8 +1055,8 @@
}
.protocol-card__aside {
flex: 0 0 120px;
min-width: 108px;
flex: 0 0 152px;
min-width: 140px;
display: flex;
flex-direction: column;
gap: 6px;
@@ -976,9 +1083,16 @@
}
.protocol-card__special-banner-line {
min-width: 0;
font-size: 12px;
line-height: 1.4;
word-break: break-all;
word-break: break-word;
white-space: normal;
:deep(.sample-code-with-special__code) {
word-break: break-all;
white-space: normal;
}
}
.protocol-card__create-time {
@@ -1041,8 +1155,8 @@
border: 1px solid #eef2f6;
&--basic {
flex: 0.9;
min-width: 150px;
flex: 0.72;
min-width: 128px;
}
&--newborn {
@@ -1141,6 +1255,14 @@
}
}
.protocol-card__kv--attachment {
align-items: flex-start;
label {
margin-bottom: 2px;
}
}
.protocol-card__empty {
font-size: 12px;
color: var(--mint-text-muted, #334155);
@@ -1248,11 +1370,11 @@
@media (max-width: 1200px) {
.protocol-card-list {
--compact-card-width: 200px;
--compact-card-height: 262px;
--compact-card-height: 266px;
}
.protocol-card.is-compact.has-special-sample {
--compact-card-height: 302px;
--compact-card-height: 306px;
}
.protocol-card--detail {
@@ -1280,11 +1402,11 @@
@media (max-width: 768px) {
.protocol-card-list {
--compact-card-width: 184px;
--compact-card-height: 238px;
--compact-card-height: 244px;
}
.protocol-card.is-compact.has-special-sample {
--compact-card-height: 278px;
--compact-card-height: 284px;
}
.protocol-card-row {
@@ -0,0 +1,391 @@
<!-- 质检物料金额查看授权 -->
<template>
<div class="page-container">
<section class="panel">
<div class="panel-top">
<h2 class="title-bar-heading">质检物料金额查看授权</h2>
</div>
<div class="filter-block">
<el-form :model="searchForm" class="filter-form" @submit.prevent>
<div class="filter-grid">
<el-form-item label="关键词">
<el-input
v-model="searchForm.keyword"
placeholder="工号/姓名/手机号"
clearable
/>
</el-form-item>
</div>
<div class="filter-actions-row">
<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 class="btn-main" type="primary" @click="handleAdd">
<el-icon><Plus /></el-icon>
添加授权用户
</el-button>
<el-button
class="btn-ghost"
type="danger"
:disabled="selectedRows.length === 0"
@click="handleBatchRevoke"
>
<el-icon><Delete /></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="userId"
@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="userNo"
label="工号"
min-width="120"
align="center"
header-align="center"
/>
<el-table-column
prop="nickName"
label="姓名"
min-width="120"
align="center"
header-align="center"
/>
<el-table-column
prop="deptName"
label="部门"
min-width="140"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column
prop="phoneNo"
label="手机号"
min-width="130"
align="center"
header-align="center"
/>
<el-table-column
prop="grantTime"
label="授权时间"
min-width="180"
align="center"
header-align="center"
/>
<el-table-column
label="操作"
min-width="140"
fixed="right"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-button class="btn-op-item" type="danger" @click="handleRevoke(row)">
<el-icon><Delete /></el-icon>
解除授权
</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination list-pager-bar">
<el-pagination
v-model:current-page="pagination.page"
v-model:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[10, 20, 50]"
layout="total, sizes, prev, pager, next, jumper"
background
@size-change="loadData"
@current-change="loadData"
/>
</div>
</div>
</section>
<el-dialog
v-model="addVisible"
title="添加授权用户"
width="520px"
append-to-body
align-center
modal-class="protocol-dialog-mask"
class="dialog-form-layout"
destroy-on-close
@closed="resetAddForm"
>
<el-form
ref="addFormRef"
:model="addForm"
:rules="addRules"
label-position="top"
@submit.prevent
>
<el-form-item label="用户" prop="userId">
<el-select
v-model="addForm.userId"
filterable
remote
reserve-keyword
placeholder="搜索质量安全部用户(工号/姓名/手机号)"
:remote-method="searchUsers"
:loading="userSearchLoading"
style="width: 100%"
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="formatUserLabel(item)"
:value="item.id"
/>
</el-select>
</el-form-item>
<p class="form-tip">
仅可选择「质量安全部」下的用户。授权后将拥有「质检物料金额查看」角色,可在质检物料库与我的物料领用记录中查看、编辑单价与金额。
</p>
</el-form>
<template #footer>
<el-button class="btn-ghost" @click="addVisible = false">
<el-icon><Close /></el-icon>
取消
</el-button>
<el-button class="btn-main" type="primary" :loading="addLoading" @click="handleAddSubmit">
<el-icon><Check /></el-icon>
确定
</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { Check, Close, Delete, Plus, RefreshLeft, Search } from '@element-plus/icons-vue'
import { fetchDeptTree, fetchUserList } from '@/api/admin'
import {
fetchBatchRevokeQcMaterialAmountAuth,
fetchGrantQcMaterialAmountAuth,
fetchQcMaterialAmountAuthUsers,
fetchRevokeQcMaterialAmountAuth,
type QcMaterialAmountAuthUser
} from '@/api/qc-material-amount-auth'
defineOptions({ name: 'QualityInspectionQcMaterialAmountAuth' })
const QUALITY_SAFETY_DEPT_NAME = '质量安全部'
const loading = ref(false)
const tableData = ref<QcMaterialAmountAuthUser[]>([])
const selectedRows = ref<QcMaterialAmountAuthUser[]>([])
const searchForm = reactive({ keyword: '' })
const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
const addVisible = ref(false)
const addLoading = ref(false)
const addFormRef = ref()
const addForm = reactive({ userId: '' })
const addRules = {
userId: [{ required: true, message: '请选择用户', trigger: 'change' }]
}
const userOptions = ref<Api.User.UserItem[]>([])
const userSearchLoading = ref(false)
const qualitySafetyDeptId = ref('')
function findDeptByName(nodes: Api.Dept.DeptItem[], name: string): Api.Dept.DeptItem | null {
for (const n of nodes || []) {
if ((n.deptName || '').trim() === name) return n
const child = findDeptByName(n.children || [], name)
if (child) return child
}
return null
}
async function ensureQualitySafetyDeptId() {
if (qualitySafetyDeptId.value) return qualitySafetyDeptId.value
const tree = await fetchDeptTree()
const dept = findDeptByName(tree || [], QUALITY_SAFETY_DEPT_NAME)
qualitySafetyDeptId.value = dept?.id || ''
return qualitySafetyDeptId.value
}
function formatUserLabel(u: Api.User.UserItem) {
const name = (u.nickName || '').trim() || '-'
const no = (u.userNo || '').trim()
const phone = (u.phoneNo || '').trim()
const parts = [name]
if (no) parts.push(no)
if (phone) parts.push(phone)
return parts.join(' · ')
}
async function searchUsers(query: string) {
userSearchLoading.value = true
try {
const deptId = await ensureQualitySafetyDeptId()
if (!deptId) {
userOptions.value = []
ElMessage.warning(`未找到部门「${QUALITY_SAFETY_DEPT_NAME}」`)
return
}
const res = await fetchUserList({
page: 1,
pageSize: 50,
keyword: query?.trim() || undefined,
status: '1',
deptId
})
userOptions.value = res.list || []
} catch {
userOptions.value = []
} finally {
userSearchLoading.value = false
}
}
function handleSelectionChange(rows: QcMaterialAmountAuthUser[]) {
selectedRows.value = rows
}
async function loadData() {
loading.value = true
try {
const res = await fetchQcMaterialAmountAuthUsers({
page: pagination.page,
pageSize: pagination.pageSize,
keyword: searchForm.keyword?.trim() || undefined
})
tableData.value = res.list || []
pagination.total = res.total || 0
} finally {
loading.value = false
}
}
function handleSearch() {
pagination.page = 1
void loadData()
}
function handleReset() {
searchForm.keyword = ''
pagination.page = 1
void loadData()
}
function handleAdd() {
addForm.userId = ''
userOptions.value = []
addVisible.value = true
void searchUsers('')
}
function resetAddForm() {
addForm.userId = ''
userOptions.value = []
addFormRef.value?.clearValidate?.()
}
async function handleAddSubmit() {
await addFormRef.value?.validate?.()
addLoading.value = true
try {
await fetchGrantQcMaterialAmountAuth(addForm.userId)
ElMessage.success('授权成功')
addVisible.value = false
await loadData()
} catch {
/* 全局处理 */
} finally {
addLoading.value = false
}
}
async function handleRevoke(row: QcMaterialAmountAuthUser) {
try {
await ElMessageBox.confirm(
`确定解除用户「${row.nickName || row.userNo}」的金额查看授权吗?`,
'解除授权确认',
{ type: 'warning' }
)
} catch {
return
}
try {
await fetchRevokeQcMaterialAmountAuth(row.userId)
ElMessage.success('已解除授权')
await loadData()
} catch {
/* 全局处理 */
}
}
async function handleBatchRevoke() {
if (!selectedRows.value.length) return
try {
await ElMessageBox.confirm(
`确定批量解除 ${selectedRows.value.length} 位用户的授权吗?`,
'批量解除确认',
{ type: 'warning' }
)
} catch {
return
}
try {
const res = await fetchBatchRevokeQcMaterialAmountAuth(
selectedRows.value.map((r) => r.userId)
)
ElMessage.success(`已解除 ${res.count ?? selectedRows.value.length} 项授权`)
selectedRows.value = []
await loadData()
} catch {
/* 全局处理 */
}
}
onMounted(() => {
void loadData()
})
</script>
<style scoped lang="scss">
.form-tip {
margin: 0;
font-size: 12px;
line-height: 1.5;
color: var(--mint-text-muted, #64748b);
}
</style>
@@ -555,7 +555,7 @@
@change="onSingleStockInPriceQtyChange"
/>
</el-form-item>
<el-form-item label="单价(元)" prop="unitPrice">
<el-form-item v-if="showAmountColumns" label="单价(元)" prop="unitPrice">
<AmountInput
v-model="stockInForm.unitPrice"
:min="0"
@@ -563,7 +563,7 @@
@change="onSingleStockInPriceQtyChange"
/>
</el-form-item>
<el-form-item label="金额(元)" prop="amount">
<el-form-item v-if="showAmountColumns" label="金额(元)" prop="amount">
<AmountInput
v-model="stockInForm.amount"
:min="0"
@@ -736,14 +736,14 @@
@change="() => onBatchInLinePriceQtyChange(row)"
/>
</el-form-item>
<el-form-item label="单价">
<el-form-item v-if="showAmountColumns" label="单价">
<AmountInput
v-model="row.unitPrice"
:min="0"
@change="() => onBatchInLinePriceQtyChange(row)"
/>
</el-form-item>
<el-form-item label="金额">
<el-form-item v-if="showAmountColumns" label="金额">
<AmountInput
v-model="row.amount"
:min="0"
@@ -1473,28 +1473,33 @@
return materialOptions.value.find((o) => o.id === key) ?? null
})
const stockInRules = {
materialKey: [{ required: true, message: '请选择或输入物资', trigger: 'change' }],
newMaterialCode: [
{
validator: (_r: unknown, _v: unknown, cb: (e?: Error) => void) => {
if (!stockInIsManualMaterial.value) return cb()
if (!(stockInForm.newMaterialCode || '').trim()) return cb(new Error('请输入新物资编码'))
cb()
},
trigger: 'blur'
}
],
stockInNo: [{ required: true, message: '请输入入库编号', trigger: 'blur' }],
stockInDate: [{ required: true, message: '请选择入库日期', trigger: 'change' }],
expireDate: [{ required: true, message: '请选择过期日期', trigger: 'change' }],
catalogNo: [{ required: true, message: '请输入货号', trigger: 'blur' }],
batchNo: [{ required: true, message: '请输入批号', trigger: 'blur' }],
manufacturer: [{ required: true, message: '请输入厂家', trigger: 'blur' }],
unitPrice: [{ required: true, message: '请输入单价', trigger: 'change' }],
amount: [{ required: true, message: '请输入金额', trigger: 'change' }],
qty: [{ required: true, message: '请输入入库数量', trigger: 'blur' }]
}
const stockInRules = computed(() => {
const rules: Record<string, unknown[]> = {
materialKey: [{ required: true, message: '请选择或输入物资', trigger: 'change' }],
newMaterialCode: [
{
validator: (_r: unknown, _v: unknown, cb: (e?: Error) => void) => {
if (!stockInIsManualMaterial.value) return cb()
if (!(stockInForm.newMaterialCode || '').trim()) return cb(new Error('请输入新物资编码'))
cb()
},
trigger: 'blur'
}
],
stockInNo: [{ required: true, message: '请输入入库编号', trigger: 'blur' }],
stockInDate: [{ required: true, message: '请选择入库日期', trigger: 'change' }],
expireDate: [{ required: true, message: '请选择过期日期', trigger: 'change' }],
catalogNo: [{ required: true, message: '请输入货号', trigger: 'blur' }],
batchNo: [{ required: true, message: '请输入批号', trigger: 'blur' }],
manufacturer: [{ required: true, message: '请输入厂家', trigger: 'blur' }],
qty: [{ required: true, message: '请输入入库数量', trigger: 'blur' }]
}
if (showAmountColumns.value) {
rules.unitPrice = [{ required: true, message: '请输入单价', trigger: 'change' }]
rules.amount = [{ required: true, message: '请输入金额', trigger: 'change' }]
}
return rules
})
function formatReceiverUserLabel(u: Api.User.UserItem) {
const name = (u.nickName || '').trim() || '-'
@@ -2299,7 +2304,10 @@
ElMessage.warning('请填写货号、批号、厂家')
return
}
if (line.unitPrice == null || line.amount == null) {
if (
showAmountColumns.value &&
(line.unitPrice == null || line.amount == null)
) {
ElMessage.warning('请填写单价和金额')
return
}
@@ -63,10 +63,17 @@
<dt>样本类型</dt>
<dd>{{ row.sampleTypeName || '—' }}</dd>
</div>
<div
v-if="activeTab === 'received'"
class="sample-reception-card__meta-item"
>
<div class="sample-reception-card__meta-item sample-reception-card__meta-item--attachment">
<dt>{{ attachmentMeta(row).label }}</dt>
<dd>
<ProtocolAttachmentMiniReadonly
:files="attachmentMeta(row).files"
@preview="handleAttachmentPreview"
@download="handleAttachmentDownload"
/>
</dd>
</div>
<div v-if="activeTab === 'received'" class="sample-reception-card__meta-item">
<dt>实验室入库编码</dt>
<dd>
{{ row.labStorageCode || '—' }}
@@ -211,6 +218,9 @@
import type { QcProtocolPaymentSummary } from '@/api/qc-work-order'
import SampleCodeWithSpecialDisplay from '@/components/business/sample-code-with-special-display/index.vue'
import QcWorkOrderProtocolPaymentPanel from '@/views/quality-inspection/qc-work-order/QcWorkOrderProtocolPaymentPanel.vue'
import ProtocolAttachmentMiniReadonly from '@/components/business/protocol-attachment-mini-readonly/index.vue'
import { getSourceProtocolAttachment } from '@/utils/protocol-source-attachment'
import { useAttachmentActions } from '@/composables/useAttachmentActions'
defineOptions({ name: 'SampleReceptionCardList' })
@@ -242,6 +252,12 @@
'page-size-change': [size: number]
}>()
const { handleAttachmentPreview, handleAttachmentDownload } = useAttachmentActions()
function attachmentMeta(row: Record<string, unknown>) {
return getSourceProtocolAttachment(row)
}
function protocolStatusLabelBySource(status: string, source: string, voidType?: string): string {
return source === 'research_donation'
? donationStatusDisplayLabel(status, voidType)
@@ -249,7 +265,9 @@
}
function protocolStatusTagTypeBySource(status: string, source: string): TagType {
return source === 'research_donation' ? donationStatusTagType(status) : protocolStatusTagType(status)
return source === 'research_donation'
? donationStatusTagType(status)
: protocolStatusTagType(status)
}
function parseEtaLocalDate(eta: unknown): Date | null {
@@ -429,6 +447,12 @@
font-variant-numeric: tabular-nums;
}
}
&--attachment {
dd {
margin-top: 2px;
}
}
}
.sample-reception-card__ops {
@@ -572,6 +572,83 @@
</el-form-item>
</div>
<!-- 传染病检测报告 -->
<div class="form-grid form-grid--attachment">
<el-form-item label="传染病检测报告">
<div
class="attachment-upload"
:class="{ 'is-dragover': isInfectiousReportAttachDragover }"
v-bind="infectiousReportAttachDropHandlers"
>
<div class="attachment-list">
<el-upload
ref="infectiousReportUploadRef"
:auto-upload="false"
:show-file-list="false"
:multiple="true"
@change="handleInfectiousReportAttachmentChange"
>
<div class="upload-card">
<el-icon :size="28" color="#047857"><Plus /></el-icon>
<span class="upload-card-text">上传附件</span>
</div>
</el-upload>
<div
v-for="(file, fIdx) in infectiousDiseaseReportAttachments"
:key="file.id || fIdx"
class="attachment-item"
:class="{ 'is-uploading': file._uploading }"
>
<div
class="attachment-preview"
@click="
isImageFile(file) && file.fileUrl ? handlePreviewAttachment(file) : undefined
"
>
<template v-if="isImageFile(file) && file.fileUrl">
<img :src="fullFileUrl(file.fileUrl)" :alt="file.fileName" />
</template>
<template v-else-if="isImageFile(file) && !file.fileUrl">
<el-icon :size="24" color="#94a3b8"><Loading /></el-icon>
</template>
<template v-else-if="isVideoFile(file)">
<div class="attachment-preview__icon attachment-preview__icon--video">
<el-icon :size="28"><VideoPlay /></el-icon>
</div>
</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>
<div class="attachment-actions">
<el-icon
class="action-btn"
title="下载"
@click="handleDownloadAttachment(file)"
><Download
/></el-icon>
<el-icon
class="action-btn action-btn--danger"
title="删除"
@click="removeInfectiousReportAttachment(fIdx)"
><Delete
/></el-icon>
</div>
</div>
</div>
</div>
<span class="upload-hint"
>支持拖拽或点击上传图片、视频、PDF、Word、Excel
等常见文件格式,可稍后补充,单文件不超过 20MB</span
>
</div>
</el-form-item>
</div>
<!-- 其他附件 -->
<div class="form-grid form-grid--attachment">
<el-form-item label="其他附件">
@@ -931,6 +1008,7 @@
samples: [] as Array<Record<string, any>>,
// Attachments
consentAttachments: [] as Array<AttachmentFileItem>,
infectiousDiseaseReportAttachments: [] as Array<AttachmentFileItem>,
otherAttachments: [] as Array<AttachmentFileItem>
})
@@ -975,6 +1053,7 @@
maternalBloodCollectTime: '',
samples: [],
consentAttachments: [],
infectiousDiseaseReportAttachments: [],
otherAttachments: []
})
customerId.value = null
@@ -1133,6 +1212,13 @@
if (consentAtt && consentAtt.length) {
formData.consentAttachments = consentAtt.map((a) => ({ ...a })) as any
}
const infectiousReportAtt = (donation?.infectiousDiseaseReportAttachmentFiles ??
(bundle as any).infectiousDiseaseReportAttachmentFiles) as Array<Record<string, any>> | null
if (infectiousReportAtt && infectiousReportAtt.length) {
formData.infectiousDiseaseReportAttachments = infectiousReportAtt.map((a) => ({
...a
})) as any
}
const otherAtt = (donation?.attachmentFiles ?? (bundle as any).attachmentFiles) as Array<
Record<string, any>
> | null
@@ -1275,6 +1361,16 @@
fileSizeDisplay: a.fileSizeDisplay,
fileType: a.fileType
})),
infectiousDiseaseReportAttachments: formData.infectiousDiseaseReportAttachments.map(
(a) => ({
id: a.id,
fileName: a.fileName,
fileUrl: a.fileUrl,
fileSize: a.fileSize,
fileSizeDisplay: a.fileSizeDisplay,
fileType: a.fileType
})
),
otherAttachments: formData.otherAttachments.map((a) => ({
id: a.id,
fileName: a.fileName,
@@ -2354,6 +2450,9 @@
/* ====== 知情同意书附件上传 ====== */
const consentUploadRef = ref()
const consentAttachments = computed(() => formData.consentAttachments)
const infectiousDiseaseReportAttachments = computed(
() => formData.infectiousDiseaseReportAttachments
)
const otherAttachments = computed(() => formData.otherAttachments)
async function handleConsentAttachmentChange(uploadFile: any) {
@@ -2406,6 +2505,61 @@
}
})
/* ====== 传染病检测报告附件上传 ====== */
const infectiousReportUploadRef = ref()
async function handleInfectiousReportAttachmentChange(uploadFile: any) {
const file = uploadFile.raw || uploadFile
if (!file) return
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
formData.infectiousDiseaseReportAttachments.push({
id: tempId,
fileName: file.name,
fileUrl: '',
fileSize: file.size,
fileSizeDisplay: `${(file.size / 1024).toFixed(1)} KB`,
fileType: file.type || '',
_uploading: true
})
const idx = formData.infectiousDiseaseReportAttachments.length - 1
try {
const fd = new FormData()
fd.append('folder', 'donation-infectious-disease-report')
fd.append('file', file)
const res = await fetchUploadAttachment(fd)
formData.infectiousDiseaseReportAttachments[idx] = {
...formData.infectiousDiseaseReportAttachments[idx],
id: res.id || tempId,
fileName: file.name || res.fileName,
fileUrl: res.fileUrl,
fileSize: res.fileSize || file.size,
fileSizeDisplay: res.fileSizeDisplay || `${(file.size / 1024).toFixed(1)} KB`,
fileType: res.fileType || file.type || '',
_uploading: false
}
} catch {
ElMessage.error('文件上传失败')
formData.infectiousDiseaseReportAttachments.splice(idx, 1)
} finally {
nextTick(() => infectiousReportUploadRef.value?.clearFiles())
}
}
function removeInfectiousReportAttachment(index: number) {
formData.infectiousDiseaseReportAttachments.splice(index, 1)
}
const {
isDragover: isInfectiousReportAttachDragover,
dropZoneHandlers: infectiousReportAttachDropHandlers
} = useAttachmentDropZone({
onFiles: (files) => {
for (const file of files) {
void handleInfectiousReportAttachmentChange({ raw: file })
}
}
})
/* ====== 其他附件上传 ====== */
const otherUploadRef = ref()
@@ -114,6 +114,15 @@
@download="downloadFile"
/>
</div>
<!-- 传染病检测报告 -->
<div v-if="infectiousDiseaseReportAttachmentFiles.length" class="attachment-row">
<div class="data-label">传染病检测报告</div>
<ProtocolAttachmentReadonly
:files="infectiousDiseaseReportAttachmentFiles"
@preview="openPreview"
@download="downloadFile"
/>
</div>
<!-- 其他附件 -->
<div v-if="otherAttachmentFiles.length" class="attachment-row">
<div class="data-label">其他附件</div>
@@ -652,6 +661,17 @@
.map((url: string) => ({ fileUrl: url, fileName: extractFileName(url) }))
})
const infectiousDiseaseReportAttachmentFiles = computed(() => {
const files = donation.value?.infectiousDiseaseReportAttachmentFiles
if (Array.isArray(files) && files.length) return files
const str = String(donation.value?.infectiousDiseaseReportUrls || '').trim()
if (!str) return []
return str
.split(',')
.filter(Boolean)
.map((url: string) => ({ fileUrl: url, fileName: extractFileName(url) }))
})
const otherAttachmentFiles = computed(() => {
const files = donation.value?.attachmentFiles
if (Array.isArray(files) && files.length) return files