This commit is contained in:
zlwu committed 2026-05-24 11:03:15 +08:00
1 parent 93f5801aa9
commit 9dd7eb56ba
28 files changed
+3310 -2858

No files matched your search

@@ -0,0 +1,251 @@
<!-- 生产任务 — 只读查看(任务信息 + 产出细胞产品) -->
<!-- eslint-disable vue/no-v-model-argument -->
<template>
<SystemViewDialog
v-model:visible="innerVisible"
title="生产任务详情"
width="960px"
:grid-columns="3"
:icon="Operation"
:meta="viewDetail?.taskNo || ''"
:sections="viewSections"
:loading="loading"
append-to-body
compact
modal-class="production-task-view-dialog-mask"
>
<template #task-outputs>
<div v-if="viewOutputs.length" class="view-subtable-wrap">
<el-table :data="viewOutputs" stripe class="list-table view-subtable">
<el-table-column
type="index"
label="序号"
min-width="56"
align="center"
header-align="center"
:index="(index) => index + 1"
/>
<el-table-column
label="产品编码"
min-width="140"
align="center"
header-align="center"
show-overflow-tooltip
>
<template #default="{ row }">{{ row.productCode || row.outputBarcode || '—' }}</template>
</el-table-column>
<el-table-column
label="产品名称"
min-width="120"
align="center"
header-align="center"
show-overflow-tooltip
>
<template #default="{ row }">{{ row.productName || row.outputName || '—' }}</template>
</el-table-column>
<el-table-column label="产品类型" min-width="100" align="center" header-align="center">
<template #default="{ row }">{{ row.productTypeName || '—' }}</template>
</el-table-column>
<el-table-column label="规格" min-width="80" align="center" header-align="center">
<template #default="{ row }">{{ row.specName || '—' }}</template>
</el-table-column>
<el-table-column
prop="passage"
label="代次"
min-width="70"
align="center"
header-align="center"
/>
<el-table-column
prop="batchNo"
label="批次号"
min-width="110"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column label="储物格位置" min-width="160" align="center" header-align="center">
<template #default="{ row }">{{ row.storageSlotName || '—' }}</template>
</el-table-column>
<el-table-column label="预计细胞数量(亿)" min-width="130" align="center" header-align="center">
<template #default="{ row }">{{ row.expectedCellCount ?? '—' }}</template>
</el-table-column>
<el-table-column label="活性" min-width="80" align="center" header-align="center">
<template #default="{ row }">{{ row.viability != null ? row.viability : '—' }}</template>
</el-table-column>
<el-table-column label="冻存日期" min-width="110" align="center" header-align="center">
<template #default="{ row }">{{ formatDateOnly(row.freezeDate) }}</template>
</el-table-column>
<el-table-column label="有效期" min-width="110" align="center" header-align="center">
<template #default="{ row }">{{ formatDateOnly(row.expiryDate) }}</template>
</el-table-column>
<el-table-column label="数量" min-width="80" align="center" header-align="center">
<template #default="{ row }">{{ row.quantity ?? '—' }}</template>
</el-table-column>
<el-table-column prop="unit" label="单位" min-width="70" align="center" header-align="center" />
<el-table-column label="状态" min-width="90" align="center" header-align="center">
<template #default="{ row }">
<el-tag :type="productStatusTagType(row.productStatus)" size="small">
{{ productStatusLabel(row.productStatus) }}
</el-tag>
</template>
</el-table-column>
</el-table>
</div>
<p v-else class="view-empty-hint">暂无产出产品</p>
</template>
</SystemViewDialog>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { Operation } from '@element-plus/icons-vue'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import type { ViewSection } from '@/components/business/system-view-dialog/index.vue'
import { fetchProductionTaskDetail } from '@/api/production-task'
const props = defineProps<{
visible: boolean
taskId?: string
}>()
const emit = defineEmits<{
(e: 'update:visible', val: boolean): void
}>()
const innerVisible = computed({
get: () => props.visible,
set: (val) => emit('update:visible', val)
})
const loading = ref(false)
const viewDetail = ref<Record<string, any> | null>(null)
const TASK_STATUS_LABELS: Record<string, string> = {
dpz: '待配置',
dzx: '待执行',
jxz: '执行中',
ywc: '已完成'
}
const TASK_TYPE_LABELS: Record<string, string> = {
cell_storage: '入库生产单',
outbound: '出库生产单'
}
watch(
() => [props.visible, props.taskId] as const,
async ([vis, id]) => {
if (!vis || !id) {
viewDetail.value = null
return
}
loading.value = true
try {
viewDetail.value = await fetchProductionTaskDetail(id)
} catch {
viewDetail.value = null
} finally {
loading.value = false
}
},
{ immediate: true }
)
function taskStatusLabel(status?: string) {
return TASK_STATUS_LABELS[status || ''] || status || '—'
}
function taskStatusTagType(status?: string) {
if (status === 'ywc') return 'success' as const
if (status === 'jxz') return 'warning' as const
if (status === 'dzx') return 'info' as const
return 'info' as const
}
function taskTypeLabel(taskType?: string) {
return TASK_TYPE_LABELS[taskType || ''] || taskType || '—'
}
function taskTypeTagType(taskType?: string) {
if (taskType === 'cell_storage') return 'primary' as const
if (taskType === 'outbound') return 'warning' as const
return 'info' as const
}
function productStatusTagType(status?: string) {
const map: Record<string, 'success' | 'warning' | 'danger' | 'info'> = {
frozen: 'success',
in_production: 'warning',
voided: 'danger',
thawed: 'info'
}
return map[status || ''] || 'info'
}
function productStatusLabel(status?: string) {
const map: Record<string, string> = {
frozen: '已冻存',
in_production: '生产中',
voided: '已作废',
thawed: '已复苏'
}
return map[status || ''] || status || '—'
}
function formatDateOnly(val: unknown) {
if (!val) return '—'
const s = String(val)
return s.length >= 10 ? s.slice(0, 10) : s
}
const viewOutputs = computed(() => {
const rows = (viewDetail.value?.outputs as Array<Record<string, any>>) || []
return rows.map((row) => ({
...row,
productCode: row.productCode || row.outputBarcode || '',
productName: row.productName || row.outputName || ''
}))
})
const viewSections = computed<ViewSection[]>(() => {
const d = viewDetail.value
if (!d) return []
return [
{
title: '任务信息',
fields: [
{ label: '任务号', value: d.taskNo || '—' },
{ label: '任务名称', value: d.taskName || '—' },
{ label: '工单号', value: d.workOrderNo || '—' },
{
label: '任务类型',
value: taskTypeLabel(d.taskType),
tagType: taskTypeTagType(d.taskType)
},
{
label: '任务状态',
value: taskStatusLabel(d.taskStatus),
tagType: taskStatusTagType(d.taskStatus)
},
{ label: '协议号', value: d.protocolNo || '—' },
{ label: '样本编码', value: d.sampleCode || '—' },
{ label: '开始时间', value: d.startedTime || '—' },
{ label: '完成时间', value: d.completedTime || '—' },
{ label: '备注', value: d.remark || '—', span: true }
]
},
{
title: '产出(细胞产品)',
fields: [],
slot: 'task-outputs'
}
]
})
</script>
<style lang="scss">
.production-task-view-dialog-mask {
z-index: 4000 !important;
}
</style>
@@ -59,30 +59,11 @@
<span class="qc-kv__label">完成时间</span>
<span class="qc-kv__value">{{ task.completedTime || '—' }}</span>
</div>
<!-- 输入信息 -->
<div v-if="task.inputs?.length" class="production-task-card__io">
<div class="production-task-card__io-label">输入</div>
<div class="production-task-card__io-items">
<div v-for="(inp, idx) in task.inputs" :key="'in-' + idx" class="io-item">
<el-tag type="info" size="small" class="io-item__type">{{
inputTypeLabel(inp.inputType)
}}</el-tag>
<span class="io-item__name">{{ inp.inputName || inp.inputCode || '—' }}</span>
</div>
</div>
</div>
<!-- 输出信息 -->
<div v-if="task.outputs?.length" class="production-task-card__io">
<div class="production-task-card__io-label">输出</div>
<div class="production-task-card__io-items">
<div v-for="(out, idx) in task.outputs" :key="'out-' + idx" class="io-item">
<el-tag type="success" size="small" class="io-item__type">{{
outputTypeLabel(out.outputType)
}}</el-tag>
<span class="io-item__name">{{ out.outputName || out.outputCode || '—' }}</span>
</div>
</div>
</div>
</div>
<div class="production-task-card__foot">
<button type="button" class="production-task-card__link" @click.stop="openTaskView(task)">
点击查看详情
</button>
</div>
</div>
</div>
@@ -91,10 +72,17 @@
暂无生产任务
</div>
</template>
<Teleport to="body">
<ProductionTaskViewDialog v-model:visible="taskViewVisible" :task-id="taskViewId" />
</Teleport>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import ProductionTaskViewDialog from '@/components/business/production-task-view-dialog/index.vue'
export type ProductionTaskInput = {
inputType?: string
inputCode?: string
@@ -143,6 +131,15 @@
productionInfo?: ProductionInfo | null
}>()
const taskViewVisible = ref(false)
const taskViewId = ref('')
function openTaskView(task: ProductionTask) {
if (!task.id) return
taskViewId.value = task.id
taskViewVisible.value = true
}
function productionWorkOrderStatusLabel(status: string) {
return PRODUCTION_WORK_ORDER_STATUS_LABELS[status] || status || '—'
}
@@ -163,20 +160,6 @@
if (status === 'dzx') return 'info' as const
return 'info' as const
}
function inputTypeLabel(type?: string) {
if (type === 'sample') return '样本'
if (type === 'reagent') return '试剂'
if (type === 'consumable') return '耗材'
return type || '—'
}
function outputTypeLabel(type?: string) {
if (type === 'sample') return '样本'
if (type === 'cell_product') return '细胞产品'
if (type === 'other') return '其他'
return type || '—'
}
</script>
<style scoped lang="scss">
@@ -253,41 +236,24 @@
gap: 8px;
}
.production-task-card__io {
margin-top: 4px;
padding-top: 8px;
.production-task-card__foot {
padding: 2px 12px 8px;
text-align: right;
border-top: 1px dashed #f1f5f9;
}
.production-task-card__io-label {
.production-task-card__link {
padding: 0;
border: none;
background: none;
font-size: 11px;
font-weight: 600;
color: #94a3b8;
margin-bottom: 6px;
}
line-height: 1.4;
color: #10b981;
cursor: pointer;
.production-task-card__io-items {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.io-item {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
color: #475569;
.io-item__type {
flex-shrink: 0;
}
.io-item__name {
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&:hover {
color: #059669;
text-decoration: underline;
}
}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_production_info_cards_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue", "source_location": "L1"}, {"id": "sample_production_info_cards_index_productiontaskstatuslabel", "label": "productionTaskStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue", "source_location": "L153"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_production_info_cards_index_vue", "target": "sample_production_info_cards_index_productiontaskstatuslabel", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue", "source_location": "L153", "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_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_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_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_production_task_view_dialog_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L1"}, {"id": "production_task_view_dialog_index_taskstatuslabel", "label": "taskStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L155"}, {"id": "production_task_view_dialog_index_tasktypelabel", "label": "taskTypeLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L166"}, {"id": "production_task_view_dialog_index_productstatustagtype", "label": "productStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L176"}, {"id": "production_task_view_dialog_index_productstatuslabel", "label": "productStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L186"}, {"id": "production_task_view_dialog_index_formatdateonly", "label": "formatDateOnly()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L196"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_production_task_view_dialog_index_vue", "target": "production_task_view_dialog_index_taskstatuslabel", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L155", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_production_task_view_dialog_index_vue", "target": "production_task_view_dialog_index_tasktypelabel", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L166", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_production_task_view_dialog_index_vue", "target": "production_task_view_dialog_index_productstatustagtype", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L176", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_production_task_view_dialog_index_vue", "target": "production_task_view_dialog_index_productstatuslabel", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L186", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_production_task_view_dialog_index_vue", "target": "production_task_view_dialog_index_formatdateonly", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L196", "weight": 1.0}], "raw_calls": [{"caller_nid": "production_task_view_dialog_index_formatdateonly", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L198"}, {"caller_nid": "production_task_view_dialog_index_formatdateonly", "callee": "slice", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue", "source_location": "L199"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_production_info_cards_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue", "source_location": "L1"}, {"id": "sample_production_info_cards_index_productiontaskstatuslabel", "label": "productionTaskStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue", "source_location": "L160"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_production_info_cards_index_vue", "target": "sample_production_info_cards_index_productiontaskstatuslabel", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue", "source_location": "L160", "weight": 1.0}], "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": "L759"}, {"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": "L764"}, {"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": "L770"}, {"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": "L776"}, {"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": "L782"}, {"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": "L788"}, {"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": "L792"}, {"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"}, {"id": "list_donationviewdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L826"}], "edges": [{"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": "L584", "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": "L585", "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_cards_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": "L586", "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_production_info_cards_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": "L587", "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_storage_release_info_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDLine truncated
+1 -1
View File
@@ -109,7 +109,7 @@ export const transportTypeTagType = createTagTypeGetter(transportType)
export const receptionSource: StatusRegistry = {
cell_storage: { label: '细胞存储', tagType: 'primary' },
research_donation: { label: '科研捐赠', tagType: 'success' }
research_donation: { label: '科研捐赠', tagType: 'warning' }
}
export const receptionSourceLabel = createLabelGetter(receptionSource)
export const receptionSourceTagType = createTagTypeGetter(receptionSource)
@@ -478,6 +478,8 @@
<div v-else class="sample-reception-empty">暂未接收</div>
</div>
<SampleQcInfoCards :qc-info="row.qcInfo" :sample-reception="row.sampleReception" />
<SampleProductionInfoCards :production-info="row.productionInfo" />
<SampleStorageReleaseInfo :storage-release-info="row.storageReleaseInfo" />
</div>
</div>
</div>
@@ -582,6 +584,8 @@
import { Calendar, CircleCheck, Close, Document, User } from '@element-plus/icons-vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import SampleQcInfoCards from '@/components/business/sample-qc-info-cards/index.vue'
import SampleProductionInfoCards from '@/components/business/sample-production-info-cards/index.vue'
import SampleStorageReleaseInfo from '@/components/business/sample-storage-release-info/index.vue'
import {
fetchResearchDonationAuditList,
fetchResearchDonationDetail,