质控录入
This commit is contained in:
parent
b584460dd8
commit
be3703bd7a
@ -107,3 +107,11 @@ export function queryValXmdh(data?: Object) {
|
||||
params: data
|
||||
})
|
||||
}
|
||||
// 查询质控品录入
|
||||
export function getqcval(data?: Object) {
|
||||
return request({
|
||||
url: '/qc/getqcval',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
@ -30,11 +30,19 @@
|
||||
<el-empty v-if="filterData.length === 0" description="没有匹配的数据" :image-size="100" />
|
||||
<div @keydown="handleKeydown" v-else tabindex="0" style="outline: none;">
|
||||
<!-- 数据存在时显示表格 -->
|
||||
<el-table ref="tableRef" :data="filterData" :highlight-current-row="props.isHighlight" style="width: 100%"
|
||||
<!-- <el-table ref="tableRef" :data="filterData" :highlight-current-row="props.isHighlight" style="width: 100%"
|
||||
:border="props.border" @row-click="handleRowChange" max-height="350px" :row-style="{ height: '25px' }">
|
||||
<el-table-column v-for="field in props.fields" :prop="field.prop" :label="field.label"
|
||||
:width="field.width" show-overflow-tooltip align="center" />
|
||||
</el-table>
|
||||
</el-table> -->
|
||||
<vxe-table class="mytable-style" ref="tableRef" border resizable highlight-current-row max-height="350px"
|
||||
:row-config="{ isHover: true, keyField: 'value', height: 30 }" :data="filterData"
|
||||
:current-row="currentRow" @current-change="currentChange"
|
||||
:tooltip-config="{ appendToBody: true, zIndex: 3000 }" :show-overflow="true"
|
||||
:scroll-y="{ enabled: true, rSize: 30, height: '100%' }">
|
||||
<vxe-table-column v-for="field in props.fields" :field="field.prop" :title="field.label" align="center"
|
||||
:width="field.width" />
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -78,7 +86,7 @@ const filterData = ref<{ [key: string]: any; pinyinMap: Record<string, string> }
|
||||
// 存储预处理后的带拼音数据
|
||||
const processedTableData = ref<{ [key: string]: any; pinyinMap: Record<string, string> }[]>([]);
|
||||
const currentIndex = ref(-1);
|
||||
|
||||
const currentRow = ref<any>(null)
|
||||
// 字典数据存储
|
||||
const dictData = ref<Record<string, any[]>>({});
|
||||
// 预处理数据:生成拼音信息
|
||||
@ -113,8 +121,8 @@ const visibleChange = (val: any) => {
|
||||
|
||||
currentIndex.value = filterData.value.findIndex(item => item[props.value!] === props.data);
|
||||
if (currentIndex.value >= 0) {
|
||||
tableRef.value.setCurrentRow(filterData.value[currentIndex.value]);
|
||||
tableRef.value.setScrollTop(currentIndex.value * 30);
|
||||
tableRef.value.setCurrentRow(filterData.value[currentIndex.value])
|
||||
tableRef.value.scrollToRow(filterData.value[currentIndex.value])
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
@ -233,11 +241,8 @@ const handleKeydown = (e: any) => {
|
||||
currentIndex.value = Math.min(maxIndex, currentIndex.value + 1);
|
||||
}
|
||||
|
||||
tableRef.value.setCurrentRow(filterData.value[currentIndex.value]);
|
||||
|
||||
// 滚动到当前行
|
||||
tableRef.value.setScrollTop(currentIndex.value * 30);
|
||||
|
||||
tableRef.value.setCurrentRow(filterData.value[currentIndex.value])
|
||||
tableRef.value.scrollToRow(filterData.value[currentIndex.value])
|
||||
// 回车确认
|
||||
if (e.key === "Enter") {
|
||||
const currentRow = filterData.value[currentIndex.value];
|
||||
@ -284,11 +289,18 @@ const filterDataHandle = () => {
|
||||
});
|
||||
|
||||
if (filterData.value.length > 0) {
|
||||
tableRef.value.setScrollTop(0)
|
||||
tableRef.value.setCurrentRow(filterData.value[0]);
|
||||
nextTick(() => {
|
||||
tableRef.value.setCurrentRow(filterData.value[0])
|
||||
tableRef.value.scrollToRow(filterData.value[0])
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const currentChange = (params: { row: any }) => {
|
||||
currentRow.value = params.row
|
||||
handleRowChange(params.row)
|
||||
}
|
||||
|
||||
const handleRowChange = (val: any) => {
|
||||
emits("update:data", props.value ? val[props.value] : val);
|
||||
setLabel(val);
|
||||
@ -316,11 +328,44 @@ const clearHandle = () => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.select-table-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.vxe-header--row th) {
|
||||
border-color: #1F6DD3;
|
||||
background-color: #1F6DD3;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
:deep(.vxe-body--row td) {
|
||||
border-color: #1F6DD3;
|
||||
}
|
||||
|
||||
:deep(.vxe-table--row-hover) {
|
||||
background-color: #1F6DD3;
|
||||
}
|
||||
|
||||
:deep(.vxe-table--current-row) {
|
||||
background-color: #1F6DD3;
|
||||
}
|
||||
|
||||
:deep(.el-table-header-cell) {
|
||||
cursor: move;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
// 表格边框
|
||||
:deep(.vxe-table--render-default.border--full .vxe-body--column) {
|
||||
background-image: linear-gradient(#96B8D9, #96B8D9), linear-gradient(#96B8D9, #96B8D9) !important;
|
||||
}
|
||||
|
||||
// 表头边框
|
||||
:deep(.vxe-table--render-default.border--full .vxe-header--column) {
|
||||
background-image: linear-gradient(#1F6DD3, #1F6DD3), linear-gradient(#1F6DD3, #1F6DD3) !important;
|
||||
}
|
||||
|
||||
.select-table-dropdown {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="app-container ">
|
||||
<div class="tips">检验科条码打印科室:{{ formatDict(queryParams.ksdh, 'DP') }}</div>
|
||||
<div class="tips">检验科条码打印 科室:{{ formatDict(queryParams.ksdh, 'DP') }} 登录人:{{ formatUser(queryParams.userid) }}</div>
|
||||
<div ref="compactForm">
|
||||
<el-row :gutter="10" class="compact-form" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" :size="aotuSize" :rules="queryRules">
|
||||
@ -167,6 +167,8 @@ import CustomTable from '@/components/elTable/index.vue'
|
||||
import CustomVxeTable from '@/components/vxeTable/index.vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { usePrintStore } from '@/store/modules/printStore'
|
||||
// @ts-ignore
|
||||
import { listUser } from '@/api/system/user.js'
|
||||
import { fetchCodeList, addObj, fetchCodeDetail, fetchCodeExec, fetchCodeReqmain, printSendSample } from '@/api/checkCode/index'
|
||||
const aotuSize = classCom.useAutoSize();
|
||||
//@ts-ignore
|
||||
@ -580,7 +582,7 @@ const sendSampleHandle = () => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const userList = ref<{ userName: string, nickName: string }[]>([])
|
||||
|
||||
onMounted(async () => {
|
||||
// 获取当前日期(当天)
|
||||
@ -612,6 +614,10 @@ onMounted(async () => {
|
||||
getList()
|
||||
}
|
||||
|
||||
listUser({ status: 0, del_flag: 0, pageSize: 1000, pageNum: 1 }).then((res: any) => {
|
||||
userList.value = res.rows;
|
||||
});
|
||||
|
||||
// 加载病人来源字典
|
||||
const dictRefs = await comDict('PT', 'HOS', 'ST', 'DP');
|
||||
|
||||
@ -629,6 +635,10 @@ const formatDict = (v: string, dictType: string) => {
|
||||
return dictData.value[dictType]?.find((item: any) => item.value == v)?.label || v;
|
||||
};
|
||||
|
||||
const formatUser = (v: string) => {
|
||||
return userList.value.find((item: any) => item.userName == v)?.nickName || v;
|
||||
};
|
||||
|
||||
const handletime = (val: Array<string>) => {
|
||||
// console.log('时间', val);
|
||||
// 校验日期格式
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
<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" plain @click="addHandle">新增</el-button>
|
||||
<el-button type="warning" plain @click="editHandle">修改</el-button>
|
||||
<el-button type="danger" plain @click="delBatch">删除</el-button>
|
||||
@ -16,6 +15,7 @@
|
||||
<el-col :span="16">
|
||||
<span class="tips">靶值列表</span>
|
||||
<el-button type="primary" plain @click="dateClick">复制第一个开始日期到每个项目</el-button>
|
||||
<el-button type="primary" plain icon="Check" @click="handleSave">保存</el-button>
|
||||
<el-button type="primary" plain @click="">复制靶值</el-button>
|
||||
<el-button type="primary" plain @click="">新增靶值</el-button>
|
||||
<el-button type="danger" plain @click="">删除靶值</el-button>
|
||||
@ -28,6 +28,9 @@
|
||||
<CustomVxeTable ref="leftTableRef" class="mytable-style" :table-data="tableData" :columns="columns"
|
||||
:row-config="{ isHover: true, keyField: 'batchno' }" @current-change="batchClick"
|
||||
:scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }">
|
||||
<template #conc="{ row }">
|
||||
{{concList.find(item => item.value == row.conc)?.label || row.conc}}
|
||||
</template>
|
||||
<template #useflag="{ row }">
|
||||
<el-checkbox :model-value="row.useflag == 1" readonly></el-checkbox>
|
||||
</template>
|
||||
@ -66,7 +69,8 @@
|
||||
<SelectTable v-model:data="row.ff" :tableData="dictData.MD" placeholder="" class="full-width-input" />
|
||||
</template>
|
||||
<template #sjph="{ row }">
|
||||
<SelectTable v-model:data="row.sjph" :tableData="dictData.TK" placeholder="" class="full-width-input" />
|
||||
<SelectTable v-model:data="row.sjph" :tableData="dictData.LOT" value="label" objKey="label" placeholder=""
|
||||
class="full-width-input" />
|
||||
</template>
|
||||
<template #qccv="{ row }">
|
||||
<el-input v-model="row.qccv" class="full-width-input" />
|
||||
@ -83,7 +87,7 @@
|
||||
{{ formatDict(row.ff, 'MD') }}
|
||||
</template>
|
||||
<template #sjph="{ row }">
|
||||
{{ formatDict(row.sjph, 'TK') }}
|
||||
{{ formatDict(row.sjph, 'LOT') }}
|
||||
</template>
|
||||
</CustomTable>
|
||||
</div>
|
||||
@ -106,12 +110,17 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="水平" prop="zkph">
|
||||
<el-select v-model="formData.zkph" placeholder="请选择">
|
||||
<el-option />
|
||||
<el-option label="水平1" value="1" />
|
||||
<el-option label="水平2" value="2" />
|
||||
<el-option label="水平3" value="3" />
|
||||
<el-option label="水平4" value="4" />
|
||||
<el-option label="水平5" value="5" />
|
||||
<el-option label="水平6" value="6" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="浓度" prop="conc">
|
||||
<el-select v-model="formData.conc" placeholder="请选择">
|
||||
<el-option />
|
||||
<el-option v-for="item in concList" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="批号(瓶子上的)" prop="batchno">
|
||||
@ -120,21 +129,19 @@
|
||||
<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 label="启用日期" prop="startda">
|
||||
<el-date-picker v-model="formData.startda" 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>
|
||||
<SelectTable v-model:data="formData.qcsrc" :tableData="dictData.LOT" value="label" objKey="label"
|
||||
placeholder="" :fields="fields" />
|
||||
</el-form-item>
|
||||
<el-form-item label="校准品厂商" prop="standsrc">
|
||||
<el-select v-model="formData.standsrc" placeholder="请选择">
|
||||
<el-option />
|
||||
</el-select>
|
||||
<SelectTable v-model:data="formData.standsrc" :tableData="dictData.LOT" value="label" objKey="label"
|
||||
:fields="fields" placeholder="" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="bk">
|
||||
<el-input v-model="formData.bk" type="textarea" :row="5" />
|
||||
@ -168,7 +175,7 @@ const formData = ref({
|
||||
useflag: '1',
|
||||
batchno: '',
|
||||
expiredt: '',
|
||||
ksrq: '',
|
||||
startda: '',
|
||||
endda: '',
|
||||
qcsrc: '',
|
||||
standsrc: '',
|
||||
@ -177,16 +184,29 @@ const formData = ref({
|
||||
const rules = ref({
|
||||
zkpph: [{ required: true, message: '请输入质控批号', trigger: 'blur' }],
|
||||
zkph: [{ required: true, message: '请选择水平', trigger: 'change' }],
|
||||
ksrq: [{ required: true, message: '请选择启用日期', trigger: 'change' }],
|
||||
startda: [{ required: true, message: '请选择启用日期', trigger: 'change' }],
|
||||
})
|
||||
|
||||
const fields = ref(
|
||||
[
|
||||
{ prop: 'value', label: '代号', width: '40%', enablePinyinSearch: true },
|
||||
{ prop: 'label', label: '名称', width: '60%', enablePinyinSearch: true },
|
||||
],
|
||||
)
|
||||
|
||||
const concList = ref([
|
||||
{ label: '高', value: 'H' },
|
||||
{ label: '低', value: 'L' },
|
||||
{ label: '中', value: 'M' },
|
||||
])
|
||||
const loading = ref(false)
|
||||
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: 'conc', resizable: true, align: 'center', slotName: 'conc' },
|
||||
{ title: '在用', field: 'useflag', resizable: true, align: 'center', slotName: 'useflag' },
|
||||
{ title: '启用日期', field: 'ksrq', width: 90, resizable: true, align: 'center' },
|
||||
{ title: '启用日期', field: 'startda', 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' },
|
||||
@ -204,8 +224,8 @@ const topColumns = [
|
||||
{ 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: '方法', field: 'ff', resizable: true, align: 'center', slotName: 'ff', width: 100 },
|
||||
{ title: '试剂', field: 'sjph', resizable: true, align: 'center', slotName: 'sjph', width: 100 },
|
||||
{ title: '目标CV(%)', field: 'qccv', resizable: true, align: 'center', slotName: 'qccv', width: 80 },
|
||||
]
|
||||
const bottomTableData = ref([])
|
||||
@ -280,12 +300,21 @@ const delBatch = () => {
|
||||
const submit = () => {
|
||||
queryRef.value.validate((valid: boolean) => {
|
||||
if (!valid) return false;
|
||||
return
|
||||
if (title.value == '修改批号') {
|
||||
updateBatchno(formData.value).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success('修改成功')
|
||||
handleDialogClose()
|
||||
getBatchList()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
addBatchno(formData.value).then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success('新增成功')
|
||||
handleDialogClose()
|
||||
getBatchList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -302,12 +331,13 @@ const handleDialogClose = () => {
|
||||
useflag: '1',
|
||||
batchno: '',
|
||||
expiredt: '',
|
||||
ksrq: '',
|
||||
startda: '',
|
||||
endda: '',
|
||||
qcsrc: '',
|
||||
standsrc: '',
|
||||
bk: ''
|
||||
}
|
||||
visible.value = false
|
||||
}
|
||||
const batchInfo: any = ref(null)
|
||||
const batchClick = (row: any) => {
|
||||
@ -317,7 +347,7 @@ const batchClick = (row: any) => {
|
||||
const getBatchList = () => {
|
||||
batchInfo.value = null
|
||||
loading.value = true
|
||||
queryBatch({ yq: yq.value, pageNum: 1, pageSize: 9999 }).then((res: any) => {
|
||||
queryBatch({ yq: yq.value }).then((res: any) => {
|
||||
loading.value = false
|
||||
tableData.value = res.data || []
|
||||
getXmList(tableData.value[0])
|
||||
@ -360,7 +390,9 @@ watch(yq, (val) => {
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-input__prefix) {
|
||||
.mytable-style {
|
||||
:deep(.el-input__prefix) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -250,7 +250,7 @@ const getDeptTree = async (): Promise<void> => {
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getDictData('MD', 'TK')
|
||||
getDictData('MD', 'LOT')
|
||||
})
|
||||
// ========== 初始化 ==========
|
||||
getDeptTree()
|
||||
|
||||
@ -0,0 +1,172 @@
|
||||
/**
|
||||
* @file dateTime.vue 日期录入
|
||||
* @author: w
|
||||
* @since: 2026-01-13
|
||||
*/
|
||||
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="handle-box mb5">
|
||||
<el-form>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-form-item label="日期:">
|
||||
<el-date-picker v-model="queryParams.zkrq" type="date" value-format="YYYY-MM-DD" style="width:100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="项目:">
|
||||
<el-select v-model="queryParams.xmdh" placeholder="请选择" style="width:100%">
|
||||
<el-option />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Check" @click="handleSave">保存</el-button>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="tips ml10">颜色说明:</span> <span class="color-red">大于3SD</span> <span
|
||||
class="color-pink">大于2SD</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<el-tabs v-model="activeName" type="card" class="tabs_box">
|
||||
<el-tab-pane v-for="tab in tabList" :key="tab.key" :label="tab.label" :name="tab.key" />
|
||||
</el-tabs>
|
||||
|
||||
<div class="table-box">
|
||||
<CustomVxeTable class="mytable-style" ref="tableRef" :table-data="tableData" :columns="columns"
|
||||
:scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" :cell-style="cellStyleHd">
|
||||
<template #xmdh="{ row }">
|
||||
{{ row.xmdh }} {{ row.xmmc }}
|
||||
</template>
|
||||
<template #cs1="{ row }">
|
||||
<el-input v-model="row.cs1" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs2="{ row }">
|
||||
<el-input v-model="row.cs2" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs3="{ row }">
|
||||
<el-input v-model="row.cs3" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs4="{ row }">
|
||||
<el-input v-model="row.cs4" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs5="{ row }">
|
||||
<el-input v-model="row.cs5" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs6="{ row }">
|
||||
<el-input v-model="row.cs6" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs7="{ row }">
|
||||
<el-input v-model="row.cs7" class="full-width-input" />
|
||||
</template>
|
||||
</CustomVxeTable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getqcval } from '@/api/liswork/qualityControl/index'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
|
||||
const yq = defineModel<string>()
|
||||
const activeName = ref('1')
|
||||
const queryParams = ref({
|
||||
xmdh: '',
|
||||
zkrq: ref(dayjs().format('YYYY-MM-DD')),
|
||||
})
|
||||
|
||||
const tabList = [
|
||||
{ key: '1', label: '质控1' },
|
||||
{ key: '2', label: '质控2' }
|
||||
]
|
||||
|
||||
const tableData = ref([])
|
||||
const columns = ref([
|
||||
{ field: 'xmdh', title: '日期', resizable: true, width: 200 },
|
||||
{ field: 'cs1', title: '次数1', resizable: true, slotName: 'cs1' },
|
||||
{ field: 'cs2', title: '次数2', resizable: true, slotName: 'cs2' },
|
||||
{ field: 'cs3', title: '次数3', resizable: true, slotName: 'cs3' },
|
||||
{ field: 'cs4', title: '次数4', resizable: true, slotName: 'cs4' },
|
||||
{ field: 'cs5', title: '次数5', resizable: true, slotName: 'cs5' },
|
||||
{ field: 'cs6', title: '次数6', resizable: true, slotName: 'cs6' },
|
||||
{ field: 'cs7', title: '次数7', resizable: true, slotName: 'cs7' },
|
||||
{ field: 'zkbz', title: '靶数', resizable: true, align: 'center' },
|
||||
{ field: 'qcusepos', title: 'SD', resizable: true, align: 'center' },
|
||||
])
|
||||
const cellStyleHd = ({ row, column }: {
|
||||
row: any;
|
||||
column: any;
|
||||
}) => {
|
||||
const styleRules: any = {
|
||||
columnMap: { cs1: 'cs1', cs2: 'cs2', cs3: 'cs3', cs4: 'cs4', cs5: 'cs5', cs6: 'cs6', cs7: 'cs7' },
|
||||
colorRules: [
|
||||
{ min: 3, color: '#f00 !important' }, // 大于3:红色
|
||||
{ min: 2, max: 3, color: '#ffc0c0 !important' } // 2~3:粉色
|
||||
]
|
||||
}
|
||||
const targetField = styleRules.columnMap[column.title];
|
||||
|
||||
if (!targetField || row.qcusepos === 0) return {};
|
||||
|
||||
const deviation = Math.abs(row.zkbz - row[targetField]) / row.qcusepos;
|
||||
|
||||
for (const rule of styleRules.colorRules) {
|
||||
if (deviation > rule.min && (!rule.max || deviation < rule.max)) {
|
||||
return { background: rule.color };
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
const getXmList = () => {
|
||||
getqcval({ yq: yq.value, ...queryParams.value }).then((res: any) => {
|
||||
tableData.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
const handleSave = () => { }
|
||||
|
||||
watch(yq, (val) => {
|
||||
if (val) {
|
||||
// getXmList()
|
||||
}
|
||||
}, { immediate: true })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-box {
|
||||
margin-top: 5px;
|
||||
height: calc(100% - 145px);
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-family: SourceHanSansCN, SourceHanSansCN;
|
||||
font-size: 16px;
|
||||
color: #409eff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.color-red {
|
||||
background-color: #f00;
|
||||
color: #fff;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.color-pink {
|
||||
background-color: #ffc0c0;
|
||||
color: #fff;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,161 @@
|
||||
/**
|
||||
* @file index.vue 质控结果手工录入
|
||||
* @author: w
|
||||
* @since: 2026-01-05
|
||||
*/
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="handle-box mb5">
|
||||
<el-form>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-form-item label="日期:">
|
||||
<el-date-picker v-model="zkrq" type="date" value-format="YYYY-MM-DD" style="width:100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Check" @click="handleSave">保存</el-button>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="tips ml10">颜色说明:</span> <span class="color-red">大于3SD</span> <span
|
||||
class="color-pink">大于2SD</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<el-tabs v-model="activeName" type="card" class="tabs_box">
|
||||
<el-tab-pane v-for="tab in tabList" :key="tab.key" :label="tab.label" :name="tab.key" />
|
||||
</el-tabs>
|
||||
|
||||
<div class="table-box">
|
||||
<CustomVxeTable class="mytable-style" ref="tableRef" :table-data="tableData" :columns="columns"
|
||||
:scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" :cell-style="cellStyleHd">
|
||||
<template #xmdh="{ row }">
|
||||
{{ row.xmdh }} {{ row.xmmc }}
|
||||
</template>
|
||||
<template #cs1="{ row }">
|
||||
<el-input v-model="row.cs1" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs2="{ row }">
|
||||
<el-input v-model="row.cs2" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs3="{ row }">
|
||||
<el-input v-model="row.cs3" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs4="{ row }">
|
||||
<el-input v-model="row.cs4" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs5="{ row }">
|
||||
<el-input v-model="row.cs5" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs6="{ row }">
|
||||
<el-input v-model="row.cs6" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs7="{ row }">
|
||||
<el-input v-model="row.cs7" class="full-width-input" />
|
||||
</template>
|
||||
</CustomVxeTable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getqcval } from '@/api/liswork/qualityControl/index'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
|
||||
const yq = defineModel<string>()
|
||||
const activeName = ref('1')
|
||||
const zkrq = ref(dayjs().format('YYYY-MM-DD'))
|
||||
const tabList = [
|
||||
{ key: '1', label: '质控1' },
|
||||
{ key: '2', label: '质控2' }
|
||||
]
|
||||
|
||||
const tableData = ref([])
|
||||
const columns = ref([
|
||||
{ field: 'xmdh', title: '质控项目', resizable: true, slotName: 'xmdh', width: 200 },
|
||||
{ field: 'cs1', title: '次数1', resizable: true, slotName: 'cs1' },
|
||||
{ field: 'cs2', title: '次数2', resizable: true, slotName: 'cs2' },
|
||||
{ field: 'cs3', title: '次数3', resizable: true, slotName: 'cs3' },
|
||||
{ field: 'cs4', title: '次数4', resizable: true, slotName: 'cs4' },
|
||||
{ field: 'cs5', title: '次数5', resizable: true, slotName: 'cs5' },
|
||||
{ field: 'cs6', title: '次数6', resizable: true, slotName: 'cs6' },
|
||||
{ field: 'cs7', title: '次数7', resizable: true, slotName: 'cs7' },
|
||||
{ field: 'zkbz', title: '靶数', resizable: true, align: 'center' },
|
||||
{ field: 'qcusepos', title: 'SD', resizable: true, align: 'center' },
|
||||
])
|
||||
const cellStyleHd = ({ row, column }: {
|
||||
row: any;
|
||||
column: any;
|
||||
}) => {
|
||||
const styleRules: any = {
|
||||
columnMap: { cs1: 'cs1', cs2: 'cs2', cs3: 'cs3', cs4: 'cs4', cs5: 'cs5', cs6: 'cs6', cs7: 'cs7' },
|
||||
colorRules: [
|
||||
{ min: 3, color: '#f00 !important' }, // 大于3:红色
|
||||
{ min: 2, max: 3, color: '#ffc0c0 !important' } // 2~3:粉色
|
||||
]
|
||||
}
|
||||
const targetField = styleRules.columnMap[column.title];
|
||||
|
||||
if (!targetField || row.qcusepos === 0) return {};
|
||||
|
||||
const deviation = Math.abs(row.zkbz - row[targetField]) / row.qcusepos;
|
||||
|
||||
for (const rule of styleRules.colorRules) {
|
||||
if (deviation > rule.min && (!rule.max || deviation < rule.max)) {
|
||||
return { background: rule.color };
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
const getXmList = () => {
|
||||
getqcval({ yq: yq.value, zkrq: zkrq.value }).then((res: any) => {
|
||||
tableData.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
const handleSave = () => { }
|
||||
|
||||
|
||||
watch(yq, (val) => {
|
||||
if (val) {
|
||||
getXmList()
|
||||
}
|
||||
}, { immediate: true })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-box {
|
||||
margin-top: 5px;
|
||||
height: calc(100% - 145px);
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-family: SourceHanSansCN, SourceHanSansCN;
|
||||
font-size: 16px;
|
||||
color: #409eff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.color-red {
|
||||
background-color: #f00;
|
||||
color: #fff;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.color-pink {
|
||||
background-color: #ffc0c0;
|
||||
color: #fff;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
@ -1,163 +1,357 @@
|
||||
/**
|
||||
* @file index.vue 质控结果手工录入
|
||||
* @file index.vue 质控
|
||||
* @author: w
|
||||
* @since: 2026-01-05
|
||||
* @since: 2025-12-29
|
||||
*/
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="handle-box mb5">
|
||||
<el-form>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-form-item label="仪器:">
|
||||
<YQSelectTable v-model:data="yq" width="200px" clearable @get-data-value="getXmList" />
|
||||
</el-form-item>
|
||||
<el-row :gutter="20" class="main-row">
|
||||
<!-- 左侧树区域 -->
|
||||
<el-col :span="4" :xs="24" class="tree-col">
|
||||
<el-input v-model="deptName" placeholder="请输入仪器名称" clearable prefix-icon="Search" class="tree-search-input" />
|
||||
<el-radio-group v-model="radiotype" @change="radioChange">
|
||||
<el-radio value="1" size="large">仪器组</el-radio>
|
||||
<el-radio value="2" size="large">所有仪器</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="tree-container">
|
||||
<el-tree :data="deptOptions" :props="treeProps" expand-on-click-node :filter-node-method="filterNode"
|
||||
ref="deptTreeRef" node-key="id" highlight-current :expanded-keys="expandedKeys"
|
||||
@node-click="handleNodeClick">
|
||||
<!-- 自定义树节点模板:新增newflag徽章 -->
|
||||
<template #default="{ node, data }">
|
||||
<span class="tree-node-content">
|
||||
{{ node.label }}
|
||||
<!-- 新节点徽章:newflag=1时显示黄色"新"标 -->
|
||||
<el-badge v-if="data.newflag === '1'" value="new" class="new-node-badge" />
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="日期:">
|
||||
<el-date-picker v-model="jyrq" type="date" value-format="YYYY-MM-DD" style="width:100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="tips ml10">颜色说明:</span> <span class="color-red">大于3SD</span> <span
|
||||
class="color-pink">大于2SD</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="mb5">
|
||||
<el-button type="primary" plain icon="Check" @click="handleSave">保存</el-button>
|
||||
</div>
|
||||
<!-- 右侧列表区域 -->
|
||||
<el-col :span="20" :xs="24" class="table-col">
|
||||
<el-row :gutter="10" class="yq-title-row">
|
||||
<h1 class="yq-title">仪器: {{ yqmc }}</h1>
|
||||
</el-row>
|
||||
<el-tabs v-model="activeName" type="card" class="tabs_box">
|
||||
<el-tab-pane v-for="tab in tabList" :key="tab.key" :label="tab.label" :name="tab.key" />
|
||||
</el-tabs>
|
||||
|
||||
<div class="table-box">
|
||||
<CustomVxeTable class="mytable-style" ref="tableRef" :table-data="tableData" :columns="columns"
|
||||
:scrollYConfig="{ enabled: true, rSize: 30, height: '100%', }" :cell-style="cellStyleHd">
|
||||
<template #xmdh="{ row }">
|
||||
{{ row.xmdh }} {{ row.xmmc }}
|
||||
</template>
|
||||
<template #cs1="{ row }">
|
||||
<el-input v-model="row.cs1" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs2="{ row }">
|
||||
<el-input v-model="row.cs2" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs3="{ row }">
|
||||
<el-input v-model="row.cs3" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs4="{ row }">
|
||||
<el-input v-model="row.cs4" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs5="{ row }">
|
||||
<el-input v-model="row.cs5" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs6="{ row }">
|
||||
<el-input v-model="row.cs6" class="full-width-input" />
|
||||
</template>
|
||||
<template #cs7="{ row }">
|
||||
<el-input v-model="row.cs7" class="full-width-input" />
|
||||
</template>
|
||||
</CustomVxeTable>
|
||||
</div>
|
||||
<!-- 动态组件渲染 -->
|
||||
<component :is="currentComponent" :key="activeName" v-model="queryParams.yq" @updateTree="getDeptTree" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { queryOldxminfo } from '@/api/liswork/xtwh/xmReqItemVsApi'
|
||||
import YQSelectTable from '@/components/SelectTable/YQSelectTable/index.vue';
|
||||
import dayjs from 'dayjs'
|
||||
import { ref, watch, nextTick, computed } from 'vue'
|
||||
import { ElMessage, ElTree, TreeNode, ElMessageBox, ElBadge } from 'element-plus'
|
||||
import { paramList, paramTree, getdef, updateParam } from '@/api/liswork/xtwh/ComOpt'
|
||||
import { getFirstLetter } from '@/utils/pinyin'
|
||||
import { formatDict, getDictData, dictData } from '@/hooks';
|
||||
import { useCommonStore } from '@/store/modules/commonStore';
|
||||
import Project from './components/project.vue';
|
||||
import DateTime from './components/dateTime.vue';
|
||||
|
||||
|
||||
const mbStore = useCommonStore();
|
||||
// ========== TypeScript 类型定义 ==========
|
||||
interface InstrTreeNode {
|
||||
id: string
|
||||
label: string
|
||||
lx: string
|
||||
newflag: string // 新增newflag字段
|
||||
children?: InstrTreeNode[]
|
||||
}
|
||||
|
||||
const yq = ref(mbStore.defaultConfig.defaultinstr || '46')
|
||||
const activeName = ref('1')
|
||||
const jyrq = ref(dayjs().format('YYYY-MM-DD'))
|
||||
const tabList = [
|
||||
{ key: '1', label: '质控1' },
|
||||
{ key: '2', label: '质控2' }
|
||||
]
|
||||
interface ParamTreeResponse {
|
||||
code: string
|
||||
msg: string
|
||||
data: InstrTreeNode[]
|
||||
url: null | string
|
||||
method: null | string
|
||||
params: null | any
|
||||
problemId: null | string
|
||||
}
|
||||
|
||||
const tableData = ref([])
|
||||
const columns = ref([
|
||||
{ field: 'xmdh', title: '质控项目', resizable: true, slotName: 'xmdh', width: 200 },
|
||||
{ field: 'cs1', title: '次数1', resizable: true, slotName: 'cs1' },
|
||||
{ field: 'cs2', title: '次数2', resizable: true, slotName: 'cs2' },
|
||||
{ field: 'cs3', title: '次数3', resizable: true, slotName: 'cs3' },
|
||||
{ field: 'cs4', title: '次数4', resizable: true, slotName: 'cs4' },
|
||||
{ field: 'cs5', title: '次数5', resizable: true, slotName: 'cs5' },
|
||||
{ field: 'cs6', title: '次数6', resizable: true, slotName: 'cs6' },
|
||||
{ field: 'cs7', title: '次数7', resizable: true, slotName: 'cs7' },
|
||||
{ field: 'zkbz', title: '靶数', resizable: true, align: 'center' },
|
||||
{ field: 'qcusepos', title: 'SD', resizable: true, align: 'center' },
|
||||
])
|
||||
const cellStyleHd = ({ row, column }: {
|
||||
row: any;
|
||||
column: any;
|
||||
}) => {
|
||||
const styleRules: any = {
|
||||
columnMap: { cs1: 'cs1', cs2: 'cs2', cs3: 'cs3', cs4: 'cs4', cs5: 'cs5', cs6: 'cs6', cs7: 'cs7' },
|
||||
colorRules: [
|
||||
{ min: 3, color: '#f00 !important' }, // 大于3:红色
|
||||
{ min: 2, max: 3, color: '#ffc0c0 !important' } // 2~3:粉色
|
||||
]
|
||||
}
|
||||
const targetField = styleRules.columnMap[column.title];
|
||||
|
||||
if (!targetField || row.qcusepos === 0) return {};
|
||||
|
||||
const deviation = Math.abs(row.zkbz - row[targetField]) / row.qcusepos;
|
||||
|
||||
for (const rule of styleRules.colorRules) {
|
||||
if (deviation > rule.min && (!rule.max || deviation < rule.max)) {
|
||||
return { background: rule.color };
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
interface QueryParams {
|
||||
yq?: string | undefined
|
||||
xxdh?: string | undefined
|
||||
xxqz?: string | undefined
|
||||
groupId?: string | undefined
|
||||
}
|
||||
|
||||
|
||||
const getXmList = () => {
|
||||
queryOldxminfo({ yq: yq.value, }).then((res: any) => {
|
||||
tableData.value = res.data
|
||||
const radiotype = ref<string>("1")
|
||||
// ========== 响应式变量 ==========
|
||||
// 树相关
|
||||
const deptTreeRef = ref<InstanceType<typeof ElTree>>()
|
||||
const deptOptions = ref<InstrTreeNode[]>([])
|
||||
const deptName = ref<string>("")
|
||||
const yqmc = ref<string>("")
|
||||
const expandedKeys = ref<string[]>([])
|
||||
const isFiltering = ref<boolean>(false)
|
||||
const treeProps = ref({
|
||||
label: 'label',
|
||||
children: 'children',
|
||||
isLeaf: (data: Record<string, any>) => !data.children || data.children.length === 0
|
||||
})
|
||||
|
||||
// 查询参数
|
||||
const queryParams = ref<QueryParams>({
|
||||
yq: undefined,
|
||||
xxdh: undefined,
|
||||
xxqz: undefined,
|
||||
groupId: undefined
|
||||
})
|
||||
|
||||
const tabList = [
|
||||
{ key: 'Project', label: '按项目', component: Project },
|
||||
{ key: 'DateTime', label: '按日期', component: DateTime },
|
||||
|
||||
]
|
||||
const activeName = ref('Project')
|
||||
|
||||
// 计算当前要渲染的组件
|
||||
const currentComponent = computed(() => {
|
||||
return tabList.find(tab => tab.key === activeName.value)?.component || 'Project'
|
||||
})
|
||||
|
||||
const result: any = ref([])
|
||||
|
||||
const treeData = ref<InstrTreeNode[]>([])
|
||||
const radioChange = (val: string) => {
|
||||
if (val == "1") {
|
||||
deptOptions.value = treeData.value
|
||||
} else {
|
||||
deptOptions.value = result.value
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 树操作核心方法 ==========
|
||||
const forceExpandSingleNode = (nodeId: string): void => {
|
||||
expandedKeys.value = []
|
||||
nextTick(() => {
|
||||
expandedKeys.value = [nodeId]
|
||||
// deptTreeRef.value?.expand(nodeId, false)
|
||||
})
|
||||
}
|
||||
|
||||
const handleSave = () => { }
|
||||
const handleNodeClick = (data: InstrTreeNode): void => {
|
||||
if (isFiltering.value) {
|
||||
queryParams.value.groupId = data.id === "-1" ? undefined : data.id
|
||||
return
|
||||
}
|
||||
|
||||
getXmList()
|
||||
if (data.children && data.children.length > 0) {
|
||||
const isExpanded = expandedKeys.value.includes(data.id)
|
||||
expandedKeys.value = isExpanded ? [] : [data.id]
|
||||
!isExpanded && forceExpandSingleNode(data.id)
|
||||
} else {
|
||||
queryParams.value.yq = data.id
|
||||
yqmc.value = data.label
|
||||
}
|
||||
}
|
||||
// ========== 检索过滤逻辑 ==========
|
||||
const filterNode = (value: string, data: any, _node: TreeNode): boolean => {
|
||||
if (!value) return true
|
||||
|
||||
const keyword = value.trim().toUpperCase()
|
||||
const nodeLabel = data.label?.toLowerCase() || ''
|
||||
const nodePinyinFirst = data.label ? getFirstLetter(data.label).toUpperCase() : ''
|
||||
|
||||
const currentMatch = nodeLabel.includes(keyword.toLowerCase()) || nodePinyinFirst.includes(keyword)
|
||||
const childrenMatch = (data.children || []).some((child: any) => filterNode(value, child, _node))
|
||||
return currentMatch || childrenMatch
|
||||
}
|
||||
|
||||
const debounceFilter = (() => {
|
||||
let timer: number | undefined
|
||||
return (val: string): void => {
|
||||
clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
isFiltering.value = true
|
||||
deptTreeRef.value?.filter(val)
|
||||
|
||||
if (val) {
|
||||
expandedKeys.value = []
|
||||
const expandMatched = (nodes: InstrTreeNode[]) => {
|
||||
nodes.forEach(node => {
|
||||
if (filterNode(val, node, {} as TreeNode) && node.children?.length) {
|
||||
expandedKeys.value.push(node.id)
|
||||
}
|
||||
node.children && expandMatched(node.children)
|
||||
})
|
||||
}
|
||||
expandMatched(deptOptions.value)
|
||||
} else {
|
||||
expandedKeys.value = []
|
||||
}
|
||||
isFiltering.value = false
|
||||
}, 300)
|
||||
}
|
||||
})()
|
||||
|
||||
watch(deptName, debounceFilter, { immediate: false })
|
||||
|
||||
// ========== 业务逻辑 ==========
|
||||
const getDeptTree = async (): Promise<void> => {
|
||||
try {
|
||||
const response = await paramTree() as ParamTreeResponse
|
||||
result.value = []
|
||||
if (response.code === "0" && response.data) {
|
||||
for (let i = 0; i < response.data.length; i++) {
|
||||
const group = response.data[i];
|
||||
if (group.children && Array.isArray(group.children)) {
|
||||
for (let j = 0; j < group.children.length; j++) {
|
||||
result.value.push(group.children[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
treeData.value = response.data
|
||||
radioChange('1')
|
||||
if (!expandedKeys.value.length) {
|
||||
// 默认展开第一个一级节点的子级
|
||||
nextTick(() => {
|
||||
if (mbStore.defaultConfig.defaultinstr) {
|
||||
queryParams.value.yq = mbStore.defaultConfig.defaultinstr
|
||||
yqmc.value = result.value.find((item: any) => item.id === queryParams.value.yq)?.label
|
||||
deptTreeRef.value?.setCurrentKey(queryParams.value.yq)
|
||||
} else {
|
||||
if (deptOptions.value.length > 0) {
|
||||
const firstLevelNode = deptOptions.value[0]
|
||||
if (firstLevelNode && firstLevelNode.children && firstLevelNode.children.length > 0) {
|
||||
expandedKeys.value = [firstLevelNode.id]
|
||||
const firstChildNode = firstLevelNode.children[0]
|
||||
queryParams.value.yq = firstChildNode.id
|
||||
yqmc.value = firstChildNode.label
|
||||
deptTreeRef.value?.setCurrentKey(queryParams.value.yq)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
} else {
|
||||
ElMessage.warning(response.msg || "获取树数据失败")
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error(`获取树数据异常:${(error as Error).message}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
})
|
||||
// ========== 初始化 ==========
|
||||
getDeptTree()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-box {
|
||||
margin-top: 5px;
|
||||
height: calc(100% - 125px);
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
width: 100%;
|
||||
height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tips {
|
||||
.main-row {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tree-col {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
.tree-container {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background: #fff;
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
|
||||
// 核心:树选中节点样式
|
||||
:deep(.el-tree) {
|
||||
--el-tree-node-transition-duration: 0.2s;
|
||||
|
||||
.el-tree-node__children {
|
||||
transition: all var(--el-tree-node-transition-duration) ease-in-out;
|
||||
}
|
||||
|
||||
.el-tree-node__expand-icon.is-leaf {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// 选中节点的背景色(蓝色)+ 文字白色
|
||||
.el-tree-node.is-current>.el-tree-node__content {
|
||||
background-color: #409eff !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
// 选中节点hover样式(加深蓝色)
|
||||
.el-tree-node.is-current>.el-tree-node__content:hover {
|
||||
background-color: #1e88e5 !important;
|
||||
}
|
||||
|
||||
// 树节点内容容器样式
|
||||
.tree-node-content {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px; // 徽章和文字间距
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// 新节点徽章样式
|
||||
.new-node-badge {
|
||||
--el-badge-font-size: 10px !important;
|
||||
--el-badge-height: 16px !important;
|
||||
--el-badge-padding: 0 4px !important;
|
||||
--el-badge-warning-color: #FFEC24 !important; // 黄色徽章
|
||||
--el-badge-warning-bg-color: #fff7e6 !important; // 浅黄色背景
|
||||
--el-badge-border-radius: 2px !important; // 圆角优化
|
||||
|
||||
// 徽章文字样式
|
||||
.el-badge__content {
|
||||
font-size: 10px !important;
|
||||
line-height: 16px !important;
|
||||
padding: 0 4px !important;
|
||||
height: 16px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-col {
|
||||
height: 100%;
|
||||
|
||||
// 仪器标题行样式
|
||||
.yq-title-row {
|
||||
margin-bottom: 8px;
|
||||
|
||||
.yq-title {
|
||||
font-family: SourceHanSansCN, SourceHanSansCN;
|
||||
font-size: 16px;
|
||||
color: #409eff;
|
||||
font-size: 16px; // 缩小h1字体(默认24px→16px)
|
||||
color: #409eff; // 蓝色(Element Plus主题色)
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.color-red {
|
||||
background-color: #f00;
|
||||
color: #fff;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.color-pink {
|
||||
background-color: #ffc0c0;
|
||||
color: #fff;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 5px;
|
||||
margin: 0; // 清除默认margin
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user