This commit is contained in:
zlwu committed 2026-05-20 20:41:47 +08:00
1 parent c6c3a37fa7
commit e6b4b9a8d7
28 files changed
+5812 -4687

No files matched your search

@@ -18,6 +18,22 @@
<el-form-item label="关键词">
<el-input v-model="searchForm.keyword" placeholder="协议号/备注" clearable />
</el-form-item>
<el-form-item label="下发对象">
<el-select
v-model="searchForm.issuedUserId"
placeholder="全部"
filterable
clearable
style="width: 100%"
>
<el-option
v-for="opt in userOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-select>
</el-form-item>
</div>
<div class="filter-actions-row">
<span class="filter-hint">模糊查询。</span>
@@ -39,6 +55,7 @@
新增协议号
</el-button>
<el-button class="btn-ghost" @click="openBatchGenerate">
<el-icon><DocumentAdd /></el-icon>
批量生成
</el-button>
<el-button
@@ -46,6 +63,7 @@
:disabled="selectedRows.length === 0"
@click="openBatchIssue"
>
<el-icon><Promotion /></el-icon>
批量下发
</el-button>
<el-button
@@ -53,6 +71,7 @@
:disabled="selectedRows.length === 0"
@click="handleBatchRevoke"
>
<el-icon><RefreshRight /></el-icon>
批量收回
</el-button>
<el-button
@@ -110,7 +129,7 @@
align="center"
header-align="center"
>
<template #default="{ row }">{{ row.issuedUserName || '-' }}</template>
<template #default="{ row }">{{ resolveIssuedUserName(row) }}</template>
</el-table-column>
<el-table-column
prop="issuedTime"
@@ -121,6 +140,16 @@
>
<template #default="{ row }">{{ row.issuedTime || '-' }}</template>
</el-table-column>
<el-table-column
prop="remark"
label="备注"
min-width="140"
align="center"
header-align="center"
show-overflow-tooltip
>
<template #default="{ row }">{{ row.remark || '-' }}</template>
</el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
@@ -314,7 +343,7 @@
inactive-text="否"
/>
</el-form-item>
<el-form-item v-if="formData.issued === 1" label="下发用户">
<el-form-item v-if="formData.issued === 1" label="下发用户" prop="issuedUserId">
<el-select
v-model="formData.issuedUserId"
placeholder="请选择用户"
@@ -363,7 +392,18 @@
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Close, Check, View, Tickets, RefreshLeft, Search } from '@element-plus/icons-vue'
import {
Plus,
Close,
Check,
View,
Tickets,
RefreshLeft,
Search,
DocumentAdd,
Promotion,
RefreshRight
} from '@element-plus/icons-vue'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import { withFullscreenLoading, fullscreenLoadingText } from '@/utils/fullscreen-loading'
import {
@@ -379,7 +419,10 @@
defineOptions({ name: 'BizCollectionProtocolNo' })
const searchForm = reactive<{ keyword: string }>({ keyword: '' })
const searchForm = reactive<{ keyword: string; issuedUserId: string }>({
keyword: '',
issuedUserId: ''
})
const tableData = ref<Api.BizCollectionProtocolNo.ProtocolNoItem[]>([])
const selectedRows = ref<Api.BizCollectionProtocolNo.ProtocolNoItem[]>([])
const loading = ref(false)
@@ -403,7 +446,7 @@
fields: [
{ label: '采集协议号', value: row.protocolNo },
{ label: '是否下发', value: row.issued === 1 ? '是' : '否' },
{ label: '下发对象', value: row.issuedUserName || '-' },
{ label: '下发对象', value: resolveIssuedUserName(row) },
{ label: '下发时间', value: row.issuedTime || '-' },
{ label: '创建时间', value: row.createTime },
{ label: '备注', value: row.remark, span: true }
@@ -458,6 +501,15 @@
}
const userOptions = ref<Array<{ label: string; value: string }>>([])
function resolveIssuedUserName(row: Api.BizCollectionProtocolNo.ProtocolNoItem): string {
const name = (row.issuedUserName || '').trim()
if (name) return name
const uid = (row.issuedUserId || '').trim()
if (!uid) return '-'
const opt = userOptions.value.find((u) => u.value === uid)
return (opt?.label || '').trim() || '-'
}
const formData = reactive({
protocolNo: '',
issued: 0,
@@ -469,7 +521,19 @@
})
const formRules = {
protocolNo: [{ required: true, message: '请输入采集协议号', trigger: 'blur' }]
protocolNo: [{ required: true, message: '请输入采集协议号', trigger: 'blur' }],
issuedUserId: [
{
validator: (_rule: unknown, value: string, callback: (err?: Error) => void) => {
if (formData.issued === 1 && !(value || '').trim()) {
callback(new Error('请选择下发用户'))
return
}
callback()
},
trigger: 'change'
}
]
}
const handleSelectionChange = (rows: Api.BizCollectionProtocolNo.ProtocolNoItem[]) => {
@@ -482,7 +546,8 @@
const res = await fetchCollectionProtocolNoList({
page: pagination.page,
pageSize: pagination.pageSize,
keyword: searchForm.keyword || undefined
keyword: searchForm.keyword || undefined,
issuedUserId: searchForm.issuedUserId || undefined
})
tableData.value = res.list || []
pagination.total = res.total ?? 0
@@ -498,6 +563,7 @@
function handleReset() {
searchForm.keyword = ''
searchForm.issuedUserId = ''
pagination.page = 1
loadData()
}
@@ -513,12 +579,13 @@
editingId.value = null
}
function handleAdd() {
async function handleAdd() {
isEdit.value = false
dialogTitle.value = '新增协议号'
resetForm()
dialogVisible.value = true
formRef.value?.clearValidate?.()
await loadUserOptions()
}
async function handleEdit(row: Api.BizCollectionProtocolNo.ProtocolNoItem) {
@@ -534,22 +601,25 @@
formData.remark = row.remark || ''
dialogVisible.value = true
formRef.value?.clearValidate?.()
if (!userOptions.value.length) {
try {
userOptions.value = await fetchUserOptions()
} catch { /* ignore */ }
}
await loadUserOptions()
}
async function handleSubmit() {
await formRef.value?.validate?.()
submitLoading.value = true
try {
const issueUserOpt =
formData.issued === 1
? userOptions.value.find((u) => u.value === formData.issuedUserId)
: undefined
const payload = {
protocolNo: formData.protocolNo.trim(),
issued: formData.issued,
issuedUserId: formData.issued === 1 ? formData.issuedUserId || undefined : null,
issuedUserName: formData.issued === 1 ? formData.issuedUserName || undefined : null,
issuedUserName:
formData.issued === 1
? (formData.issuedUserName || issueUserOpt?.label || '').trim() || undefined
: null,
issuedTime: formData.issuedTime || undefined,
orderNum: formData.orderNum,
remark: formData.remark?.trim() || undefined
@@ -642,12 +712,7 @@
if (!selectedRows.value.length) return
batchIssueForm.issuedUserId = ''
batchIssueVisible.value = true
// load user options
if (!userOptions.value.length) {
try {
userOptions.value = await fetchUserOptions()
} catch { /* ignore */ }
}
await loadUserOptions()
}
async function handleBatchIssue() {
@@ -669,7 +734,17 @@
}
}
onMounted(() => {
async function loadUserOptions() {
if (userOptions.value.length) return
try {
userOptions.value = await fetchUserOptions()
} catch {
/* ignore */
}
}
onMounted(async () => {
await loadUserOptions()
loadData()
})
</script>
@@ -75,18 +75,12 @@
align="center"
header-align="center"
/>
<el-table-column
prop="createTime"
label="创建时间"
min-width="180"
align="center"
header-align="center"
/>
<el-table-column
label="医院信息"
min-width="240"
align="center"
align="left"
header-align="center"
class-name="hospital-info-col"
>
<template #default="{ row }">
<template v-if="row.hospitalNames && row.hospitalNames.length">
@@ -101,6 +95,26 @@
<span v-else class="muted">—</span>
</template>
</el-table-column>
<el-table-column
prop="remark"
label="备注"
min-width="160"
align="center"
header-align="center"
show-overflow-tooltip
>
<template #default="{ row }">
<span v-if="row.remark">{{ row.remark }}</span>
<span v-else class="muted">—</span>
</template>
</el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
min-width="180"
align="center"
header-align="center"
/>
<el-table-column
label="操作"
width="400"
@@ -232,6 +246,19 @@
align="center"
header-align="center"
/>
<el-table-column
prop="remark"
label="备注"
min-width="160"
align="center"
header-align="center"
show-overflow-tooltip
>
<template #default="{ row }">
<span v-if="row.remark">{{ row.remark }}</span>
<span v-else class="muted">—</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="260"
@@ -550,6 +577,7 @@
currentRegionId.value = ''
currentRegionName.value = ''
hospitalTable.value = []
loadData()
}
function handleAddHospital() {
@@ -653,10 +681,17 @@
padding-top: 0;
}
:deep(.hospital-info-col .cell) {
white-space: normal;
line-height: 1.5;
}
.hospital-cell-line {
line-height: 1.8;
text-align: left;
padding-left: 8px;
}
.hospital-cell-line + .hospital-cell-line {
margin-top: 2px;
}
.muted {
@@ -280,7 +280,7 @@
const formData = reactive({
customerName: '',
sex: '2',
sex: '0',
idCardNo: '',
age: null as number | null,
phoneNo: '',
@@ -325,7 +325,7 @@
function resetForm() {
formData.customerName = ''
formData.sex = '2'
formData.sex = '0'
formData.idCardNo = ''
formData.age = null
formData.phoneNo = ''
@@ -18,6 +18,33 @@
<el-form-item label="关键词">
<el-input v-model="searchForm.keyword" placeholder="样本编码/备注" clearable />
</el-form-item>
<el-form-item label="编码类型">
<el-select
v-model="searchForm.sampleCodeType"
placeholder="全部"
clearable
style="width: 100%"
>
<el-option label="造血编码 (ZKZX)" value="zxbm" />
<el-option label="脐带编码 (ZKQD)" value="qdbm" />
</el-select>
</el-form-item>
<el-form-item label="下发对象">
<el-select
v-model="searchForm.issuedUserId"
placeholder="全部"
filterable
clearable
style="width: 100%"
>
<el-option
v-for="opt in userOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-select>
</el-form-item>
</div>
<div class="filter-actions-row">
<span class="filter-hint">模糊查询。</span>
@@ -39,6 +66,7 @@
新增样本编码
</el-button>
<el-button class="btn-ghost" @click="openBatchGenerate">
<el-icon><DocumentAdd /></el-icon>
批量生成
</el-button>
<el-button
@@ -46,6 +74,7 @@
:disabled="selectedRows.length === 0"
@click="openBatchIssue"
>
<el-icon><Promotion /></el-icon>
批量下发
</el-button>
<el-button
@@ -53,6 +82,7 @@
:disabled="selectedRows.length === 0"
@click="handleBatchRevoke"
>
<el-icon><RefreshRight /></el-icon>
批量收回
</el-button>
<el-button
@@ -130,6 +160,16 @@
>
<template #default="{ row }">{{ row.issuedTime || '-' }}</template>
</el-table-column>
<el-table-column
prop="remark"
label="备注"
min-width="120"
align="center"
header-align="center"
show-overflow-tooltip
>
<template #default="{ row }">{{ row.remark || '-' }}</template>
</el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
@@ -316,7 +356,17 @@
maxlength="32"
/>
</el-form-item>
<el-form-item v-if="isEdit" label="编码类型">
<el-form-item v-if="!isEdit" label="编码类型" prop="sampleCodeType">
<el-select
v-model="formData.sampleCodeType"
placeholder="请选择"
style="width: 100%"
>
<el-option label="造血编码 (ZKZX)" value="zxbm" />
<el-option label="脐带编码 (ZKQD)" value="qdbm" />
</el-select>
</el-form-item>
<el-form-item v-else label="编码类型">
<span class="text-sm text-gray-500">{{ sampleCodeTypeLabel(formData.sampleCodeType) }}</span>
</el-form-item>
<el-form-item label="是否下发">
@@ -329,7 +379,7 @@
inactive-text="否"
/>
</el-form-item>
<el-form-item v-if="formData.issued === 1" label="下发用户">
<el-form-item v-if="formData.issued === 1" label="下发用户" prop="issuedUserId">
<el-select
v-model="formData.issuedUserId"
placeholder="请选择用户"
@@ -378,7 +428,18 @@
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Close, Check, View, Ticket, RefreshLeft, Search } from '@element-plus/icons-vue'
import {
Plus,
Close,
Check,
View,
Ticket,
RefreshLeft,
Search,
DocumentAdd,
Promotion,
RefreshRight
} from '@element-plus/icons-vue'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import { withFullscreenLoading, fullscreenLoadingText } from '@/utils/fullscreen-loading'
import {
@@ -395,7 +456,11 @@
defineOptions({ name: 'BizSampleCode' })
const searchForm = reactive<{ keyword: string }>({ keyword: '' })
const searchForm = reactive<{ keyword: string; sampleCodeType: string; issuedUserId: string }>({
keyword: '',
sampleCodeType: '',
issuedUserId: ''
})
const tableData = ref<Api.BizSampleCode.SampleCodeItem[]>([])
const selectedRows = ref<Api.BizSampleCode.SampleCodeItem[]>([])
const loading = ref(false)
@@ -489,7 +554,20 @@
})
const formRules = {
sampleCode: [{ required: true, message: '请输入样本编码', trigger: 'blur' }]
sampleCode: [{ required: true, message: '请输入样本编码', trigger: 'blur' }],
sampleCodeType: [{ required: true, message: '请选择编码类型', trigger: 'change' }],
issuedUserId: [
{
validator: (_rule: unknown, value: string, callback: (err?: Error) => void) => {
if (formData.issued === 1 && !(value || '').trim()) {
callback(new Error('请选择下发用户'))
return
}
callback()
},
trigger: 'change'
}
]
}
const handleSelectionChange = (rows: Api.BizSampleCode.SampleCodeItem[]) => {
@@ -502,7 +580,9 @@
const res = await fetchSampleCodeList({
page: pagination.page,
pageSize: pagination.pageSize,
keyword: searchForm.keyword || undefined
keyword: searchForm.keyword || undefined,
sampleCodeType: searchForm.sampleCodeType || undefined,
issuedUserId: searchForm.issuedUserId || undefined
})
tableData.value = res.list || []
pagination.total = res.total ?? 0
@@ -518,13 +598,15 @@
function handleReset() {
searchForm.keyword = ''
searchForm.sampleCodeType = ''
searchForm.issuedUserId = ''
pagination.page = 1
loadData()
}
function resetForm() {
formData.sampleCode = ''
formData.sampleCodeType = ''
formData.sampleCodeType = 'zxbm'
formData.issued = 0
formData.issuedUserId = ''
formData.issuedUserName = ''
@@ -534,12 +616,22 @@
editingId.value = null
}
function handleAdd() {
async function loadUserOptions() {
if (userOptions.value.length) return
try {
userOptions.value = await fetchUserOptions()
} catch {
/* ignore */
}
}
async function handleAdd() {
isEdit.value = false
dialogTitle.value = '新增样本编码'
resetForm()
dialogVisible.value = true
formRef.value?.clearValidate?.()
await loadUserOptions()
}
async function handleEdit(row: Api.BizSampleCode.SampleCodeItem) {
@@ -556,22 +648,26 @@
formData.remark = row.remark || ''
dialogVisible.value = true
formRef.value?.clearValidate?.()
if (!userOptions.value.length) {
try {
userOptions.value = await fetchUserOptions()
} catch { /* ignore */ }
}
await loadUserOptions()
}
async function handleSubmit() {
await formRef.value?.validate?.()
submitLoading.value = true
try {
const issueUserOpt =
formData.issued === 1
? userOptions.value.find((u) => u.value === formData.issuedUserId)
: undefined
const payload = {
sampleCode: formData.sampleCode.trim(),
sampleCodeType: !isEdit.value ? formData.sampleCodeType || undefined : undefined,
issued: formData.issued,
issuedUserId: formData.issued === 1 ? formData.issuedUserId || undefined : null,
issuedUserName: formData.issued === 1 ? formData.issuedUserName || undefined : null,
issuedUserName:
formData.issued === 1
? (formData.issuedUserName || issueUserOpt?.label || '').trim() || undefined
: null,
issuedTime: formData.issuedTime || undefined,
orderNum: formData.orderNum,
remark: formData.remark?.trim() || undefined
@@ -664,11 +760,7 @@
if (!selectedRows.value.length) return
batchIssueForm.issuedUserId = ''
batchIssueVisible.value = true
if (!userOptions.value.length) {
try {
userOptions.value = await fetchUserOptions()
} catch { /* ignore */ }
}
await loadUserOptions()
}
async function handleBatchIssue() {
@@ -690,7 +782,8 @@
}
}
onMounted(() => {
onMounted(async () => {
await loadUserOptions()
loadData()
})
</script>