308 lines
11 KiB
Vue
308 lines
11 KiB
Vue
/**
|
|
* @file index.vue 批号管理
|
|
* @author: w
|
|
* @since: 2025-12-31
|
|
*/
|
|
<template>
|
|
<div class="app-container">
|
|
<div class="table-toolbar mb5">
|
|
<el-row>
|
|
<el-col :span="8">
|
|
<el-button type="primary" plain icon="Check" @click="handleSave">保存</el-button>
|
|
<el-button type="primary" @click="addHandle">新增</el-button>
|
|
<el-button type="danger">删除</el-button>
|
|
</el-col>
|
|
<el-col :span="16">
|
|
<span class="tips">靶值列表</span>
|
|
<el-button type="primary" plain @click="dateClick">复制第一个开始日期到每个项目</el-button>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
<el-row :gutter="10" class="table-row">
|
|
<el-col :span="8" class="table-col left-table">
|
|
<CustomVxeTable ref="leftTableRef" class="mytable-style" :table-data="tableData" :columns="columns"
|
|
:row-config="{ isHover: true, keyField: 'batchno' }"
|
|
:scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }">
|
|
<template #useflag="{ row }">
|
|
<el-checkbox :model-value="row.useflag == 1" readonly></el-checkbox>
|
|
</template>
|
|
</CustomVxeTable>
|
|
</el-col>
|
|
<el-col :span="16" class="table-col">
|
|
<div style="height:59%" class="mb8">
|
|
<CustomVxeTable ref="topTableRef" class="mytable-style" :table-data="topTableData" :columns="topColumns"
|
|
@current-change="rowClick" :row-config="{ isHover: true, keyField: 'xmdh' }"
|
|
:scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }">
|
|
<template #xmdh="{ row }">
|
|
{{ row.xmdh }} {{ row.xmmc }}
|
|
</template>
|
|
<template #zkbz="{ row }">
|
|
<el-input v-model="row.zkbz" class="full-width-input" />
|
|
</template>
|
|
<template #sd="{ row }">
|
|
<el-input v-model="row.sd" class="full-width-input" />
|
|
</template>
|
|
<template #cv="{ row }">
|
|
<el-input v-model="row.cv" class="full-width-input" />
|
|
</template>
|
|
<template #bc="{ row }">
|
|
<el-input v-model="row.bc" class="full-width-input" />
|
|
</template>
|
|
<template #ksrq="{ row }">
|
|
<el-date-picker v-model="row.ksrq" type="date" value-format="YYYY-MM-DD" class="full-width-input"
|
|
style="width:100%" />
|
|
</template>
|
|
<template #stopdate="{ row }">
|
|
<el-date-picker v-model="row.stopdate" type="date" value-format="YYYY-MM-DD" class="full-width-input"
|
|
style="width:100%" />
|
|
</template>
|
|
<template #ff="{ row }">
|
|
<el-select v-model="row.ff" placeholder="请选择" class="full-width-input">
|
|
<!-- <el-option /> -->
|
|
</el-select>
|
|
</template>
|
|
<template #sjph="{ row }">
|
|
<el-select v-model="row.sjph" placeholder="请选择" class="full-width-input">
|
|
<!-- <el-option /> -->
|
|
</el-select>
|
|
</template>
|
|
<template #qccv="{ row }">
|
|
<el-input v-model="row.qccv" class="full-width-input" />
|
|
</template>
|
|
</CustomVxeTable>
|
|
</div>
|
|
<div style="height:40%">
|
|
<CustomTable ref="rightTableRef" :data="bottomTableData" :columns="bottomColumns" :enableColumnDrag="true"
|
|
@column-drag-end="columnDragEnd" :config="{ border: true, highlightCurrentRow: true, height: '100%' }">
|
|
</CustomTable>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<el-dialog title="批号" v-model="visible" width="30vw" :close-on-click-modal="false" :draggable="true"
|
|
@close="handleDialogClose">
|
|
<el-form :model="formData" ref="queryRef" :rules="rules" label-position="right" label-width="auto">
|
|
<el-form-item label="仪器" prop="yq">
|
|
<span class="mr20"> {{ formData.yq }}</span>
|
|
<el-radio-group v-model="formData.useflag">
|
|
<el-radio value="1">在用</el-radio>
|
|
<el-radio value="0">停用</el-radio>
|
|
</el-radio-group>
|
|
|
|
</el-form-item>
|
|
<el-form-item label="质控批号" prop="zkpph">
|
|
<el-input v-model="formData.zkpph" />
|
|
</el-form-item>
|
|
<el-form-item label="水平" prop="zkph">
|
|
<el-select v-model="formData.zkph" placeholder="请选择">
|
|
<el-option />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="浓度" prop="conc">
|
|
<el-select v-model="formData.conc" placeholder="请选择">
|
|
<el-option />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="批号(瓶子上的)" prop="batchno">
|
|
<el-input v-model="formData.batchno" />
|
|
</el-form-item>
|
|
<el-form-item label="有效期" prop="expiredt">
|
|
<el-date-picker v-model="formData.expiredt" type="date" value-format="YYYY-MM-DD" />
|
|
</el-form-item>
|
|
<el-form-item label="启用日期" prop="ksrq">
|
|
<el-date-picker v-model="formData.ksrq" type="date" value-format="YYYY-MM-DD" />
|
|
</el-form-item>
|
|
<el-form-item label="结束日期" prop="endda">
|
|
<el-date-picker v-model="formData.endda" type="date" value-format="YYYY-MM-DD" />
|
|
</el-form-item>
|
|
<el-form-item label="质控厂商" prop="qcsrc">
|
|
<el-select v-model="formData.qcsrc" placeholder="请选择">
|
|
<el-option />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="校准品厂商" prop="standsrc">
|
|
<el-select v-model="formData.standsrc" placeholder="请选择">
|
|
<el-option />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="备注" prop="bk">
|
|
<el-input v-model="formData.bk" type="textarea" :row="5" />
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="visible = false">取消</el-button>
|
|
<el-button type="primary" @click="submit">确定</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { queryBatch, queryQcSample, queryBatchXm } from '@/api/liswork/qualityControl'
|
|
import { templateRef } from '@vueuse/core'
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
|
|
const yq = defineModel<string>()
|
|
const visible = ref(false)
|
|
const selectedRow = ref()
|
|
const queryRef = templateRef('queryRef')
|
|
const formData = ref({
|
|
yq: yq,
|
|
zkpph: '',
|
|
zkph: '',
|
|
conc: '',
|
|
useflag: '1',
|
|
batchno: '',
|
|
expiredt: '',
|
|
ksrq: '',
|
|
endda: '',
|
|
qcsrc: '',
|
|
standsrc: '',
|
|
bk: ''
|
|
})
|
|
const rules = ref({
|
|
zkpph: [{ required: true, message: '请输入质控批号', trigger: 'blur' }],
|
|
zkph: [{ required: true, message: '请选择水平', trigger: 'change' }],
|
|
ksrq: [{ required: true, message: '请选择启用日期', trigger: 'change' }],
|
|
})
|
|
const tableData = ref([])
|
|
const columns = ref([
|
|
{ title: '质控批号', field: 'zkpph', width: 80, resizable: true, align: 'center' },
|
|
{ title: '水平', field: 'zkph', resizable: true, align: 'center' },
|
|
{ title: '浓度', field: 'conc', resizable: true, align: 'center' },
|
|
{ title: '在用', field: 'useflag', resizable: true, align: 'center', slotName: 'useflag' },
|
|
{ title: '启用日期', field: 'ksrq', width: 90, resizable: true, align: 'center' },
|
|
{ title: '停用日期', field: 'endda', width: 90, resizable: true, align: 'center' },
|
|
{ title: '批号(瓶子上的)', field: 'batchno', resizable: true, align: 'center', width: 100 },
|
|
{ title: '有效期', field: 'expiredt', width: 90, resizable: true, align: 'center' },
|
|
{ title: '质控来源', field: 'qcsrc', width: 80, resizable: true, align: 'center' },
|
|
{ title: '校准品厂商', field: 'standsrc', width: 80, resizable: true, align: 'center' },
|
|
{ title: '备注', field: 'bk', resizable: true, align: 'center', width: 100 },
|
|
{ title: '仪器', field: 'yq', resizable: true, align: 'center', },
|
|
])
|
|
const topTableData: any = ref([])
|
|
const topColumns = [
|
|
{ title: '项目代号', field: 'xmdh', resizable: true, slotName: 'xmdh', width: 150 },
|
|
{ title: '靶值', field: 'zkbz', resizable: true, align: 'center', slotName: 'zkbz' },
|
|
{ title: 'Sd', field: 'sd', resizable: true, align: 'center', slotName: 'sd' },
|
|
{ title: 'Cv', field: 'cv', resizable: true, align: 'center', slotName: 'cv' },
|
|
{ title: '开始日期', field: 'ksrq', resizable: true, align: 'center', slotName: 'ksrq', width: 100 },
|
|
{ title: '结束日期', field: 'stopdate', resizable: true, align: 'center', slotName: 'stopdate', width: 100 },
|
|
{ title: '波长', field: 'bc', resizable: true, align: 'center', slotName: 'bc', },
|
|
{ title: '方法', field: 'ff', resizable: true, align: 'center', slotName: 'ff', },
|
|
{ title: '试剂', field: 'sjph', resizable: true, align: 'center', slotName: 'sjph', },
|
|
{ title: '目标CV(%)', field: 'qccv', resizable: true, align: 'center', slotName: 'qccv', width: 80 },
|
|
]
|
|
const bottomTableData = ref([])
|
|
const bottomColumns = ref([
|
|
{ label: '项目代号', prop: 'xmdh', visible: true, slot: 'xmdh', width: 150 },
|
|
{ label: '靶值', prop: 'zkbz', visible: true, align: 'center', },
|
|
{ label: 'Sd', prop: 'sd', visible: true, align: 'center', },
|
|
{ label: 'Cv', prop: 'cv', visible: true, align: 'center', },
|
|
{ label: '开始日期', prop: 'ksrq', visible: true, align: 'center', },
|
|
{ label: '结束日期', prop: 'stopdate', visible: true, align: 'center', },
|
|
{ label: '波长', prop: 'bc', visible: true, align: 'center', },
|
|
{ label: '方法', prop: 'ff', visible: true, align: 'center', },
|
|
{ label: '试剂', prop: 'sjph', visible: true, align: 'center', },
|
|
{ label: '目标CV(%)', prop: 'qccv', visible: true, align: 'center', },
|
|
])
|
|
|
|
const columnDragEnd = (data: any) => {
|
|
bottomColumns.value = data.columns
|
|
}
|
|
|
|
const rowClick = (row: any) => {
|
|
selectedRow.value = row
|
|
const data = {
|
|
xmdh: row.xmdh,
|
|
yq: yq.value,
|
|
}
|
|
queryQcSample(data).then((res: any) => {
|
|
bottomTableData.value = res.data
|
|
})
|
|
}
|
|
|
|
const dateClick = () => {
|
|
if (!topTableData.value[0].ksrq) return
|
|
topTableData.value.forEach((item: any) => {
|
|
item.ksrq = topTableData.value[0].ksrq
|
|
})
|
|
}
|
|
|
|
const addHandle = () => {
|
|
visible.value = true
|
|
}
|
|
|
|
const submit = () => {
|
|
queryRef.value.validate((valid: boolean) => {
|
|
if (!valid) return false;
|
|
})
|
|
}
|
|
|
|
const handleDialogClose = () => {
|
|
queryRef.value.resetFields()
|
|
formData.value = {
|
|
yq: yq,
|
|
zkpph: '',
|
|
zkph: '',
|
|
conc: '',
|
|
useflag: '1',
|
|
batchno: '',
|
|
expiredt: '',
|
|
ksrq: '',
|
|
endda: '',
|
|
qcsrc: '',
|
|
standsrc: '',
|
|
bk: ''
|
|
}
|
|
}
|
|
|
|
const getBatchList = () => {
|
|
queryBatch({ yq: yq.value, pageNum: 1, pageSize: 9999 }).then((res: any) => {
|
|
tableData.value = res.rows || []
|
|
})
|
|
}
|
|
const getXmList = () => {
|
|
queryBatchXm({ yq: yq.value, }).then((res: any) => {
|
|
topTableData.value = res.data
|
|
// rowClick(topTableData.value[0])
|
|
})
|
|
}
|
|
|
|
const handleSave = () => { }
|
|
|
|
watch(yq, (val) => {
|
|
if (val) {
|
|
getBatchList()
|
|
getXmList()
|
|
}
|
|
}, { immediate: true })
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.tips {
|
|
font-family: SourceHanSansCN, SourceHanSansCN;
|
|
font-size: 16px;
|
|
color: #409eff;
|
|
font-weight: 600;
|
|
height: 32px;
|
|
}
|
|
|
|
.table-row {
|
|
height: calc(100% - 105px);
|
|
|
|
.table-col {
|
|
height: 100%;
|
|
}
|
|
|
|
.left-table {
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
:deep(.el-input__prefix) {
|
|
display: none;
|
|
}
|
|
</style> |