lis8.0-vue3/src/views/liswork/work/index copy.vue
2025-11-03 12:12:47 +08:00

871 lines
28 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-row :gutter="10" class="compact-form">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">新增明细</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="delResultFlag" @click="handleDelete"
v-hasPermi="['system:dict:remove']">删除明细</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="changeResultFlag" @click="handleUpdate"
v-hasPermi="['system:dict:edit']">保存</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" @click="handleCheck0"
v-hasPermi="['system:dict:import']">初报</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Download" @click="handleCheck"
v-hasPermi="['system:dict:import']">初审</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Upload" @click="handleUnCheck"
v-hasPermi="['system:dict:export']">取消初审</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Download" @click="handleCheck"
v-hasPermi="['system:dict:import']">审核</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Upload" @click="handleUnCheck"
v-hasPermi="['system:dict:export']">取消审核</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="Edit" @click="handleUnCheck"
v-hasPermi="['system:dict:export']">预览</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="Edit" @click="handleUnCheck"
v-hasPermi="['system:dict:export']">打印</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Upload" @click="handleUnCheck"
v-hasPermi="['system:dict:export']">上一个</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Download" @click="handleUnCheck"
v-hasPermi="['system:dict:export']">下一个</el-button>
</el-col>
</el-row>
<el-row :gutter="10" class="compact-form">
<el-form :model="queryParams" ref="queryRef" :inline="true" :rules="rules">
<el-form-item class="compact-form" label="" label-width="0px" prop="ybh">
<el-col :span="1.5">样本编号</el-col>
<el-col :span="4.5">
<el-input v-model="queryParams.ybh" clearable placeholder="样本编号" prefix-icon="Search"
@keyup.enter="handleQueryYbh" @clear="handleQueryYbh" />
</el-col>
<el-col :span="1.5">
<div>检验日期</div>
</el-col>
<el-col :span="3.5">
<el-date-picker v-model="queryParams.jyrq" type="date" label-width="20px" placeholder="检验日期"
value-format="YYYY-MM-DD" :clearable="false" @change="handleQuery"></el-date-picker>
</el-col>
<el-col :span="1.5">
<div>部门组别</div>
</el-col>
<el-col :span="3.5">
<!-- <Ddlb v-model="queryParams.instrGroup" :options="instrGroupOptions" placeholder="请选择部门组别"
@change="handleinstrGroupChange" :value="setInstrGroup" label-width="40px" /> -->
<el-select v-model="queryParams.instrGroup" placeholder="请选择" style="width:140px"
@change="handleinstrGroupChange">
<el-option v-for="item in instrGroupOptions" :key="item.zddh" :label="item.zdmc" :value="item.zddh" />
</el-select>
</el-col><el-col :span="1">
<div>仪器</div>
</el-col>
<el-col :span="4">
<Ddlb v-model="queryParams.yq" :options="instrOptions" placeholder="请选择仪器" @change="handleYqChange"
:value="setInstr" />
</el-col>
</el-form-item>
</el-form>
</el-row>
<el-row :gutter="5">
<el-col :span="5" :xs="24">
<div class="compact-form">
<LabPatForm v-model:labPat="labPat" :labPatKey="queryParams" ref="labPatRef" @save="savelabPat"
@reset="resetlabPat" />
</div>
</el-col>
<el-col :span="8" :xs="24">
<div class="compact-form">
<LabResultForm ref="labResultRef" :tableData="labResuts" :tableKey="queryParams"
:is-data-refreshed="isDataRefreshed" @add="addLabResult" @delete="deleteLabResults" @edit="editLabResult"
@delfalg="setdelResultFlag" @changefalg="setchangeResultFlag" @fetchLabResults="fetchLabResults" />
</div>
</el-col>
<el-col :span="11" :xs="24">
<div class="compact-form">
<LabPatListForm :labPatList="labPatList" :labPatKey="queryParams" :total="total" @select="selectJob"
@search="searchJobs" @page-change="pageChange" />
</div>
</el-col>
<ItemInput ref="itemDictRef" v-model="selectedItemValue" :label-value.sync="selectedItemLabel"
:dict-type="'LAB_ITEM'" :fetch-dict="fetchLabItemDict" :dialog-title="'选择检验项目'" :disabled="false"
:load-on-mount="false" :table-data.sync="labResuts" class="hidden-dict-input" @select="handleItemSelect" />
</el-row>
<!-- 引入弹窗组件 -->
<unconfirmlog v-model:visible="dialogVisible" :reason-text="currentReason" @onConfirm="unconfirmlogConfirm"
@onCancel="unconfirmlogCancel" />
<CheckUser v-model:visible="showCheckUser" :title="checktitle"
:validation-rules="{ userIdMinLength: 4, passwordMinLength: 6 }" @onConfirm="handleAuthSuccess"
@onCancel="handleAuthCancel" />
<uploadwarning v-model:visible="showuploadwarning" :msgdata="warningMsgdata" :showRules=1
@onupload="handleWarningSuccess" @onCancel="handleWarningCancel" />
</div>
</template>
<script setup>
import {
getDate,
queryLabPatList,
queryLabResults,
updateLabPat,
queryLabPat,
check2, uncheck2, unconfirmlog, checkuser, reglimit, queryXmInfo
} from "../../../api/liswork/work/LisWork";
import { querylabInstrList, querylabInstrListByLisgroup } from "../../../api/liswork/dict/LabInstr";
import { getComDicts, queryComDictListService } from "../../../api/liswork/dict/ComDict";
import LabPatForm from './components/labpat.vue'
import LabResultForm from './components/labresult.vue'
import LabPatListForm from './components/labpatlist.vue'
import Unconfirmlog from './components/unconfirmlog.vue'
import Ddlb from './components/ddlb.vue'
import CheckUser from './components/CheckUser.vue'
import uploadwarning from './components/uploadwarning.vue'
import UCKDictInput from './components/DictInput.vue';
import { ElMessage, ElMessageBox } from "element-plus";
import ItemInput from "@/components/projectDetails/index.vue";
const showuploadwarning = ref(false);
const single = ref(true);
const delResultFlag = ref(true);
const changeResultFlag = ref(true);
const loading = ref(true);
const instrGroupOptions = ref([]);
const instrOptions = ref([]);
const labPatList = ref([])
const patdata = reactive({
form: {},
labPat: {
// jyrq: '',
// yq: '',
// ybh: '',
// brly: '',
// jzbz: '',
// brdh: '',
// brxm: '',
// brxb: '',
// nl: null,
// nldw: '1',
// ksdh: '',
// ch: '',
// sjys: '',
// sqsj: '',
// cyrq: '',
// dysj: '',
// zd: '',
// bz: '',
// yhdh: '',
// hdys: '',
// jgbz: '0',
// yblx: ''
},
rules: {}
});
const { labPat } = toRefs(patdata);
const labResuts = ref([])
const total = ref(0)
const currentLabResults = ref([])
const searchText = ref('')
const pageSize = ref(10)
const currentPage = ref(1)
const setInstrGroup = ref('')
const setInstr = ref('')
const yq0 = ref('')
const jyrq0 = ref('')
const ybh0 = ref('')
const checktitle = ref('操作人身份验证')
const nextstepname = ref('')
const warningMsgdata = ref('')
const checkuserid = ref('')
const querydata = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
jyrq: formatDate(new Date()),
yq: '1',
ybh: '1',
days: 1,
instrGroup: '02',
problemId: 0,
yhdh: '46'
},
rules: {
ybh: [],
jyrq: [],
instrGroup: [],
yq: [],
}
,
});
// 父组件:新增“数据刷新标记”,初始为false
const isDataRefreshed = ref(false);
// 新增:控制标记的重置(避免持续触发子组件缓存更新)
const resetDataRefreshFlag = () => {
// 延迟重置,确保子组件有足够时间接收标记并更新缓存
setTimeout(() => {
isDataRefreshed.value = false;
}, 100);
};
const { queryParams, form, rules } = toRefs(querydata);
//子组件labResult.vue
const labResultRef = ref(null);
//子组件labPatRef.vue
const labPatRef = ref(null);
// 弹窗控制状态
const dialogVisible = ref(false);
const showCheckUser = ref(false);
// 弹窗显示的原因文本
const currentReason = ref('');
// 存储需要传递给API的参数
const apiParams = ref(null);
// 处理弹窗确认(获取返回值后调用API)
const unconfirmlogConfirm = async (inputValue) => {
try {
console.log('用户输入的操作原因:', inputValue);
// 调用API,携带用户输入的原因和之前保存的参数
loading.value = true;
unconfirmlog({ ...queryParams.value, reason: inputValue }).then(response => {
console.log('response:', response)
loading.value = false;
if (response.code == "0") {
runnextstepname();
}
}).catch(error => {
console.error('审核失败', error);
loading.value = false;
});
// API调用成功后的处理
console.log('操作成功:', response);
// 可以添加成功提示、刷新数据等逻辑
} catch (error) {
console.error('操作失败:', error);
// 错误处理
} finally {
// 重置参数
apiParams.value = null;
}
};
// 处理弹窗取消
const unconfirmlogCancel = () => {
console.log('用户取消了操作');
// 重置参数
apiParams.value = null;
cancalnextstepname();
};
// 处理验证成功
const handleAuthSuccess = async (userInfo) => {
console.log('验证信息:', userInfo);
// 调用后端接口进行实际验证
loading.value = true;
checkuser({ yhdh: userInfo.userId, mm: userInfo.password }).then(response => {
console.log('response:', response)
loading.value = false;
console.log('userInfo:', userInfo);
if (response.code == "0") {
checkuserid.value = userInfo.userId;
runnextstepname();
}
}).catch(error => {
console.error('验证接口调用失败', error);
loading.value = false;
checkuserid.value = '';
});
};
// 处理取消验证
const handleAuthCancel = () => {
console.log('用户取消了验证');
// 执行取消后的操作
cancalnextstepname();
};
// 处理危急值登记
const handleWarningSuccess = async (userInfo) => {
console.log('处理危急值登记:', userInfo);
// 调用后端接口进行实际验证
loading.value = true;
reglimit({ ...queryParams.value, qrr: userInfo.userId, tzfs: userInfo.uploadTp, phone: userInfo.phone }).then(response => {
console.log('危急值response:', response.code);
loading.value = false;
if (response.code == "0") {
runnextstepname();
}
if (response.code == "4") {
ElMessageBox.confirm(response.msg, '系统提示', { confirmButtonText: '是', cancelButtonText: '否', type: 'warning' }).then(() => {
queryParams.value.problemId = queryParams.value.problemId + 1;
handleWarningSuccess(userInfo);
}).catch(() => {
runnextstepname();
});
}
}).catch(error => {
console.error('处理危急值登记接口调用失败', error);
loading.value = false;
});
};
// 处理取消验证
const handleWarningCancel = () => {
console.log('用户取消了登记');
// 执行取消后的操作
cancalnextstepname();
};
// 页面载入时获取基本默认值参数信息,后面有扩展需要都放这里
const loadYqConfig = async () => {
// 使用 .value 获取响应式数据的值
jyrq0.value = '2025-08-19';//formatDate(new Date());
yq0.value = 'COBAS';
ybh0.value = '1';
querydata.queryParams.jyrq = jyrq0.value;
querydata.queryParams.yq = 46;
querydata.queryParams.ybh = ybh0.value;
querydata.queryParams.instrGroup = '02';
}
// 加载部门下拉列表
function loadinstrGroupOptions() {
loading.value = true;
getComDicts({ zdlb: 'GROUP' }).then(response => {
instrGroupOptions.value = response.data
loading.value = false;
setInstrGroup.value = querydata.queryParams.instrGroup;
});
loadYqConfig();
}
// 部门组别变化时更新仪器下拉框
const handleinstrGroupChange = (value) => {
queryParams.value.instrGroup = value
// 清空仪器选择并重新加载
// queryParams.value.yq = '';
instrOptions.value = [];
// 加载对应组别的仪器数据
loadinstrOptions();
}
// 仪器变化时的处理函数
const handleYqChange = (value) => {
if (value === null || value === '') {
queryParams.value.yq = yq0.value;
setInstr.value = yq0.value;
} else {
yq0.value = value;
queryParams.value.yq = value;
handleQuery();
}
}
// 加载仪器下拉列表
const loadinstrOptions = () => {
loading.value = true;
querylabInstrListByLisgroup({ pageNum: 1, pageSize: 100, lisgroup: queryParams.value.instrGroup })
.then(response => {
if (response.rows) {
instrOptions.value = toRaw(response.rows).map(item => ({
id: item.yq.trimEnd(),
text: item.yqmc
}))
loading.value = false;
setInstr.value = querydata.queryParams.yq;
} else {
throw new Error('仪器响应数据为空');
}
})
.catch(error => {
console.error('仪器数据加载失败', error);
loading.value = false;
});
// console.error('aaa', queryParams.value);
//console.log('test22:', instrOptions.value);
}
//获取服务器时间
const serverDate = computed(() => {
return formatDate(new Date());
});
//切换仪器或检验日期后重置页码
function resetData() {
queryParams.value = {
pageNum: 1,
pageSize: 15,
}
searchText.value = ''
currentPage.value = 1
pageSize.value = 15
}
//载入样本列表(右边labpatlist.vue组件)
const fetchlabPatList = async (search = '', page = 1, size = 15) => {
loading.value = true;
queryParams.value.pageSize = size;
queryParams.value.pageNum = page;
queryLabPatList(queryParams.value).then(response => {
labPatList.value = response.rows;
total.value = response.total;
loading.value = false;
}).catch(error => {
console.error('列表数据加载失败', error);
loading.value = false;
});
}
//载入样本编辑表单(左边labpat.vue组件)
const fetchLabPat = async () => {
loading.value = true;
queryLabPat(queryParams.value).then(response => {
labPat.value = response.data;
loadingPatLabel();
loading.value = false;
}).catch(error => {
console.error('列表数据加载失败', error);
loading.value = false;
});
}
//载入样本结果表单(中间labresult.vue组件)
const fetchLabResults = async () => {
loading.value = true;
// console.log('test', queryParams.value);
queryLabResults({ jyrq: queryParams.value.jyrq, yq: queryParams.value.yq, ybh: queryParams.value.ybh }).then(response => {
// console.log('RESULT:', response);
labResuts.value = response.data;
loading.value = false;
// 关键:设置“数据刷新标记”为true(删除后数据变化,需更新子组件缓存)
isDataRefreshed.value = true;
// 数据刷新后重置标记
resetDataRefreshFlag();
}).catch(error => {
console.error('列表数据加载失败', error);
loading.value = false;
});
}
//保存样本表单
const savelabPat = async (labPat) => {
// 实际项目中这里应该是API调用
console.log('保存主表:', labPat)
if (!labPat.id) {
// 新增
labPat.id = Date.now()
labPatList.value.unshift({ ...labPat })
} else {
// 更新
const index = labPatList.value.findIndex(item => item.id === labPat.id)
if (index !== -1) {
labPatList.value.splice(index, 1, { ...labPat })
}
}
alert('保存成功')
}
//重置结果表单
const resetlabPat = () => {
labResuts.value = []
currentLabResults.value = []
}
//新增结果列
const addLabResult = async (LabResult) => {
// 实际项目中这里应该是API调用
console.log('添加明细:', LabResult)
if (!LabResult.xh) {
LabResult.xh = currentLabResults.value.length + 1
}
const index = currentLabResults.value.findIndex(item => item.xh === LabResult.xh)
if (index !== -1) {
currentLabResults.value.splice(index, 1, { ...LabResult })
} else {
currentLabResults.value.push({ ...LabResult })
}
alert('添加成功')
}
//删除结果列
const deleteLabResults = async (xhList) => {
// 实际项目中这里应该是API调用
console.log('删除明细:', xhList)
currentLabResults.value = currentLabResults.value.filter(item => !xhList.includes(item.xh))
alert('删除成功')
}
//修改结果列
const editLabResult = (LabResult) => {
console.log('编辑明细:', LabResult)
// 在表单中填充数据
// 这里不需要做任何事情,因为组件已经绑定了数据
}
//样本列表点击切换样本信息,同步载入左边样本信息表单和中间结果表单
const selectJob = async (job) => {
// 复制选中的job数据到当前编辑状态
// Object.assign(labPat.value, {...job})
queryParams.value.jyrq = job.jyrq;
queryParams.value.yq = job.yq;
queryParams.value.ybh = job.ybh;
checkQuery()
isDataRefreshed.value = true;
//await nextTick();
// 获取对应的明细数据
await fetchLabPat();
await fetchLabResults();
resetDataRefreshFlag();
}
//样本列表检索时刷新列表信息
const searchJobs = async (text, page, size) => {
searchText.value = text
currentPage.value = page
pageSize.value = size
loadlabPatList()
}
//样本列表翻页时刷新列表信息
const pageChange = async (page, size) => {
currentPage.value = page
pageSize.value = size
loadlabPatList()
}
//刷新样本列表方法封装
const loadlabPatList = async () => {
await fetchlabPatList(searchText.value, currentPage.value, pageSize.value)
}
/** 查询服务器时间 */
function getdate() {
getDate().then(response => {
serverDate.value = formatDate(new Date(response.data));
})
}
//日期格式化
function formatDate(date) {
const year = date.getFullYear();
// 月份是从0开始的,所以要加1
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day} 00:00:00`;
}
const setdelResultFlag = (value) => {
delResultFlag.value = value;
}
const setchangeResultFlag = (value) => {
changeResultFlag.value = value;
}
//新增
const handleAdd = () => {
// labResultRef.value?.handleAdd();
openItemDictDialog();
};
function handleUpdate() {
}
function handleDelete() {
labResultRef.value?.handleBatchDelete();
}
function loadingPatLabel() {
// labPatRef.value?.loadingLabel();
}
function handleCheck0() {
}
function handleCheck() {
queryParams.value.problemId = 0;
nextstepname.value = 'handleCheck2';
queryParams.value.yhdh = checkuserid.value
if (queryParams.value.yhdh == '') {
checktitle.value = '审核人工号密码验证'
showCheckUser.value = true;
} else {
handleCheck2();
}
}
function handleCheck2() {
loading.value = true;
console.log('queryParams:', queryParams.value)
queryParams.value.yhdh = checkuserid.value
check2(queryParams.value).then(response => {
loading.value = false;
if (response.code == "4" && response.problemId === 4) {
console.log('queryParams1111:', queryParams.value)
nextstepname.value = 'handleCheck2';
queryParams.value.problemId = response.problemId;
// 保存需要传递给API的参数
apiParams.value = queryParams;
// 设置弹窗显示的原因文本
warningMsgdata.value = response.msg;
// 显示弹窗
showuploadwarning.value = true;
}
console.log('response:', response)
}).catch(error => {
console.error('审核失败', error);
loading.value = false;
});
}
function handleUnCheck() {
queryParams.value.problemId = 0;
nextstepname.value = 'handleuncheck2';
queryParams.value.yhdh = checkuserid.value
if (queryParams.value.yhdh == '') {
checktitle.value = '取消审核人工号密码验证'
showCheckUser.value = true;
} else {
handleuncheck2();
}
}
function handleuncheck2() {
loading.value = true;
queryParams.value.yhdh = checkuserid.value
uncheck2(queryParams.value).then(response => {
loading.value = false;
if (response.code == "4") {
nextstepname.value = 'handleuncheck2';
queryParams.value.problemId = response.problemId;
// 保存需要传递给API的参数
apiParams.value = queryParams;
// 设置弹窗显示的原因文本
currentReason.value = response.msg;
// 显示弹窗
dialogVisible.value = true;
}
}).catch(error => {
console.error('解除审核失败', error);
loading.value = false;
});
}
function handlePrint() {
}
function handleQueryDetail() {
}
//切换仪器或检验日期时载入
const handleQuery = async () => {
if (checkQuery() === false) return false
// resetData();
await loadlabPatList();
//暂时默认打开1号样本,后面由参数控制
querydata.queryParams.ybh = '1';
isDataRefreshed.value = true;
await handleQueryYbh();
resetDataRefreshFlag();
}
//切换样本号时载入
const handleQueryYbh = async () => {
if (checkQuery() === false) return false
isDataRefreshed.value = true;
await fetchLabPat();
await fetchLabResults();
resetDataRefreshFlag();
}
//主键空置拦截
function checkQuery() {
if (querydata.queryParams.jyrq === '' || querydata.queryParams.jyrq === null) {
querydata.queryParams.jyrq = jyrq0.value
return false;
}
if (querydata.queryParams.yq === '' || querydata.queryParams.yq === null) {
querydata.queryParams.yq = yq0.value
return false;
}
if (querydata.queryParams.ybh === '' || querydata.queryParams.ybh === null) {
querydata.queryParams.ybh = ybh0.value
return false;
}
jyrq0.value = querydata.queryParams.jyrq
yq0.value = querydata.queryParams.yq
ybh0.value = querydata.queryParams.ybh
}
function runnextstepname() {
if (nextstepname.value != '') {
switch (nextstepname.value) {
case 'handleuncheck2':
handleuncheck2();
break;
case 'handleCheck2':
handleCheck2();
break;
default:
// 当所有case都不匹配时执行(可选)
}
}
}
function cancalnextstepname() {
if (nextstepname.value != '') {
switch (nextstepname.value) {
case 'handleuncheck2':
ElMessage({ message: '取消操作,撤销审核失败!', type: 'error' })
break;
case 'handleCheck2':
ElMessage({ message: '取消操作,审核失败!', type: 'error' })
break;
default:
// 当所有case都不匹配时执行(可选)
}
}
}
// -------------------------- 项目选择相关变量 --------------------------
const itemDictRef = ref(null); // DictInput组件引用
const selectedItemValue = ref(""); // 选择的项目编码xmdh
const selectedItemLabel = ref(""); // 选择的项目名称xmmc
// -------------------------- 1. 项目字典API调用方法(传递给DictInput) --------------------------
/**
* 项目字典加载方法:适配DictInput的fetchDict参数格式
* @param {String} dictType - 父组件传递的dict-type(无实际意义,可忽略)
* @returns {Promise<Array>} - 项目字典数据(格式需匹配DictInput要求:{value, label})
*/
// 父组件中:完善的项目字典加载方法
const fetchLabItemDict = async (dictType) => {
// 日志1:确认方法被调用
try {
// 1. 验证必要参数(如当前仪器yq)
if (!queryParams.value.yq) {
console.error("[fetchLabItemDict] 缺少必要参数:yq(仪器)");
ElMessage.error("请先选择仪器");
return [];
}
// 日志2:打印请求参数
const requestParams = {
pageNum: 1,
pageSize: 1000, // 加载足够多的项目
yq: queryParams.value.yq, // 当前选中的仪器
};
// 2. 调用API(确保queryXmInfo是正确的API方法)
const response = await queryXmInfo(requestParams);
// 日志3:打印原始响应
// 3. 验证响应格式
if (!response) {
throw new Error("API返回为空");
}
if (response.code !== "0") { // 假设0为成功状态码
throw new Error(`API返回错误:${response.msg || "未知错误"}`);
}
if (!Array.isArray(response.data)) {
throw new Error(`API返回data不是数组,实际为:${typeof response.data}`);
}
// 4. 格式化数据(适配DictInput的{value, label}结构)
const formattedData = response.data.map((item, index) => {
// 验证项目数据完整性
if (!item.xmdh) {
console.warn(`[fetchLabItemDict] 第${index}条数据缺少xmdh(项目编码):`, item);
}
if (!item.xmmc) {
console.warn(`[fetchLabItemDict] 第${index}条数据缺少xmmc(项目名称):`, item);
}
return {
value: item.xmdh || `未知编码_${index}`, // 确保value存在
label: item.xmmc || `未知名称_${index}`, // 确保label存在
dw: item.dw || "", // 单位(可选)
refs: item.refs || "", // 参考值(可选)
};
});
// 日志4:打印格式化后的数据量
return formattedData;
} catch (error) {
// 日志5:捕获并显示错误
console.error(`[fetchLabItemDict] 加载失败:`, error.message);
ElMessage.error(`项目字典加载失败:${error.message}`);
return []; // 失败时返回空数组,避免弹窗报错
}
};
// -------------------------- 2. 打开项目选择弹窗 --------------------------
const openItemDictDialog = () => {
if (itemDictRef.value && typeof itemDictRef.value.openDictSelector === 'function') {
itemDictRef.value.openDictSelector(); // 确保方法存在再调用
} else {
console.warn("DictInput组件未加载完成或方法未暴露");
}
};
// -------------------------- 3. 处理项目选择结果:传递给labresult子组件新增行 --------------------------
const handleItemSelect = async (selectedItem) => {
// 1. 构造新增行数据
const newRow = {
id: `temp_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
xmdh: selectedItem.value,
xmmc: selectedItem.label,
dw: selectedItem.dw || "",
refs: selectedItem.refs || "",
jyrq: queryParams.value.jyrq,
yq: queryParams.value.yq,
ybh: queryParams.value.ybh,
};
// 2. 调用子组件方法新增行(仅一次)
if (labResultRef.value && typeof labResultRef.value.addRowFromDict === 'function') {
await labResultRef.value.addRowFromDict(newRow);
ElMessage.success(`已新增项目:${newRow.xmmc}`);
}
};
//打开页面需要先初始化的内容都放这里
onMounted(() => {
loadYqConfig();
loadinstrGroupOptions(); // 页面加载时获取部门组别数据
loadinstrOptions();
loadlabPatList();
})
</script>
<style scoped lang="scss">
.compact-form .el-form-item {
padding: 5px;
margin-bottom: 5px;
}
.compact-form .el-form-item__label {
padding-bottom: 0px;
}
.card-content {
max-height: 450px;
/* 设置最大高度 */
overflow-y: auto;
/* 超出高度时显示垂直滚动条 */
padding: 5px;
/* 保持与卡片默认一致的内边距 */
}
.clickable:hover {
cursor: pointer;
/* 鼠标悬停时显示手型 */
transition: all 0.3s;
/* 平滑过渡效果 */
color: blue;
}
.hidden-dict-input {
/* 定位到屏幕左侧外,视觉上不可见 */
position: absolute;
left: -9999px;
top: auto;
/* 防止占用布局空间 */
width: 1px;
height: 1px;
/* 防止意外聚焦 */
outline: none;
}
</style>