Compare commits
4 Commits
c2898550f3
...
ad24b9e8d9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad24b9e8d9 | ||
|
|
0daeb17792 | ||
|
|
409d625a95 | ||
|
|
1e42410b9e |
30
src/api/liswork/germ/med.ts
Normal file
30
src/api/liswork/germ/med.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// 抗菌药物字典 xm_med
|
||||||
|
// @ts-ignore
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询药物列表(后端全量返回,不分页)
|
||||||
|
export function listMed(params) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMed/query',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增/修改药物(后端按 ywdh 存在即更新),入参为数组
|
||||||
|
export function addMed(data) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMed/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除药物
|
||||||
|
export function delMed(ywdh) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMed/del',
|
||||||
|
method: 'get',
|
||||||
|
params: { ywdh }
|
||||||
|
})
|
||||||
|
}
|
||||||
39
src/api/liswork/germ/medgroup.ts
Normal file
39
src/api/liswork/germ/medgroup.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// 常用抗生素组 xm_medgroup
|
||||||
|
// @ts-ignore
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询(不传条件返回全部明细,前端去重得到组名)
|
||||||
|
export function listMedgroup(params) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMedgroup/query',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增明细(无 @RequestBody,参数走 query)
|
||||||
|
export function addMedgroup(params) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMedgroup/add',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改明细(无 @RequestBody,参数走 query)
|
||||||
|
export function updateMedgroup(params) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMedgroup/update',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除明细
|
||||||
|
export function delMedgroup(params) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMedgroup/del',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
39
src/api/liswork/germ/medinter.ts
Normal file
39
src/api/liswork/germ/medinter.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// 抗生素通道号 xm_medinter
|
||||||
|
// @ts-ignore
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询某仪器的通道号列表
|
||||||
|
export function listMedinter(params) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMedinter/query',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增通道号
|
||||||
|
export function addMedinter(data) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMedinter/add',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改通道号(只改药物)
|
||||||
|
export function updateMedinter(data) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMedinter/update',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除通道号
|
||||||
|
export function delMedinter(params) {
|
||||||
|
return request({
|
||||||
|
url: '/xmMedinter/del',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
55
src/api/liswork/xtwh/AntibioticBreakpointApi.ts
Normal file
55
src/api/liswork/xtwh/AntibioticBreakpointApi.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// 抗生素折点范围字典 API
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 获取菌属列表(从 xm_meddetail 表)
|
||||||
|
export function getGermClassList(params?: any) {
|
||||||
|
return request({
|
||||||
|
url: '/xm/meddetail/germclass/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取抗生素字典列表(从 xm_med 表)
|
||||||
|
export function getAntibioticList(params?: any) {
|
||||||
|
return request({
|
||||||
|
url: '/xm/med/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取折点范围数据
|
||||||
|
export function getBreakpointList(params: any) {
|
||||||
|
return request({
|
||||||
|
url: '/xm/breakpoint/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存折点范围
|
||||||
|
export function saveBreakpoint(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/xm/breakpoint',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量保存折点范围
|
||||||
|
export function batchSaveBreakpoint(data: any[]) {
|
||||||
|
return request({
|
||||||
|
url: '/xm/breakpoint/batch',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除折点范围
|
||||||
|
export function deleteBreakpoint(id: number) {
|
||||||
|
return request({
|
||||||
|
url: `/xm/breakpoint/${id}`,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -222,6 +222,28 @@ export const dynamicRoutes = [{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
// ========== 抗生素折点范围字典 ==========
|
||||||
|
{
|
||||||
|
path: '/liswork/xtwh/antibioticBreakpoint',
|
||||||
|
component: Layout,
|
||||||
|
hidden: false,
|
||||||
|
permissions: ['liswork:xtwh:antibioticBreakpoint:list'],
|
||||||
|
meta: {
|
||||||
|
title: '抗生素折点范围字典',
|
||||||
|
icon: 'el-icon-menu'
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'AntibioticBreakpoint',
|
||||||
|
component: () => import('@/views/liswork/xtwh/antibioticBreakpoint/index'),
|
||||||
|
meta: {
|
||||||
|
title: '抗生素折点范围字典',
|
||||||
|
noCache: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
268
src/views/liswork/germ/group/index.vue
Normal file
268
src/views/liswork/germ/group/index.vue
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container med-group">
|
||||||
|
<el-row :gutter="12" class="main-row">
|
||||||
|
<!-- 左:药物组列表 -->
|
||||||
|
<el-col :span="6" class="left-col">
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-title">抗生素组名称</div>
|
||||||
|
<div class="left-toolbar">
|
||||||
|
<el-input v-model="newGroupName" size="small" placeholder="新组名称" style="width: 110px" />
|
||||||
|
<el-button type="primary" size="small" icon="Plus" @click="addGroup">新增组</el-button>
|
||||||
|
<el-button type="danger" size="small" icon="Delete" @click="delGroup">删除组</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table ref="groupTableRef" :data="groupList" height="100%" highlight-current-row
|
||||||
|
@current-change="onGroupChange">
|
||||||
|
<el-table-column prop="ywzmc" label="组名称" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span>{{ row.ywzmc }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 右:组信息 + 明细 -->
|
||||||
|
<el-col :span="18" class="right-col">
|
||||||
|
<div class="panel">
|
||||||
|
<el-form :inline="true" class="head-form">
|
||||||
|
<el-form-item label="抗生素组名称">
|
||||||
|
<el-input v-model="rightForm.ywzmc" :disabled="!isNewGroup" placeholder="组名称" style="width: 220px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="输入模式">
|
||||||
|
<el-radio-group v-model="rightForm.ismic">
|
||||||
|
<el-radio value="0">输入Rad</el-radio>
|
||||||
|
<el-radio value="1">输入Mic</el-radio>
|
||||||
|
<el-radio value="2">不输入</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="detail-toolbar">
|
||||||
|
<el-button type="primary" plain icon="Plus" size="small" @click="addDetail">新增药物</el-button>
|
||||||
|
<el-button type="danger" plain icon="Delete" size="small" @click="delDetail">删除药物</el-button>
|
||||||
|
<el-button type="success" plain icon="Check" size="small" @click="saveDetail">保存</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table ref="detailTableRef" :data="detailList" border height="100%" highlight-current-row
|
||||||
|
@row-click="onDetailRow">
|
||||||
|
<el-table-column label="抗生素" prop="ywdh" min-width="240">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<SelectTable v-model:data="row.ywdh" :tableData="medList" class="full-width-input" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="中介下限(Mic/Rad)" prop="zjmic" width="150" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-input-number v-model="row.zjmic" :precision="2" controls-position="right" class="num-input" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="中介上限(Mic/Rad)" prop="nymic" width="150" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-input-number v-model="row.nymic" :precision="2" controls-position="right" class="num-input" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" prop="bz" min-width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-input v-model="row.bz" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="序号" prop="xh" width="80" align="center" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="germMedGroup">
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { listMed } from '@/api/liswork/germ/med'
|
||||||
|
import { listMedgroup, addMedgroup, updateMedgroup, delMedgroup } from '@/api/liswork/germ/medgroup'
|
||||||
|
|
||||||
|
const groupTableRef = ref()
|
||||||
|
const detailTableRef = ref()
|
||||||
|
|
||||||
|
const newGroupName = ref('')
|
||||||
|
const isNewGroup = ref(false)
|
||||||
|
const groupList = ref([])
|
||||||
|
const detailList = ref([])
|
||||||
|
const medList = ref([])
|
||||||
|
const selectedDetail = ref(null)
|
||||||
|
|
||||||
|
const rightForm = reactive({
|
||||||
|
ywzmc: '',
|
||||||
|
ismic: '0'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 加载药物字典(下拉用)
|
||||||
|
const loadMedList = () => {
|
||||||
|
listMed({}).then(res => {
|
||||||
|
medList.value = (res.data || []).map(item => ({
|
||||||
|
label: `${item.ywmc}(${item.ywdh})`,
|
||||||
|
value: item.ywdh
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载左侧组列表(全量明细按组名去重)
|
||||||
|
const loadGroupList = () => {
|
||||||
|
listMedgroup({}).then(res => {
|
||||||
|
const rows = res.data || []
|
||||||
|
const map = {}
|
||||||
|
rows.forEach(r => { map[r.ywzmc] = true })
|
||||||
|
groupList.value = Object.keys(map).sort().map(k => ({ ywzmc: k }))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中某组 → 加载明细
|
||||||
|
const onGroupChange = (row) => {
|
||||||
|
if (!row) return
|
||||||
|
isNewGroup.value = false
|
||||||
|
rightForm.ywzmc = row.ywzmc
|
||||||
|
listMedgroup({ ywzmc: row.ywzmc }).then(res => {
|
||||||
|
const rows = res.data || []
|
||||||
|
detailList.value = rows.map(r => ({ ...r, _isNew: false }))
|
||||||
|
// ismic 取该组第一行
|
||||||
|
if (rows.length) rightForm.ismic = rows[0].ismic || '0'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增组
|
||||||
|
const addGroup = () => {
|
||||||
|
const name = newGroupName.value.trim()
|
||||||
|
if (!name) return ElMessage.warning('请输入新组名称')
|
||||||
|
if (groupList.value.some(g => g.ywzmc === name)) return ElMessage.warning('该组已存在')
|
||||||
|
newGroupName.value = ''
|
||||||
|
isNewGroup.value = true
|
||||||
|
rightForm.ywzmc = name
|
||||||
|
rightForm.ismic = '0'
|
||||||
|
detailList.value = []
|
||||||
|
groupTableRef.value?.setCurrentRow(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除组(删除该组全部明细)
|
||||||
|
const delGroup = () => {
|
||||||
|
const name = rightForm.ywzmc
|
||||||
|
if (!name) return ElMessage.warning('请先选择要删除的组')
|
||||||
|
ElMessageBox.confirm(`确认删除组"${name}"及其全部药物?`, '提示', { type: 'warning' }).then(() => {
|
||||||
|
const rows = detailList.value.filter(r => !r._isNew)
|
||||||
|
const tasks = rows.map(r => delMedgroup({ ywzmc: r.ywzmc, xh: r.xh }))
|
||||||
|
Promise.all(tasks).then(() => {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
rightForm.ywzmc = ''
|
||||||
|
detailList.value = []
|
||||||
|
loadGroupList()
|
||||||
|
})
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增明细行
|
||||||
|
const addDetail = () => {
|
||||||
|
if (!rightForm.ywzmc) return ElMessage.warning('请先选择或新建组')
|
||||||
|
const maxXh = detailList.value.reduce((m, r) => Math.max(m, Number(r.xh) || 0), 0)
|
||||||
|
detailList.value.push({
|
||||||
|
ywzmc: rightForm.ywzmc,
|
||||||
|
xh: maxXh + 10,
|
||||||
|
ywdh: '',
|
||||||
|
bz: '',
|
||||||
|
zjmic: null,
|
||||||
|
nymic: null,
|
||||||
|
ismic: rightForm.ismic,
|
||||||
|
_isNew: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDetailRow = (row) => { selectedDetail.value = row }
|
||||||
|
|
||||||
|
const delDetail = () => {
|
||||||
|
if (!selectedDetail.value) return ElMessage.error('请先选择要删除的行')
|
||||||
|
const row = selectedDetail.value
|
||||||
|
const doDel = () => {
|
||||||
|
if (row._isNew) {
|
||||||
|
detailList.value = detailList.value.filter(r => r !== row)
|
||||||
|
selectedDetail.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
delMedgroup({ ywzmc: row.ywzmc, xh: row.xh }).then(() => {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
detailList.value = detailList.value.filter(r => r !== row)
|
||||||
|
selectedDetail.value = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
doDel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存:明细逐行 add/update;ismic 同步到每行
|
||||||
|
const saveDetail = () => {
|
||||||
|
if (!rightForm.ywzmc) return ElMessage.warning('请先选择或新建组')
|
||||||
|
for (let i = 0; i < detailList.value.length; i++) {
|
||||||
|
const r = detailList.value[i]
|
||||||
|
if (!r.ywdh) return ElMessage.error(`第${i + 1}行请选择抗生素`)
|
||||||
|
}
|
||||||
|
const tasks = detailList.value.map(r => {
|
||||||
|
const payload = {
|
||||||
|
ywzmc: rightForm.ywzmc,
|
||||||
|
xh: r.xh,
|
||||||
|
ywdh: r.ywdh,
|
||||||
|
bz: r.bz || '',
|
||||||
|
zjmic: r.zjmic,
|
||||||
|
nymic: r.nymic,
|
||||||
|
ismic: rightForm.ismic
|
||||||
|
}
|
||||||
|
return r._isNew ? addMedgroup(payload) : updateMedgroup(payload)
|
||||||
|
})
|
||||||
|
Promise.all(tasks).then(() => {
|
||||||
|
ElMessage.success('保存成功')
|
||||||
|
loadGroupList()
|
||||||
|
// 重新拉取明细
|
||||||
|
listMedgroup({ ywzmc: rightForm.ywzmc }).then(res => {
|
||||||
|
detailList.value = (res.data || []).map(r => ({ ...r, _isNew: false }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMedList()
|
||||||
|
loadGroupList()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.med-group {
|
||||||
|
height: calc(100vh - 120px);
|
||||||
|
}
|
||||||
|
.main-row {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.left-col, .right-col {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.panel {
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.panel-title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
.left-toolbar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.head-form {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.detail-toolbar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.num-input {
|
||||||
|
width: 130px;
|
||||||
|
}
|
||||||
|
.full-width-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
342
src/views/liswork/germ/med/index.vue
Normal file
342
src/views/liswork/germ/med/index.vue
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 查询条件 -->
|
||||||
|
<el-form :model="queryParams" ref="queryRef" inline v-show="showSearch" class="query-form">
|
||||||
|
<el-form-item label="药物代码" prop="ywdh">
|
||||||
|
<el-input v-model="queryParams.ywdh" placeholder="请输入药物代码" clearable style="width: 180px"
|
||||||
|
@keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="药物名称" prop="ywmc">
|
||||||
|
<el-input v-model="queryParams.ywmc" placeholder="请输入药物名称" clearable style="width: 180px"
|
||||||
|
@keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="助记符" prop="zjf">
|
||||||
|
<el-input v-model="queryParams.zjf" placeholder="简拼检索" clearable style="width: 180px"
|
||||||
|
@keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="mb5">
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
<el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||||
|
<el-button type="info" plain icon="Edit" :disabled="single" @click="handleUpdate">修改</el-button>
|
||||||
|
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-container">
|
||||||
|
<el-table v-loading="loading" :data="pageList" border height="100%"
|
||||||
|
@selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
|
<el-table-column label="药物代码" align="center" prop="ywdh" width="90" show-overflow-tooltip />
|
||||||
|
<el-table-column label="药物名称" align="left" prop="ywmc" min-width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column label="简码" align="center" prop="medno" width="90" show-overflow-tooltip />
|
||||||
|
<el-table-column label="英文代码" align="center" prop="yydh" width="110" show-overflow-tooltip />
|
||||||
|
<el-table-column label="助记符" align="center" prop="zjf" width="90" show-overflow-tooltip />
|
||||||
|
<el-table-column label="用法1" align="center" prop="yf" width="90" show-overflow-tooltip />
|
||||||
|
<el-table-column label="用法2" align="center" prop="yfim" width="90" show-overflow-tooltip />
|
||||||
|
<el-table-column label="用法3" align="center" prop="yfiv" width="90" show-overflow-tooltip />
|
||||||
|
<el-table-column label="中介下限" align="center" prop="zjmic" width="80" />
|
||||||
|
<el-table-column label="中介上限" align="center" prop="nymic" width="80" />
|
||||||
|
<el-table-column label="血药浓度" align="center" prop="xyfz" width="90" show-overflow-tooltip />
|
||||||
|
<el-table-column label="尿药浓度" align="center" prop="nyfz" width="90" show-overflow-tooltip />
|
||||||
|
<el-table-column label="序号" align="center" prop="seq" width="60" />
|
||||||
|
<el-table-column label="Whonet" align="center" prop="whonet" width="100" show-overflow-tooltip />
|
||||||
|
<el-table-column label="备注" align="left" prop="bz" min-width="120" show-overflow-tooltip />
|
||||||
|
<el-table-column label="操作" width="130" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||||
|
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||||
|
|
||||||
|
<!-- 新增/修改对话框 -->
|
||||||
|
<el-dialog :title="title" v-model="open" width="780px" append-to-body>
|
||||||
|
<el-form ref="medRef" :model="form" :rules="rules" label-width="100px">
|
||||||
|
<el-divider content-position="left">基本信息</el-divider>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="药物代码" prop="ywdh">
|
||||||
|
<el-input v-model="form.ywdh" placeholder="主键" :disabled="isEdit" maxlength="20" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="药物名称" prop="ywmc">
|
||||||
|
<el-input v-model="form.ywmc" placeholder="请输入名称" maxlength="50" @input="autoPinyin" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="助记符" prop="zjf">
|
||||||
|
<el-input v-model="form.zjf" placeholder="按名称自动生成" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="简码" prop="medno">
|
||||||
|
<el-input v-model="form.medno" placeholder="medno" maxlength="20" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="英文代码" prop="yydh">
|
||||||
|
<el-input v-model="form.yydh" placeholder="yydh" maxlength="30" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="序号" prop="seq">
|
||||||
|
<el-input-number v-model="form.seq" controls-position="right" :min="0" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-divider content-position="left">用法 / 浓度</el-divider>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="用法1" prop="yf">
|
||||||
|
<el-input v-model="form.yf" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="用法2" prop="yfim">
|
||||||
|
<el-input v-model="form.yfim" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="用法3" prop="yfiv">
|
||||||
|
<el-input v-model="form.yfiv" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="血药浓度" prop="xyfz">
|
||||||
|
<el-input v-model="form.xyfz" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="尿药浓度" prop="nyfz">
|
||||||
|
<el-input v-model="form.nyfz" maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-divider content-position="left">药敏阈值</el-divider>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="中介下限" prop="zjmic">
|
||||||
|
<el-input-number v-model="form.zjmic" :precision="2" controls-position="right" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="中介上限" prop="nymic">
|
||||||
|
<el-input-number v-model="form.nymic" :precision="2" controls-position="right" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="抑菌圈下限" prop="zjkb">
|
||||||
|
<el-input-number v-model="form.zjkb" :precision="2" controls-position="right" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="抑菌圈上限" prop="nykb">
|
||||||
|
<el-input-number v-model="form.nykb" :precision="2" controls-position="right" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="Etest下限" prop="zjetest">
|
||||||
|
<el-input-number v-model="form.zjetest" :precision="2" controls-position="right" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="Etest上限" prop="nyetest">
|
||||||
|
<el-input-number v-model="form.nyetest" :precision="2" controls-position="right" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="多MIC" prop="multimic">
|
||||||
|
<el-input v-model="form.multimic" maxlength="1" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="IKB" prop="ikb">
|
||||||
|
<el-input v-model="form.ikb" maxlength="20" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-divider content-position="left">Whonet</el-divider>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="Whonet" prop="whonet">
|
||||||
|
<el-input v-model="form.whonet" maxlength="20" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="WhonetMic" prop="whonet_mic">
|
||||||
|
<el-input v-model="form.whonet_mic" maxlength="20" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="WhonetKb" prop="whonet_kb">
|
||||||
|
<el-input v-model="form.whonet_kb" maxlength="20" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="WhonetEtest" prop="whonet_etest">
|
||||||
|
<el-input v-model="form.whonet_etest" maxlength="20" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-form-item label="备注" prop="bz">
|
||||||
|
<el-input v-model="form.bz" type="textarea" :rows="2" maxlength="255" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="germMed">
|
||||||
|
import { pinyin } from 'pinyin-pro'
|
||||||
|
import { listMed, addMed, delMed } from '@/api/liswork/germ/med'
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
const open = ref(false)
|
||||||
|
const showSearch = ref(true)
|
||||||
|
const single = ref(true)
|
||||||
|
const multiple = ref(true)
|
||||||
|
const title = ref('')
|
||||||
|
const isEdit = ref(false)
|
||||||
|
const total = ref(0)
|
||||||
|
const allList = ref([])
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: {},
|
||||||
|
queryParams: {
|
||||||
|
ywdh: undefined,
|
||||||
|
ywmc: undefined,
|
||||||
|
zjf: undefined,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 30
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
ywdh: [{ required: true, message: '药物代码不能为空', trigger: 'blur' }],
|
||||||
|
ywmc: [{ required: true, message: '药物名称不能为空', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const { queryParams, form, rules } = toRefs(data)
|
||||||
|
|
||||||
|
// 前端分页切片
|
||||||
|
const pageList = computed(() => {
|
||||||
|
const start = (queryParams.value.pageNum - 1) * queryParams.value.pageSize
|
||||||
|
return allList.value.slice(start, start + queryParams.value.pageSize)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 名称变更自动生成首拼助记符(后端保存时也会再生成一次)
|
||||||
|
function autoPinyin() {
|
||||||
|
if (!form.value.ywmc) {
|
||||||
|
form.value.zjf = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
form.value.zjf = pinyin(form.value.ywmc, { pattern: 'first', toneType: 'none', type: 'array' }).join('').toUpperCase()
|
||||||
|
} catch (e) {
|
||||||
|
form.value.zjf = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getList() {
|
||||||
|
loading.value = true
|
||||||
|
listMed(queryParams.value).then(res => {
|
||||||
|
allList.value = res.data || []
|
||||||
|
total.value = allList.value.length
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancel() {
|
||||||
|
open.value = false
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
ywdh: undefined, ywmc: undefined, medno: undefined, yydh: undefined, zjf: undefined,
|
||||||
|
seq: 0, yf: undefined, yfim: undefined, yfiv: undefined, xyfz: undefined, nyfz: undefined,
|
||||||
|
zjmic: undefined, nymic: undefined, zjkb: undefined, nykb: undefined,
|
||||||
|
zjetest: undefined, nyetest: undefined, multimic: undefined, ikb: undefined,
|
||||||
|
whonet: undefined, whonet_mic: undefined, whonet_kb: undefined, whonet_etest: undefined,
|
||||||
|
bz: undefined
|
||||||
|
}
|
||||||
|
proxy.resetForm('medRef')
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetQuery() {
|
||||||
|
proxy.resetForm('queryRef')
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSelectionChange(selection) {
|
||||||
|
single.value = selection.length !== 1
|
||||||
|
multiple.value = !selection.length
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAdd() {
|
||||||
|
reset()
|
||||||
|
isEdit.value = false
|
||||||
|
open.value = true
|
||||||
|
title.value = '新增抗菌药物'
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleUpdate(row) {
|
||||||
|
reset()
|
||||||
|
isEdit.value = true
|
||||||
|
form.value = { ...row }
|
||||||
|
open.value = true
|
||||||
|
title.value = '修改抗菌药物'
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitForm() {
|
||||||
|
proxy.$refs['medRef'].validate(valid => {
|
||||||
|
if (!valid) return
|
||||||
|
// 后端入参为数组,按 ywdh 存在即更新
|
||||||
|
addMed([form.value]).then(() => {
|
||||||
|
proxy.$modal.msgSuccess(isEdit.value ? '修改成功' : '新增成功')
|
||||||
|
open.value = false
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete(row) {
|
||||||
|
const ywdh = row.ywdh
|
||||||
|
proxy.$modal.confirm('是否确认删除药物"' + ywdh + '"?').then(() => {
|
||||||
|
return delMed(ywdh)
|
||||||
|
}).then(() => {
|
||||||
|
getList()
|
||||||
|
proxy.$modal.msgSuccess('删除成功')
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
getList()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.table-container {
|
||||||
|
height: calc(100% - 150px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
549
src/views/liswork/xtwh/antibioticBreakpoint/index.vue
Normal file
549
src/views/liswork/xtwh/antibioticBreakpoint/index.vue
Normal file
@ -0,0 +1,549 @@
|
|||||||
|
/**
|
||||||
|
* @file index.vue 抗生素折点范围字典
|
||||||
|
* @author: w
|
||||||
|
* @since: 2026-09-16
|
||||||
|
*/
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<div class="unified-panel">
|
||||||
|
<div class="btn-bar">
|
||||||
|
<el-button type="primary" icon="Search" @click="search">查询</el-button>
|
||||||
|
<el-button type="primary" icon="Check" @click="saveBreakpoints">保存</el-button>
|
||||||
|
<el-button type="warning" icon="Refresh" @click="reset">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-container">
|
||||||
|
<!-- 左栏:菌属树 -->
|
||||||
|
<div class="panel left-panel">
|
||||||
|
<div class="panel-header">菌属</div>
|
||||||
|
<div class="panel-content">
|
||||||
|
<el-input v-model="treeFilter" placeholder="搜索菌属" size="small" clearable style="padding: 4px;" />
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="germClassTree"
|
||||||
|
:props="{ label: 'label', children: 'children' }"
|
||||||
|
node-key="zddh"
|
||||||
|
highlight-current
|
||||||
|
default-expand-all
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
@node-click="handleTreeNodeClick"
|
||||||
|
>
|
||||||
|
<template #default="{ node, data }">
|
||||||
|
<span class="tree-node">
|
||||||
|
<span class="tree-code">{{ data.zddh }}</span>
|
||||||
|
<span class="tree-name">{{ data.zdmc }}</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 中栏:折点范围编辑 -->
|
||||||
|
<div class="panel middle-panel">
|
||||||
|
<div class="panel-header">折点范围编辑</div>
|
||||||
|
<div class="panel-content">
|
||||||
|
<el-table
|
||||||
|
:data="breakpointList"
|
||||||
|
border
|
||||||
|
size="mini"
|
||||||
|
height="100%"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column prop="ywdh" label="药物代号" width="90" fixed />
|
||||||
|
<el-table-column label="抗生素" width="130" fixed show-overflow-tooltip>
|
||||||
|
<template #default="scope">{{ getMedName(scope.row.ywdh) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="S(MIC<=)" width="75">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input v-model="scope.row.mic1" size="small" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="R(MIC>=)" width="75">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input v-model="scope.row.mic2" size="small" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="micref" label="MIC折点" width="130" show-overflow-tooltip />
|
||||||
|
<el-table-column label="S(KB>=)" width="75">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input v-model="scope.row.rad1" size="small" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="R(KB<=)" width="75">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input v-model="scope.row.rad2" size="small" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="radref" label="KB折点" width="130" show-overflow-tooltip />
|
||||||
|
<el-table-column label="I=SDD" width="45" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-checkbox v-model="scope.row.sddfalg" :true-value="1" :false-value="null" class="sdd-checkbox" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="xh" label="序号" width="55" />
|
||||||
|
<el-table-column label="操作" width="65" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="danger" link size="small" @click="removeBreakpoint(scope.$index)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右栏:抗生素字典 -->
|
||||||
|
<div class="panel right-panel">
|
||||||
|
<div class="panel-header">抗生素字典</div>
|
||||||
|
<div class="panel-content right-content">
|
||||||
|
<el-input v-model="antibioticFilter" placeholder="搜索抗生素" size="small" clearable style="padding: 4px;" />
|
||||||
|
<el-table
|
||||||
|
:data="filteredAntibioticList"
|
||||||
|
border
|
||||||
|
size="mini"
|
||||||
|
height="100%"
|
||||||
|
style="width: 100%"
|
||||||
|
@row-dblclick="handleAddBreakpoint"
|
||||||
|
>
|
||||||
|
<el-table-column prop="ywdh" label="代号" width="85" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="ywmc" label="药物名称" width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="zjf" label="简码" width="70" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="yydh" label="英文代码" width="130" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="zjmic" label="中介MIC" width="90" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="nymic" label="尿MIC" width="85" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="multimic" label="多级参数" width="75" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="yf" label="用法" width="80" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="xyfz" label="血药浓度" width="80" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="seq" label="序号" width="55" show-overflow-tooltip />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, computed, watch } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import {
|
||||||
|
getGermClassList,
|
||||||
|
getAntibioticList,
|
||||||
|
getBreakpointList,
|
||||||
|
batchSaveBreakpoint
|
||||||
|
} from '@/api/liswork/xtwh/AntibioticBreakpointApi'
|
||||||
|
|
||||||
|
const treeRef = ref(null)
|
||||||
|
const treeFilter = ref('')
|
||||||
|
const antibioticFilter = ref('')
|
||||||
|
const germClassList = ref([])
|
||||||
|
const antibioticList = ref([])
|
||||||
|
const breakpointList = ref([])
|
||||||
|
const currentGermClass = ref(null)
|
||||||
|
const loading = ref(false)
|
||||||
|
let rowWatchers = []
|
||||||
|
|
||||||
|
const germClassTree = computed(() => {
|
||||||
|
return germClassList.value.map(item => ({
|
||||||
|
...item,
|
||||||
|
label: `${item.zddh} ${item.zdmc}`
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
const getMedName = (ywdh) => {
|
||||||
|
return antibioticList.value.find(m => m.ywdh === ywdh)?.ywmc || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const filteredAntibioticList = computed(() => {
|
||||||
|
const kw = antibioticFilter.value.trim().toLowerCase()
|
||||||
|
if (!kw) return antibioticList.value
|
||||||
|
return antibioticList.value.filter(m =>
|
||||||
|
m.ywmc?.toLowerCase().includes(kw) ||
|
||||||
|
m.ywdh?.toLowerCase().includes(kw) ||
|
||||||
|
m.zjf?.toLowerCase().includes(kw) ||
|
||||||
|
m.yydh?.toLowerCase().includes(kw)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const calcMicRef = (mic1, mic2) => {
|
||||||
|
const s = mic1 != null && mic1 !== '' ? Number(mic1) : null
|
||||||
|
const r = mic2 != null && mic2 !== '' ? Number(mic2) : null
|
||||||
|
if (s == null && r == null) return ''
|
||||||
|
if (s != null && r != null) {
|
||||||
|
const mid = buildMicMiddle(s, r)
|
||||||
|
return `<=${s}${mid ? ', ' + mid : ''}, >=${r}`
|
||||||
|
}
|
||||||
|
return s != null ? `<=${s}` : `>=${r}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const calcRadRef = (rad1, rad2) => {
|
||||||
|
const s = rad1 != null && rad1 !== '' ? Number(rad1) : null
|
||||||
|
const r = rad2 != null && rad2 !== '' ? Number(rad2) : null
|
||||||
|
if (s == null && r == null) return ''
|
||||||
|
if (s != null && r != null) {
|
||||||
|
const mid = buildRadMiddle(s, r)
|
||||||
|
return `>=${r}${mid ? ', ' + mid : ''}, <=${s}`
|
||||||
|
}
|
||||||
|
return r != null ? `>=${r}` : `<=${s}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildMicMiddle = (s, r) => {
|
||||||
|
if (r - s <= 1) return ''
|
||||||
|
if (Number.isInteger(s) && Number.isInteger(r)) {
|
||||||
|
return `${s + 1}-${r - 1}`
|
||||||
|
}
|
||||||
|
const vals = []
|
||||||
|
let v = s + 1
|
||||||
|
while (v < r) {
|
||||||
|
vals.push(Number.isInteger(v) ? v.toString() : v.toFixed(1))
|
||||||
|
v = Math.round((v + 1) * 10) / 10
|
||||||
|
}
|
||||||
|
return vals.join(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildRadMiddle = (s, r) => {
|
||||||
|
if (r - s <= 1) return ''
|
||||||
|
return `${s + 1}-${r - 1}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const setupBreakpointWatchers = (row) => {
|
||||||
|
return [
|
||||||
|
watch(() => row.mic1, val => { row.micref = calcMicRef(val, row.mic2) }),
|
||||||
|
watch(() => row.mic2, val => { row.micref = calcMicRef(row.mic1, val) }),
|
||||||
|
watch(() => row.rad1, val => { row.radref = calcRadRef(val, row.rad2) }),
|
||||||
|
watch(() => row.rad2, val => { row.radref = calcRadRef(row.rad1, val) })
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(treeFilter, val => {
|
||||||
|
treeRef.value?.filter(val)
|
||||||
|
})
|
||||||
|
|
||||||
|
const filterNode = (value, data) => {
|
||||||
|
if (!value) return true
|
||||||
|
return data.zdmc.includes(value) || data.zddh.toLowerCase().includes(value.toLowerCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadGermClassList = () => {
|
||||||
|
getGermClassList().then(res => {
|
||||||
|
germClassList.value = res.data || []
|
||||||
|
if (germClassList.value.length > 0) {
|
||||||
|
currentGermClass.value = germClassList.value[0]
|
||||||
|
loadBreakpoints()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadAntibioticList = () => {
|
||||||
|
getAntibioticList().then(res => {
|
||||||
|
antibioticList.value = res.data || []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadBreakpoints = () => {
|
||||||
|
if (!currentGermClass.value) return
|
||||||
|
loading.value = true
|
||||||
|
getBreakpointList({ germClassCode: currentGermClass.value.zddh }).then(res => {
|
||||||
|
rowWatchers.forEach(stop => stop())
|
||||||
|
rowWatchers = []
|
||||||
|
breakpointList.value = res.data || []
|
||||||
|
breakpointList.value.forEach(row => {
|
||||||
|
rowWatchers.push(...setupBreakpointWatchers(row))
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTreeNodeClick = (data) => {
|
||||||
|
currentGermClass.value = data
|
||||||
|
loadBreakpoints()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddBreakpoint = (row) => {
|
||||||
|
if (!currentGermClass.value) {
|
||||||
|
ElMessage.warning('请先选择菌属')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const exists = breakpointList.value.some(item => item.ywdh === row.ywdh)
|
||||||
|
if (exists) {
|
||||||
|
ElMessage.warning(`${row.ywmc} 已在折点列表中`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const maxXh = breakpointList.value.reduce((max, item) => Math.max(max, item.xh || 0), 0)
|
||||||
|
const newRow = {
|
||||||
|
ywdh: row.ywdh,
|
||||||
|
mic1: null,
|
||||||
|
mic2: null,
|
||||||
|
rad1: null,
|
||||||
|
rad2: null,
|
||||||
|
micref: '',
|
||||||
|
radref: '',
|
||||||
|
xh: maxXh + 10,
|
||||||
|
sddfalg: null,
|
||||||
|
bz: null
|
||||||
|
}
|
||||||
|
breakpointList.value.push(newRow)
|
||||||
|
rowWatchers.push(...setupBreakpointWatchers(newRow))
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeBreakpoint = (index) => {
|
||||||
|
breakpointList.value.splice(index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const search = () => {
|
||||||
|
loadGermClassList()
|
||||||
|
loadAntibioticList()
|
||||||
|
if (currentGermClass.value) {
|
||||||
|
loadBreakpoints()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveBreakpoints = () => {
|
||||||
|
if (!currentGermClass.value) {
|
||||||
|
ElMessage.warning('请先选择菌属')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (breakpointList.value.length === 0) {
|
||||||
|
ElMessage.warning('没有可保存的数据')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = breakpointList.value.map(item => ({
|
||||||
|
yq: '_med_',
|
||||||
|
xmdh: currentGermClass.value.zddh,
|
||||||
|
ywzmc: '菌属',
|
||||||
|
ywdh: item.ywdh,
|
||||||
|
mic1: item.mic1 != null ? Number(item.mic1) : null,
|
||||||
|
mic2: item.mic2 != null ? Number(item.mic2) : null,
|
||||||
|
rad1: item.rad1 != null ? Number(item.rad1) : null,
|
||||||
|
rad2: item.rad2 != null ? Number(item.rad2) : null,
|
||||||
|
xh: item.xh,
|
||||||
|
micref: item.micref,
|
||||||
|
radref: item.radref,
|
||||||
|
sddfalg: item.sddfalg,
|
||||||
|
bz: item.bz
|
||||||
|
}))
|
||||||
|
|
||||||
|
batchSaveBreakpoint(data).then(() => {
|
||||||
|
ElMessage.success('保存成功')
|
||||||
|
loadBreakpoints()
|
||||||
|
}).catch(() => {
|
||||||
|
ElMessage.error('保存失败')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
if (currentGermClass.value) {
|
||||||
|
loadBreakpoints()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
search()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.app-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #d5d5d5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-panel {
|
||||||
|
background: #e6f7fa;
|
||||||
|
border-right: 1px solid #d9e8fb;
|
||||||
|
border-bottom: 1px solid #d9e8fb;
|
||||||
|
border-left: 1px solid #d9e8fb;
|
||||||
|
border-radius: 0 0 8px 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
margin-top: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-bar {
|
||||||
|
padding: 8px 12px 8px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-container {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
gap: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #d9e8fb;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: #f0f8ff;
|
||||||
|
border-bottom: 1px solid #d9e8fb;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #3282F6;
|
||||||
|
font-family: SimSun, "宋体", serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-panel {
|
||||||
|
width: 220px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-panel {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-panel {
|
||||||
|
width: 560px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
:deep(.el-table) {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表格样式
|
||||||
|
:deep(.el-table) {
|
||||||
|
--el-table-row-height: 20px;
|
||||||
|
--el-table-header-row-height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__header-wrapper th) {
|
||||||
|
height: 26px !important;
|
||||||
|
min-height: 26px !important;
|
||||||
|
max-height: 26px !important;
|
||||||
|
line-height: 26px !important;
|
||||||
|
padding: 0 4px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
font-family: SimSun, "宋体", serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__body-wrapper td) {
|
||||||
|
height: 20px !important;
|
||||||
|
min-height: 20px !important;
|
||||||
|
max-height: 20px !important;
|
||||||
|
line-height: 20px !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
font-family: SimSun, "宋体", serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__cell) {
|
||||||
|
font-family: SimSun, "宋体", serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__cell .cell) {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0 2px;
|
||||||
|
line-height: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__body-wrapper .el-input) {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__body-wrapper .el-input__wrapper) {
|
||||||
|
height: 100%;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__body-wrapper .el-input__inner) {
|
||||||
|
height: 100%;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-node {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: SimSun, "宋体", serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-code {
|
||||||
|
color: #3282F6;
|
||||||
|
font-weight: 600;
|
||||||
|
min-width: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-name {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree) {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree-node__content) {
|
||||||
|
height: 26px;
|
||||||
|
padding-left: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree-node__content:hover) {
|
||||||
|
background: #ecf5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree-node.is-current > .el-tree-node__content) {
|
||||||
|
background: #409eff;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree-node.is-current > .el-tree-node__content .tree-code) {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree-node.is-current > .el-tree-node__content .tree-name) {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.sdd-checkbox) {
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.sdd-checkbox .el-checkbox__input) {
|
||||||
|
transform: scale(1.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-panel :deep(.el-table__row) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
150
src/views/liswork/xtwh/comopt/components/sysMedinter/index.vue
Normal file
150
src/views/liswork/xtwh/comopt/components/sysMedinter/index.vue
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 抗生素通道号设定 -->
|
||||||
|
<div class="table-container">
|
||||||
|
<el-row :gutter="10" class="table-toolbar">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="success" plain icon="Check" @click="handleSave">保存</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" plain icon="Plus" @click="addItem">新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="danger" plain icon="Delete" @click="delItem">删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<div class="table-row">
|
||||||
|
<CustomTable ref="tableRef" :data="tableData" :columns="columns" :config="tableConfig" :loading="loading"
|
||||||
|
@row-click="handleRowClick">
|
||||||
|
<template #tdh="{ row }">
|
||||||
|
<el-input v-model="row.tdh" placeholder="请输入通道号" :disabled="!row._isNew" class="full-width-input" />
|
||||||
|
</template>
|
||||||
|
<template #ywdh="{ row }">
|
||||||
|
<SelectTable v-model:data="row.ywdh" :tableData="medList" class="full-width-input" />
|
||||||
|
</template>
|
||||||
|
</CustomTable>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { listMed } from '@/api/liswork/germ/med'
|
||||||
|
import { listMedinter, addMedinter, updateMedinter, delMedinter } from '@/api/liswork/germ/medinter'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const yq = defineModel<string>();
|
||||||
|
const loading = ref(false);
|
||||||
|
const tableRef = ref();
|
||||||
|
const tableData = ref<Array<any>>([]);
|
||||||
|
const medList = ref<Array<{ label: string, value: string }>>([]);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ label: '序号', type: 'index', visible: true, width: 50, align: 'center' },
|
||||||
|
{ label: '通道号', prop: 'tdh', visible: true, align: 'center', slot: 'tdh', width: 160 },
|
||||||
|
{ label: '药物', prop: 'ywdh', visible: true, align: 'center', slot: 'ywdh', minWidth: 260 },
|
||||||
|
];
|
||||||
|
const tableConfig = {
|
||||||
|
border: true,
|
||||||
|
height: '100%',
|
||||||
|
highlightCurrentRow: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedRow = ref<any>(null);
|
||||||
|
const handleRowClick = (row: any) => {
|
||||||
|
selectedRow.value = row;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 药物字典:label 显示 名称(代码),value 为药物代码
|
||||||
|
const getMedList = () => {
|
||||||
|
listMed({}).then((res: any) => {
|
||||||
|
medList.value = (res.data || []).map((item: any) => ({
|
||||||
|
label: `${item.ywmc}(${item.ywdh})`,
|
||||||
|
value: item.ywdh,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
const getList = () => {
|
||||||
|
if (!yq.value) return;
|
||||||
|
loading.value = true;
|
||||||
|
listMedinter({ yq: yq.value }).then((res: any) => {
|
||||||
|
loading.value = false;
|
||||||
|
tableData.value = (res.data || []).map((r: any) => ({ ...r, _isNew: false }));
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
const addItem = () => {
|
||||||
|
if (!yq.value) return ElMessage.warning('请先在左侧选择仪器');
|
||||||
|
tableData.value.push({ yq: yq.value, tdh: '', ywdh: '', _isNew: true });
|
||||||
|
nextTick(() => {
|
||||||
|
tableRef.value?.setScrollTop(tableData.value.length);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const delItem = () => {
|
||||||
|
if (!selectedRow.value) return ElMessage.error('请先选择要删除的行!');
|
||||||
|
const row = selectedRow.value;
|
||||||
|
if (row._isNew) {
|
||||||
|
tableData.value = tableData.value.filter((r: any) => r !== row);
|
||||||
|
selectedRow.value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delMedinter({ yq: row.yq, tdh: row.tdh }).then(() => {
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
if (!yq.value) return ElMessage.warning('请先在左侧选择仪器');
|
||||||
|
// 校验
|
||||||
|
for (let i = 0; i < tableData.value.length; i++) {
|
||||||
|
const row = tableData.value[i];
|
||||||
|
if (!row.tdh || !row.tdh.trim()) return ElMessage.error(`第${i + 1}行通道号不能为空!`);
|
||||||
|
if (!row.ywdh) return ElMessage.error(`第${i + 1}行请选择药物!`);
|
||||||
|
}
|
||||||
|
// 通道号去重
|
||||||
|
const tdhSet = new Set();
|
||||||
|
for (const row of tableData.value) {
|
||||||
|
const k = row.tdh.trim().toUpperCase();
|
||||||
|
if (tdhSet.has(k)) return ElMessage.error(`通道号 ${row.tdh} 重复!`);
|
||||||
|
tdhSet.add(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tasks: Promise<any>[] = [];
|
||||||
|
tableData.value.forEach((row: any) => {
|
||||||
|
const payload = { yq: yq.value, tdh: row.tdh.trim(), ywdh: row.ywdh };
|
||||||
|
if (row._isNew) {
|
||||||
|
tasks.push(addMedinter(payload));
|
||||||
|
} else {
|
||||||
|
tasks.push(updateMedinter(payload));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Promise.all(tasks).then(() => {
|
||||||
|
ElMessage.success('保存成功!');
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(yq, (val) => {
|
||||||
|
if (val) getList();
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
|
getMedList();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.table-container {
|
||||||
|
height: calc(100% - 58px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-toolbar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row {
|
||||||
|
height: calc(100% - 45px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -53,6 +53,7 @@ import SysDefaultParams from './components/sysDefaultParams/index.vue'
|
|||||||
import SysParameter from './components/sysParameter/index.vue'
|
import SysParameter from './components/sysParameter/index.vue'
|
||||||
import SysChannel from './components/sysChannel/index.vue'
|
import SysChannel from './components/sysChannel/index.vue'
|
||||||
import SysSort from './components/sysSort/index.vue'
|
import SysSort from './components/sysSort/index.vue'
|
||||||
|
import SysMedinter from './components/sysMedinter/index.vue'
|
||||||
const mbStore = useCommonStore();
|
const mbStore = useCommonStore();
|
||||||
// ========== TypeScript 类型定义 ==========
|
// ========== TypeScript 类型定义 ==========
|
||||||
interface InstrTreeNode {
|
interface InstrTreeNode {
|
||||||
@ -112,6 +113,7 @@ const tabList = [
|
|||||||
{ key: 'SysDefaultParams', label: '默认界面参数', component: SysDefaultParams },
|
{ key: 'SysDefaultParams', label: '默认界面参数', component: SysDefaultParams },
|
||||||
{ key: 'SysParameter', label: '参数', component: SysParameter },
|
{ key: 'SysParameter', label: '参数', component: SysParameter },
|
||||||
{ key: 'SysChannel', label: '通道号', component: SysChannel },
|
{ key: 'SysChannel', label: '通道号', component: SysChannel },
|
||||||
|
{ key: 'SysMedinter', label: '抗生素通道号', component: SysMedinter },
|
||||||
{ key: 'SysSort', label: '项目排序', component: SysSort },
|
{ key: 'SysSort', label: '项目排序', component: SysSort },
|
||||||
{ key: 'SysReport', label: '报告单设置', component: SysReport },
|
{ key: 'SysReport', label: '报告单设置', component: SysReport },
|
||||||
]
|
]
|
||||||
|
|||||||
@ -5,22 +5,23 @@
|
|||||||
*/
|
*/
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<div class="mb8">
|
<div class="unified-panel">
|
||||||
|
<div class="btn-bar">
|
||||||
<el-button type="primary" icon="Search" @click="search">查询</el-button>
|
<el-button type="primary" icon="Search" @click="search">查询</el-button>
|
||||||
<el-button type="warning" icon="Printer" plain :loading="printLoading" @click="print">打印</el-button>
|
<el-button type="warning" icon="Printer" plain :loading="printLoading" @click="print">打印</el-button>
|
||||||
<el-button type="primary" icon="Download" plain :loading="exportLoading" @click="exportHandle">导出Excel</el-button>
|
<el-button type="primary" icon="Download" plain :loading="exportLoading" @click="exportHandle">导出Excel</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form ref="form" :model="queryParams" inline size="small" class="stats-form" label-width="auto">
|
<div class="divider-h"></div>
|
||||||
<el-row :gutter="10" class="stats-form-row">
|
|
||||||
<el-col :span="checkBoxs.length ? 16 : 24">
|
<el-form ref="form" :model="queryParams" inline size="small" class="stats-form" label-width="72px">
|
||||||
<div class="form-panel">
|
<el-row :gutter="0" class="stats-form-row">
|
||||||
|
<el-col :span="checkBoxs.length ? 16 : 24" class="panel-section">
|
||||||
<div class="tips">统计条件</div>
|
<div class="tips">统计条件</div>
|
||||||
<div class="panel-content panel-content-left">
|
<div class="panel-content panel-content-left">
|
||||||
<template v-for="item in Parameter">
|
<template v-for="item in Parameter">
|
||||||
<el-form-item :label="item.paramOptiontype == '0' ? '' : item.paramName"
|
<el-form-item :label="item.paramOptiontype == '0' ? '' : item.paramName"
|
||||||
:class="{ 'checkbox-form-item': item.paramOptiontype == '0' }"
|
:class="{ 'checkbox-form-item': item.paramOptiontype == '0' }">
|
||||||
:label-width="item.paramName == '-' ? '0px' : 'auto'">
|
|
||||||
<template v-if="item.paramOptiontype == '0'">
|
<template v-if="item.paramOptiontype == '0'">
|
||||||
<el-checkbox v-model="item.paramDefvalue" :label="item.paramName" true-value="1" false-value="0" />
|
<el-checkbox v-model="item.paramDefvalue" :label="item.paramName" true-value="1" false-value="0" />
|
||||||
</template>
|
</template>
|
||||||
@ -53,32 +54,30 @@
|
|||||||
<!-- 特殊处理 -->
|
<!-- 特殊处理 -->
|
||||||
</template>
|
</template>
|
||||||
<template v-if="item.paramOptiontype == '5'">
|
<template v-if="item.paramOptiontype == '5'">
|
||||||
<el-input v-model="item.paramDefvalue" placeholder="请输入" />
|
<el-input v-model="item.paramDefvalue" placeholder="请输入" style="width:150px" />
|
||||||
</template>
|
</template>
|
||||||
<template v-if="item.paramOptiontype == '6'">
|
<template v-if="item.paramOptiontype == '6'">
|
||||||
<el-input v-model="item.paramDefvalue" type="number" placeholder="请输入" />
|
<el-input v-model="item.paramDefvalue" type="number" placeholder="请输入" style="width:150px" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="item.paramOptiontype == '7'">
|
<template v-if="item.paramOptiontype == '7'">
|
||||||
<el-date-picker v-model="item.paramDefvalue" type="date" format="YYYY-MM-DD"
|
<el-date-picker v-model="item.paramDefvalue" type="date" format="YYYY-MM-DD"
|
||||||
value-format="YYYY-MM-DD" @change="handletime" style="width:120px" />
|
value-format="YYYY-MM-DD" @change="handletime" style="width:150px" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="item.paramOptiontype == '8'">
|
<template v-if="item.paramOptiontype == '8'">
|
||||||
<el-time-picker v-model="item.paramDefvalue" value-format="HH:mm:ss" format="HH:mm:ss"
|
<el-time-picker v-model="item.paramDefvalue" value-format="HH:mm:ss" format="HH:mm:ss"
|
||||||
style="width:100px" />
|
style="width:150px" />
|
||||||
</template>
|
</template>
|
||||||
<template v-if="item.paramOptiontype == '9'">
|
<template v-if="item.paramOptiontype == '9'">
|
||||||
<el-time-picker v-model="item.paramDefvalue" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
|
<el-time-picker v-model="item.paramDefvalue" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
format="YYYY-MM-DD HH:mm:ss" style="width:100px" />
|
format="YYYY-MM-DD HH:mm:ss" style="width:150px" />
|
||||||
</template>
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8" class="panel-section" v-if="checkBoxs.length">
|
||||||
<div class="form-panel" v-if="checkBoxs.length">
|
|
||||||
<div class="tips">统计项目</div>
|
<div class="tips">统计项目</div>
|
||||||
<div class="panel-content panel-content-right">
|
<div class="panel-content panel-content-right">
|
||||||
<el-form-item label="" class="stats-items-form-item">
|
<el-form-item label="" class="stats-items-form-item">
|
||||||
@ -89,17 +88,17 @@
|
|||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
</div>
|
||||||
<!-- statsType==1 查询表格 0 统计 -->
|
<!-- statsType==1 查询表格 0 统计 -->
|
||||||
<div class="print_box">
|
<div class="print_box">
|
||||||
<div class="print_content" :style="{ width: Template.statsType == 1 ? '100%' : '70%' }">
|
<div class="print_content" :style="{ width: Template.statsType == 1 ? '100%' : '70%' }">
|
||||||
<div class="title" v-if="statsTitle">{{ formatDict(userStore.sysLoginParam.loginYLJG, 'HOS') }}</div>
|
<div class="title" v-if="statsTitle">{{ formatDict(userStore.sysLoginParam.loginYLJG, 'HOS') }}</div>
|
||||||
<div class="content">{{ statsTitle }}</div>
|
<div class="content">{{ statsTitle }}</div>
|
||||||
<div class="table-container bb_table" :style="{ height: `calc(100% - ${statsTitle ? '70px' : '15px'})` }">
|
<div class="table-container bb_table" :style="{ height: `calc(100% - ${statsTitle ? '70px' : '15px'})` }">
|
||||||
<vxe-table :data="tableData" border v-loading="loading" height="100%"
|
<vxe-table :data="tableData" border v-loading="loading" height="100%" size="mini"
|
||||||
:tooltip-config="{ appendToBody: true, zIndex: 3000 }" show-footer :footer-method="getSummaries"
|
:tooltip-config="{ appendToBody: true, zIndex: 3000 }" show-footer :footer-method="getSummaries"
|
||||||
:scroll-y="{ enabled: true, rSize: 30, height: '100%', oSize: 20, gt: 30, }" show-footer-overflow
|
:scroll-y="{ enabled: true, rSize: 30, height: '100%', oSize: 20, gt: 30, }" show-footer-overflow
|
||||||
@cell-dblclick="cellDblclickEvent">
|
@cell-dblclick="cellDblclickEvent">
|
||||||
@ -409,31 +408,69 @@ onMounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-color: #eee;
|
background-color: #d5d5d5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-form {
|
.stats-form {
|
||||||
margin-bottom: 6px;
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unified-panel {
|
||||||
|
background: #e6f7fa;
|
||||||
|
border-right: 1px solid #d9e8fb;
|
||||||
|
border-bottom: 1px solid #d9e8fb;
|
||||||
|
border-left: 1px solid #d9e8fb;
|
||||||
|
border-radius: 0 0 8px 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
margin-top: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-bar {
|
||||||
|
padding: 8px 12px 8px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider-h {
|
||||||
|
height: 3px;
|
||||||
|
background: #f8fbff;
|
||||||
|
border-top: 1px solid #a0b8d0;
|
||||||
|
border-bottom: 1px solid #fff;
|
||||||
|
margin: 0 12px;
|
||||||
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-form-row {
|
.stats-form-row {
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-panel {
|
.panel-section {
|
||||||
height: 100%;
|
padding: 8px 12px;
|
||||||
padding: 5px 12px;
|
|
||||||
background: #f8fbff;
|
|
||||||
border: 1px solid #d9e8fb;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panel-section + .panel-section {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 8px;
|
||||||
|
bottom: 8px;
|
||||||
|
width: 3px;
|
||||||
|
background: #f8fbff;
|
||||||
|
border-left: 1px solid #a0b8d0;
|
||||||
|
border-right: 1px solid #fff;
|
||||||
|
box-shadow: inset 1px 0 2px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.panel-content {
|
.panel-content {
|
||||||
display: flex;
|
display: grid !important;
|
||||||
flex-wrap: wrap;
|
grid-template-columns: repeat(auto-fill, 230px);
|
||||||
align-items: flex-start;
|
gap: 4px 6px;
|
||||||
gap: 4px 12px;
|
align-items: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-content-left {
|
.panel-content-left {
|
||||||
@ -442,16 +479,35 @@ onMounted(() => {
|
|||||||
|
|
||||||
.panel-content-right {
|
.panel-content-right {
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-content-right .stats-items-form-item {
|
||||||
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-form :deep(.el-form-item) {
|
.stats-form :deep(.el-form-item) {
|
||||||
margin-right: 0;
|
display: flex !important;
|
||||||
margin-bottom: 2px;
|
width: 100% !important;
|
||||||
|
margin-right: 0 !important;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-form :deep(.el-form-item__label) {
|
.stats-form :deep(.el-form-item__label) {
|
||||||
padding-right: 8px;
|
padding-right: 4px !important;
|
||||||
color: #4b5563;
|
color: #4b5563;
|
||||||
|
text-align: left;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-form :deep(.el-form-item__content) {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-form :deep(.checkbox-form-item .el-form-item__content) {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -474,6 +530,7 @@ onMounted(() => {
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
font-family: SimSun, "宋体", serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
@ -481,18 +538,21 @@ onMounted(() => {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
font-family: SimSun, "宋体", serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.print_box {
|
.print_box {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
margin-top: 12px;
|
||||||
|
|
||||||
|
|
||||||
.print_content {
|
.print_content {
|
||||||
width: 70%;
|
width: 70%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,6 +561,48 @@ onMounted(() => {
|
|||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-container :deep(.vxe-table) {
|
||||||
|
--vxe-table-row-height: 24px !important;
|
||||||
|
--vxe-table-header-row-height: 28px !important;
|
||||||
|
--vxe-table-footer-row-height: 24px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container :deep(.vxe-body--row),
|
||||||
|
.table-container :deep(.vxe-header--row),
|
||||||
|
.table-container :deep(.vxe-footer--row),
|
||||||
|
.table-container :deep(tr) {
|
||||||
|
height: 24px !important;
|
||||||
|
min-height: 24px !important;
|
||||||
|
max-height: 24px !important;
|
||||||
|
line-height: 24px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container :deep(.vxe-header--row),
|
||||||
|
.table-container :deep(thead tr) {
|
||||||
|
height: 28px !important;
|
||||||
|
min-height: 28px !important;
|
||||||
|
max-height: 28px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container :deep(.vxe-cell),
|
||||||
|
.table-container :deep(td),
|
||||||
|
.table-container :deep(.vxe-body--column .vxe-cell),
|
||||||
|
.table-container :deep(th) {
|
||||||
|
padding: 0 4px !important;
|
||||||
|
line-height: 24px !important;
|
||||||
|
height: 24px !important;
|
||||||
|
font-family: SimSun, "宋体", serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container :deep(thead th) {
|
||||||
|
height: 28px !important;
|
||||||
|
line-height: 28px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container :deep(.vxe-header--column .vxe-cell) {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@ -523,8 +625,8 @@ onMounted(() => {
|
|||||||
|
|
||||||
|
|
||||||
@media (max-width: 1400px) {
|
@media (max-width: 1400px) {
|
||||||
.checkbox-form-item {
|
.panel-content {
|
||||||
min-width: 180px;
|
grid-template-columns: repeat(auto-fill, 215px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-checkbox-group :deep(.el-checkbox) {
|
.stats-checkbox-group :deep(.el-checkbox) {
|
||||||
|
|||||||
@ -41,7 +41,7 @@ export default defineConfig(({
|
|||||||
proxy: {
|
proxy: {
|
||||||
// https://cn.vitejs.dev/config/#server-proxy
|
// https://cn.vitejs.dev/config/#server-proxy
|
||||||
'/dev-api': {
|
'/dev-api': {
|
||||||
target: 'http://47.97.125.165:8904',
|
target: 'http://localhost:9801',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user