feat: copy pre-transit sample views under production.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
b8a89a81f9
commit
dcf4f83ed0
2 files changed
+1706
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,284 @@
|
||||
<!-- 生产管理 — 预产及在途样本 -->
|
||||
<!-- eslint-disable vue/no-v-model-argument -->
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<section class="panel">
|
||||
<div class="panel-top">
|
||||
<h2>预产及在途样本</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>
|
||||
<el-form-item label="来源类型">
|
||||
<el-select
|
||||
v-model="searchForm.sourceType"
|
||||
placeholder="全部"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option label="细胞存储" value="cell_storage" />
|
||||
<el-option label="科研捐赠" value="research_donation" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker
|
||||
v-model="createTimeRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="样本采集时间">
|
||||
<el-date-picker
|
||||
v-model="sampleCollectTimeRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
/>
|
||||
</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="pre-transit-section">
|
||||
<div class="panel-top pre-transit-section-head">
|
||||
<h2 class="title-bar-heading">在途样本</h2>
|
||||
</div>
|
||||
<PreTransitProtocolCardList
|
||||
mode="in_transit"
|
||||
:rows="inTransitData"
|
||||
:loading="inTransitLoading"
|
||||
:pagination="inTransitPagination"
|
||||
empty-description="暂无在途样本"
|
||||
@view="handleView"
|
||||
@page-size-change="onInTransitPageSizeChange"
|
||||
@page-change="onInTransitPageChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pre-transit-section">
|
||||
<div class="panel-top pre-transit-section-head">
|
||||
<h2 class="title-bar-heading">预产样本</h2>
|
||||
</div>
|
||||
<PreTransitProtocolCardList
|
||||
mode="pre_delivery"
|
||||
:rows="preDeliveryData"
|
||||
:loading="preDeliveryLoading"
|
||||
:pagination="preDeliveryPagination"
|
||||
empty-description="暂无预产样本"
|
||||
@view="handleView"
|
||||
@page-size-change="onPreDeliveryPageSizeChange"
|
||||
@page-change="onPreDeliveryPageChange"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ProtocolViewDialog
|
||||
v-model="protocolViewVisible"
|
||||
:protocol-id="viewProtocolId"
|
||||
:list-row="protocolViewRow"
|
||||
/>
|
||||
<DonationViewDialog
|
||||
v-model="donationViewVisible"
|
||||
:donation-id="viewDonationId"
|
||||
:list-row="donationViewRow"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Search, RefreshLeft } from '@element-plus/icons-vue'
|
||||
import PreTransitProtocolCardList from './PreTransitProtocolCardList.vue'
|
||||
import ProtocolViewDialog from '@/views/cell-storage/protocol/ProtocolViewDialog.vue'
|
||||
import DonationViewDialog from '@/views/research-donation/list/DonationViewDialog.vue'
|
||||
import {
|
||||
fetchPreTransitInTransitList,
|
||||
fetchPreTransitPreDeliveryList,
|
||||
type PreTransitProtocolRow
|
||||
} from '@/api/pre-transit-sample'
|
||||
import type { CollectionProtocolRow } from '@/api/collection-protocol'
|
||||
import type { ResearchDonationRow } from '@/api/research-donation'
|
||||
|
||||
defineOptions({ name: 'ProductionPreTransitSample' })
|
||||
|
||||
const searchForm = reactive({ keyword: '', sourceType: '' })
|
||||
const createTimeRange = ref<[string, string] | null>(null)
|
||||
const sampleCollectTimeRange = ref<[string, string] | null>(null)
|
||||
|
||||
const inTransitData = ref<PreTransitProtocolRow[]>([])
|
||||
const preDeliveryData = ref<PreTransitProtocolRow[]>([])
|
||||
const inTransitLoading = ref(false)
|
||||
const preDeliveryLoading = ref(false)
|
||||
const inTransitPagination = reactive({ page: 1, pageSize: 10, total: 0 })
|
||||
const preDeliveryPagination = reactive({ page: 1, pageSize: 10, total: 0 })
|
||||
|
||||
const protocolViewVisible = ref(false)
|
||||
const donationViewVisible = ref(false)
|
||||
const viewProtocolId = ref<string | null>(null)
|
||||
const viewDonationId = ref<string | null>(null)
|
||||
const protocolViewRow = ref<CollectionProtocolRow | null>(null)
|
||||
const donationViewRow = ref<ResearchDonationRow | null>(null)
|
||||
|
||||
function listParams(page: number, pageSize: number) {
|
||||
return {
|
||||
page,
|
||||
pageSize,
|
||||
keyword: searchForm.keyword || undefined,
|
||||
sourceType: searchForm.sourceType || undefined,
|
||||
createTimeStart: createTimeRange.value?.[0] || undefined,
|
||||
createTimeEnd: createTimeRange.value?.[1] || undefined,
|
||||
sampleCollectTimeStart: sampleCollectTimeRange.value?.[0] || undefined,
|
||||
sampleCollectTimeEnd: sampleCollectTimeRange.value?.[1] || undefined
|
||||
}
|
||||
}
|
||||
|
||||
async function loadInTransit() {
|
||||
inTransitLoading.value = true
|
||||
try {
|
||||
const result = await fetchPreTransitInTransitList(
|
||||
listParams(inTransitPagination.page, inTransitPagination.pageSize)
|
||||
)
|
||||
const res = (result as Record<string, unknown>) || {}
|
||||
inTransitData.value = (res.list as PreTransitProtocolRow[]) || []
|
||||
inTransitPagination.total = Number(res.total) || 0
|
||||
} finally {
|
||||
inTransitLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPreDelivery() {
|
||||
preDeliveryLoading.value = true
|
||||
try {
|
||||
const result = await fetchPreTransitPreDeliveryList(
|
||||
listParams(preDeliveryPagination.page, preDeliveryPagination.pageSize)
|
||||
)
|
||||
const res = (result as Record<string, unknown>) || {}
|
||||
preDeliveryData.value = (res.list as PreTransitProtocolRow[]) || []
|
||||
preDeliveryPagination.total = Number(res.total) || 0
|
||||
} finally {
|
||||
preDeliveryLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function loadAll() {
|
||||
await Promise.all([loadInTransit(), loadPreDelivery()])
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
inTransitPagination.page = 1
|
||||
preDeliveryPagination.page = 1
|
||||
loadAll()
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
Object.assign(searchForm, { keyword: '', sourceType: '' })
|
||||
createTimeRange.value = null
|
||||
sampleCollectTimeRange.value = null
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
function onInTransitPageSizeChange(val: number) {
|
||||
inTransitPagination.page = 1
|
||||
inTransitPagination.pageSize = val
|
||||
loadInTransit()
|
||||
}
|
||||
|
||||
function onInTransitPageChange(val: number) {
|
||||
inTransitPagination.page = val
|
||||
loadInTransit()
|
||||
}
|
||||
|
||||
function onPreDeliveryPageSizeChange(val: number) {
|
||||
preDeliveryPagination.page = 1
|
||||
preDeliveryPagination.pageSize = val
|
||||
loadPreDelivery()
|
||||
}
|
||||
|
||||
function onPreDeliveryPageChange(val: number) {
|
||||
preDeliveryPagination.page = val
|
||||
loadPreDelivery()
|
||||
}
|
||||
|
||||
function handleView(row: PreTransitProtocolRow) {
|
||||
const source = String(row.sourceType || 'cell_storage')
|
||||
if (source === 'research_donation') {
|
||||
const did = String(row.researchDonationId || '')
|
||||
if (!did) {
|
||||
ElMessage.warning('缺少关联捐赠协议单,无法查看')
|
||||
return
|
||||
}
|
||||
viewDonationId.value = did
|
||||
donationViewRow.value = {
|
||||
id: did,
|
||||
motherName: row.motherName,
|
||||
newbornName: row.newbornName
|
||||
} as ResearchDonationRow
|
||||
donationViewVisible.value = true
|
||||
return
|
||||
}
|
||||
const pid = String(row.collectionProtocolId || row.id || '')
|
||||
if (!pid) {
|
||||
ElMessage.warning('缺少关联协议单,无法查看')
|
||||
return
|
||||
}
|
||||
viewProtocolId.value = pid
|
||||
protocolViewRow.value = {
|
||||
id: pid,
|
||||
motherName: row.motherName,
|
||||
newbornName: row.newbornName
|
||||
} as CollectionProtocolRow
|
||||
protocolViewVisible.value = true
|
||||
}
|
||||
|
||||
watchDebounced(
|
||||
[searchForm, createTimeRange, sampleCollectTimeRange],
|
||||
() => {
|
||||
inTransitPagination.page = 1
|
||||
preDeliveryPagination.page = 1
|
||||
loadAll()
|
||||
},
|
||||
{ debounce: 300, deep: true }
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
loadAll()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pre-transit-section-head {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.pre-transit-section + .pre-transit-section {
|
||||
margin-top: 24px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user