This commit is contained in:
jiangs 2025-11-06 18:22:21 +08:00
commit c2bf4656eb
17 changed files with 1295 additions and 142 deletions

View File

@ -354,5 +354,77 @@ export function unLockSample(query?: Object) {
params: query
})
}
// 查看电子病历
export function emrquery(query?: Object) {
return request({
url: '/liswork/emrquery',
method: 'get',
params: query
})
}
// 查看患者360视图
export function allPatquery(query?: Object) {
return request({
url: '/liswork/allpatquery',
method: 'get',
params: query
})
}
// 双工流水线
export function datalink(query?: Object) {
return request({
url: '/liswork/datalink',
method: 'get',
params: query
})
}
// 批量更改流水线状态
export function changeLinkList(query?: Object) {
return request({
url: '/liswork/changelinklist',
method: 'post',
data: query
})
}
// 清除所有未做项目
export function clearnotComplete(query?: Object) {
return request({
url: '/liswork/clearnotcomplete',
method: 'get',
params: query
})
}
// 查看备份数据
export function viewBackup(query?: Object) {
return request({
url: '/liswork/viewbackup',
method: 'get',
params: query
})
}
// 未建项目结果
export function noiteMresult(query?: Object) {
return request({
url: '/liswork/noitemresult',
method: 'get',
params: query
})
}
// 项目与通道号对照
export function setitemInter(query?: Object) {
return request({
url: '/liswork/setiteminter',
method: 'get',
params: query
})
}
// 清除打印标志
export function clearPrintflag(query?: Object) {
return request({
url: '/liswork/clearprintflag',
method: 'get',
params: query
})
}

View File

@ -173,6 +173,32 @@ aside {
}
}
.compact-form {
flex: 1;
position: relative;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
.el-form-item {
margin-bottom: 0px;
}
.el-form-item__label {
padding-bottom: 0px;
color: #08355E;
font-size: 12px;
}
// pointer-events: none;
:deep(.el-radio__label) {
color: #08355E;
}
}
.filter-container {
padding-bottom: 10px;

View File

@ -158,18 +158,28 @@
.el-table__body-wrapper .el-table-column--selection>.cell {
padding: 0 !important;
height: 30px;
line-height: 30px;
}
.cell.el-tooltip {
padding: 0 !important;
height: 30px;
line-height: 30px;
}
.el-table-header-cell .cell {
padding: 0 !important;
}
.el-table--default .cell {
padding: 0 !important;
}
.el-table__cell {
padding: 0 !important;
height: 30px;
line-height: 30px;
}
.el-checkbox {
@ -222,13 +232,19 @@
}
.el-select__wrapper.is-disabled {
background-color: #ccc !important;
color: #000 !important;
background-color: #dfdcdc !important;
}
.el-select-dropdown__item.is-hovering {
background-color: #a4beef !important;
}
.el-input.is-disabled .el-input__wrapper {
background-color: #ccc !important;
color: #000 !important;
background-color: #dfdcdc !important;
}
.el-input.is-disabled .el-input__inner {
-webkit-text-fill-color: #4e4c4c
}
@ -277,12 +293,12 @@
}
.vxe-table--render-default .vxe-body--column {
height: 1.4375rem !important;
line-height: 1.4375rem !important;
height: 1.875rem !important;
line-height: 1.875rem !important;
}
.el-checkbox {
height: 1.4375rem !important;
height: 1.875rem !important;
}
}
@ -302,7 +318,7 @@
// 滚动条
.mytable-style ::-webkit-scrollbar {
width: .5rem;
width: .6rem;
height: .5rem;
}

View File

@ -115,14 +115,17 @@ const handleKeyDown = (e: KeyboardEvent) => {
onMounted(() => {
document.addEventListener('click', handleClickOutside);
document.addEventListener('keydown', handleKeyDown);
// 关闭所有菜单
emitter.on('closeAllContextMenus', () => {
if (visible.value) {
hideMenu();
}
});
document.addEventListener('click', handleClickOutside);
document.addEventListener('keydown', handleKeyDown);
});
// 卸载时移除事件监听

View File

@ -3,8 +3,8 @@
<!-- 字典选择弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="30vw" :close-on-click-modal="false" :draggable="true"
@close="handleDialogClose">
<el-input v-model="searchKey" placeholder="搜索(支持名称、编码、简拼)..." class="mb10" clearable @clear="filterDictData"
@input="filterDictData" />
<el-input ref="inputRef" v-model="searchKey" placeholder="搜索(支持名称、编码、简拼)..." class="mb10" clearable
@clear="filterDictData" @input="filterDictData" />
<el-table :data="filteredDictData" height="300px" border @row-dblclick="selectItem" highlight-current-row>
<el-table-column prop="value" label="编码" align="center" width="150" />
@ -100,7 +100,7 @@ const filterDictData = () => {
});
};
const inputRef = ref()
// 关键修改:打开弹窗时重新加载数据
const openDictSelector = async () => {
if (props.disabled || isDictLoading.value) {
@ -113,6 +113,11 @@ const openDictSelector = async () => {
// 数据加载完成后再显示弹窗
dialogVisible.value = true;
searchKey.value = '';
nextTick(() => {
setTimeout(() => {
inputRef.value.focus();
}, 100);
});
filterDictData();
};

View File

@ -1,7 +1,7 @@
<template>
<div>
<el-dialog :title="dialogTitle" v-model="csjgVisible" width="300px" :close-on-click-modal="false" :draggable="true">
<el-input v-model="searchKey" :placeholder="placeholder" size="small" class="mb10" clearable
<el-input ref="inputRef" v-model="searchKey" :placeholder="placeholder" size="small" class="mb10" clearable
@clear="filterDictData" @input="filterDictData" />
<el-table :data="filterData" max-height="300px" border @row-dblclick="selectItem" highlight-current-row
@ -85,9 +85,15 @@ const processTableData = (data: object[]) => {
});
};
const inputRef = ref()
const open = () => {
csjgVisible.value = true;
nextTick(() => {
searchKey.value = '';
setTimeout(() => {
inputRef.value.focus();
}, 100);
});
};
defineExpose({

View File

@ -0,0 +1,113 @@
<template>
<div>
<el-dialog v-model="visible" :title="title" :width="500" :close-on-click-modal="false" :draggable="true">
<el-form ref="formRef" :model="formValue" label-width="100px">
<!-- 用户代号 -->
<el-form-item label="用户代号:" prop="yhdh" :rules="[{ required: true, message: '请输入用户代号', trigger: 'change' }]">
<el-input ref="yhdhRef" v-model="formValue.yhdh" @change="handleChange" />
</el-form-item>
<!-- 用户姓名 -->
<el-form-item label="用户姓名:">
<el-input v-model="formValue.userName" disabled />
</el-form-item>
<!-- 密码输入 -->
<el-form-item label="密码:" prop="mm" :rules="[{ required: true, message: '请输入密码', trigger: 'change' }]">
<el-input v-model="formValue.mm" type="password" @keyup.enter="handleConfirm" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer" style="text-align: center;">
<el-button type="primary" @click="handleConfirm"> 确定 </el-button>
<el-button @click="cancel"> 取消 </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { checkYsUser } from '@/api/liswork/work/LisWork'
interface UserInfo {
usenName: string,
nickName: string,
}
const props = defineProps({
formValue: {
type: Object,
default: {
yhdh: '',
userName: '',
mm: '',
}
},
labPatKey: {
type: Object,
default: () => { }
},
userList: {
type: Array as PropType<UserInfo[]>,
default: () => []
},
title: {
type: String,
default: '请输入锁定人员账号密码'
}
});
const visible = ref(false);
// 表单数据
const formRef = ref();
const yhdhRef = ref();
const open = () => {
visible.value = true
nextTick(() => {
setTimeout(() => {
yhdhRef.value?.focus();
}, 100);
});
}
const emit = defineEmits(["confirm", "cancel",]);
// 处理确定按钮点击
const handleConfirm = async () => {
if (!formRef.value) return;
// 表单验证
const valid = await formRef.value.validate();
if (valid) {
checkYsUser({ ...props.formValue, ...props.labPatKey }).then((res: any) => {
if (res.code == 0) {
emit('confirm', props.formValue)
}
})
}
};
// 处理取消按钮点击
const cancel = () => {
formRef.value?.resetFields();
visible.value = false
emit('cancel',)
};
const handleChange = (value: string) => {
props.formValue.userName = props.userList.find((item: any) => item.userName == value)?.nickName
};
defineExpose({
open,
cancel
})
</script>
<style scoped></style>

View File

@ -20,7 +20,7 @@
</el-select>
</el-form-item>
<el-form-item label="" prop="failed4">
<el-select v-model="queryParams.failed4" placeholder="请选择" style="width:8.75">
<el-select v-model="queryParams.failed4" placeholder="请选择" style="width:8.75rem">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
@ -77,7 +77,6 @@
@column-drag-end="handleColumnDragEnd">
<template #dy="{ row }">
<svg-icon v-if="row.zt != 1" icon-class="lvgou" />
<svg-icon v-else icon-class="hongcha" />
</template>
<template #jzbz="{ row }">
{{ row.jzbz == '1' ? '急' : '' }}
@ -282,7 +281,7 @@ const cellStyleHd = ({ row, column, rowIndex, columnIndex }: {
}) => {
// console.log(row, column, rowIndex, columnIndex);
if (column.label == "急" && row.jzbz == "1") {
return { background: '#f00 !important', color: '#fff' };
return { color: '#f00' };
}
if (column.label == "类别") {
@ -568,8 +567,8 @@ function adjustTableHeight() {
if (compactForm.value) {
// 获取高度
heightForm.value = compactForm.value.offsetHeight;
tableConfig.value.height = `calc(71vh - ${heightForm.value}px)`; // 设置表格容器的高度
rightTableConfig.value.height = `calc(71vh - ${heightForm.value}px)`;
tableConfig.value.height = `calc(74vh - ${heightForm.value}px)`; // 设置表格容器的高度
rightTableConfig.value.height = `calc(74vh - ${heightForm.value}px)`;
}
}
@ -681,9 +680,9 @@ const printPdf = () => {
display: flex;
justify-content: space-around;
align-items: center;
margin-top: .625rem;
margin-top: .35rem;
background-color: #f0f3f8;
padding: .625rem 2.5rem;
padding: .3rem 2.5rem;
}
.time-line-item {
@ -699,9 +698,9 @@ const printPdf = () => {
align-items: center;
.index {
width: 2.5rem;
height: 2.5rem;
line-height: 2.5rem;
width: 1.875rem;
height: 1.875rem;
line-height: 1.875rem;
background: #E1E9F7;
border-radius: 50%;
text-align: center;

View File

@ -92,7 +92,6 @@
@column-drag-end="handleColumnDragEnd">
<template #dybz="{ row }">
<svg-icon v-if="row.dybz == 1" icon-class="lvgou" />
<svg-icon v-else icon-class="hongcha" />
</template>
<template #alarmflag="{ row }">
{{ row.alarmflag == 1 ? '危' : '' }}
@ -127,6 +126,20 @@
</el-col>
</el-row>
<!-- 样本流程 -->
<div class="time-line-box">
<div v-for="(item, i) in timelineItems" :key="i" class="time-line-item">
<div v-if="i != 0 && item.time" class="timeline-connector">
<img class="timg" src="@/assets/images/yjt.png" alt="">
</div>
<div class="timeline-content">
<div :class="['index', lastTimeIndex == i ? 'active' : '']">{{ i + 1 }}</div>
<div class="timeline-title">{{ item.title }}</div>
<div class="timeline-time">{{ item.time }}</div>
</div>
</div>
</div>
<!-- 结果对比 -->
<el-dialog v-model="dialogVisible" title="结果对比" draggable :close-on-click-modal="false">
@ -178,8 +191,7 @@ const options = ref([
{ label: '复制全部数据', value: 'All' },
{ label: '复制异常数据', value: 'N' },
{ label: '复制正常数据', value: 'Y' },
]
)
])
interface QueryParams {
times: string[]; // 明确类型为字符串元组
alarmflag: boolean,
@ -238,6 +250,31 @@ const queryRules = ref({
// ],
})
// 时间线数据
const timelineItems = ref(
[
{ title: '检验申请', time: '' },
{ title: '标本采集', time: '' },
{ title: '上机检验', time: '' },
{ title: '标本送检', time: '' },
// { title: '检验接收', time: '' },
{ title: '标本签收', time: '' },
{ title: '结果审核', time: '' },
]
);
// 计算最后一个有时间的节点索引
const lastTimeIndex = computed(() => {
const lastIndex = timelineItems.value.findLastIndex(item => item.time);
if (lastIndex === -1) {
return -1
} else {
return lastIndex;
}
});
const handleQuery = async () => {
const valid = await queryRef.value.validate().catch(() => { });
if (!valid) return false;
@ -284,6 +321,17 @@ const selectionChange = (selection: any) => {
const rightTableRef = ref()
const rowHandle = (row: any) => {
timelineItems.value =
[
{ title: '检验申请', time: row.sqsj },
{ title: '标本采集', time: row.cysj },
{ title: '上机检验', time: row.zxsj },
{ title: '标本送检', time: row.bbsjsj },
// { title: '检验接收', time: row.jssj},
{ title: '标本签收', time: row.jssj },
{ title: '结果审核', time: row.confirmtime },
]
Info.value = row
const data = {
jyrq: row.jyrq,
@ -336,10 +384,10 @@ const cellStyleHd = ({ row, column, rowIndex, columnIndex }: {
}) => {
// console.log(row, column, rowIndex, columnIndex);
if (column.label == "急" && row.jzbz == "1") {
return { background: '#f00 !important', color: '#fff' };
return { color: '#f00' };
}
if (column.label == "危" && row.alarmflag == "1") {
return { background: '#f00 !important', color: '#fff' };
return { color: '#f00' };
}
};
@ -480,12 +528,12 @@ const xmrowHandle = (row: any) => {
bottomTableData.value = res.rows
if (res.rows.length > 0) {
nextTick(() => {
rightTableConfig.value.height = `calc(55vh - ${heightForm.value}px)`
rightTableConfig.value.height = `calc(50vh - ${heightForm.value}px)`
rightTableRef.value?.doLayout && rightTableRef.value.doLayout();
});
} else {
nextTick(() => {
rightTableConfig.value.height = `calc(93vh - ${heightForm.value}px)`
rightTableConfig.value.height = `calc(83vh - ${heightForm.value}px)`
rightTableRef.value?.doLayout && rightTableRef.value.doLayout();
});
}
@ -728,7 +776,7 @@ const bottomTableConfig = ref(
{
// stripe: true, // 斑马纹
border: true, // 边框
height: '37vh', // 高度
height: '32vh', // 高度
highlightCurrentRow: true, // 高亮当前行
cellStyle: botCellStyleHd
}
@ -817,7 +865,7 @@ function adjustTableHeight() {
heightForm.value = compactForm.value.offsetHeight;
nextTick(() => {
tableConfig.value.height = `calc(93vh - ${heightForm.value}px)`
tableConfig.value.height = `calc(83vh - ${heightForm.value}px)`
tableRefs.value?.doLayout && tableRefs.value.doLayout();
});
@ -833,8 +881,74 @@ function adjustTableHeight() {
.title {
border-bottom: 1px solid #E1E9F7;
margin-bottom: 10px;
padding: 10px;
margin-bottom: .625rem;
padding: .625rem;
font-weight: 700;
}
.time-line-box {
display: flex;
justify-content: space-around;
align-items: center;
margin-top: .35rem;
background-color: #f0f3f8;
padding: .3rem 2.5rem;
}
.time-line-item {
display: flex;
align-items: center;
justify-content: space-around;
width: 16.6%;
// padding: 0 30px;
.timeline-content {
display: flex;
flex-direction: column;
align-items: center;
.index {
width: 1.875rem;
height: 1.875rem;
line-height: 1.875rem;
background: #E1E9F7;
border-radius: 50%;
text-align: center;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 500;
font-size: 1.125rem;
color: #4767A3;
}
.active {
background-color: #4096ff;
box-shadow: 0 0 0 .25rem rgba(64, 150, 255, 0.2);
color: #FFF;
}
.timeline-title {
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 500;
font-size: 1rem;
color: #4767A3;
}
.timeline-time {
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 400;
font-size: .875rem;
color: #4767A3;
}
}
.timg {
width: 3.125rem;
}
}
:deep(.el-form-item--default) {
margin-bottom: 1.125rem;
}
</style>

View File

@ -0,0 +1,225 @@
<template>
<el-dialog v-model="show" title="申请信息条形码自动输入" width="800px" :close-on-click-modal="false" :draggable="true"
@close="handleClose">
<div class="container">
<el-form inline class="compact-form">
<el-form-item label="样本号:">
<el-input v-model="ybh" @keyup.enter="ybhChange" />
</el-form-item>
<el-form-item label="条形码:">
<el-input ref="sqhRef" v-model="newSqh" @keyup.enter="handleEnter" />
</el-form-item>
</el-form>
<el-button-group class="mb-4">
<el-button type="default" @click="goPrev">上一个</el-button>
<el-button type="default" @click="goNext">下一个</el-button>
<el-button type="default" @click="goLast">最后</el-button>
<el-button @click="show = false">退出</el-button>
<el-button type="primary" @click="printHandle">打印列表</el-button>
</el-button-group>
<div class="prev-specimen-info p-2 border">
<div class="title">上一标本信息</div>
<el-form inline :model="prevSpecimen" label-width="80px" class="compact-form">
<el-form-item label="样本号:">
<div class="text"> {{ prevSpecimen.ybh }}</div>
</el-form-item>
<el-form-item label="申请号:">
<div class="text"> {{ prevSpecimen.sqh }}</div>
</el-form-item>
<el-form-item label="姓名:">
<div class="text"> {{ prevSpecimen.brxm }}</div>
</el-form-item>
<el-form-item label="科室:">
<div class="text"> {{ formatDict(prevSpecimen.ksdh, 'DP') }} </div>
</el-form-item>
<el-form-item label="性别:">
<div class="text"> {{ formatDict(prevSpecimen.brxb, 'SX') }}</div>
</el-form-item>
<el-form-item label="年龄:">
<div class="text"> {{ prevSpecimen.nl }} {{ formatDict(prevSpecimen.nldw, 'AU') }}</div>
</el-form-item>
<el-form-item label="床号:">
<div class="text"> {{ prevSpecimen.ch }}</div>
</el-form-item>
<el-form-item label="申请项目:">
<div class="text"> {{ prevSpecimen.jymd }}</div>
</el-form-item>
</el-form>
</div>
<div class="flex justify-between">
<div class="sum">
本次扫描 <span class="c_text">{{ currentScanCount }}</span> 个,当天样本总数 <span class="sum_text"> {{ totalCount
}}</span> 个
</div>
</div>
<el-table :data="tableData" border class="mt-4 w-full" height="400px">
<el-table-column prop="ybh" label="样本号" />
<el-table-column prop="sqh" label="条码" />
<el-table-column prop="brxm" label="姓名" />
<el-table-column prop="brdh" label="病历号" />
<el-table-column prop="jymd" label="项目" width="300" />
</el-table>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { updateLabPat } from "@/api/liswork/work/LisWork";
import emitter from "@/utils/mitt";
import { ElMessage } from "element-plus";
const props = defineProps({
labPat: {
type: Object,
required: true
},
totalCount: {
type: Number,
default: 0
},
labPatKey: {
type: Object,
default: () => { }
},
dictData: {
type: Object,
default: () => ({})
}
});
const { labPat, totalCount, labPatKey } = toRefs(props);
watch(() => labPat.value, () => {
if (labPat.value.ybh) {
ybh.value = labPat.value.ybh
}
})
const sqhRef = ref()
const newSqh = ref('')
const show = ref(false);
const ybh = ref('')
// 上一标本信息
const prevSpecimen: any = ref({});
// 表格数据
const tableData: any = ref([]);
const currentScanCount = ref(0);
const emit = defineEmits(['goPrev', 'goNext', 'update:labPat', 'changeStatus', 'queryYbh', 'goLast']);
const ybhChange = () => {
if (!ybh.value.trim()) return ElMessage.warning('请输入样本号!')
emit('queryYbh', ybh.value)
}
// 处理Enter键添加数据并跳转到下一个标本
const handleEnter = () => {
if (!newSqh.value.trim()) return ElMessage.warning('请录入条形码!')
const index = tableData.value.findIndex((item: any) => item.sqh == newSqh.value)
if (index > -1) return ElMessage.warning('条形码已录入!')
emitter.emit('saveLab');
updateLabPat({ ...labPatKey.value, ...labPat.value, sqh: newSqh.value }).then((res: any) => {
if (res.code == 0) {
newSqh.value = ''
sqhRef.value.focus()
if (res.data) {
emit('update:labPat', res.data)
emit("changeStatus", res.data, true);
} else {
emit("changeStatus", labPat.value, true);
}
prevSpecimen.value = res.data
tableData.value.push(res.data)
currentScanCount.value++;
}
})
};
// 上一个标本
const goPrev = () => {
emit('goPrev');
};
// 下一个标本
const goNext = () => {
emit('goNext');
};
// 最后一个标本
const goLast = () => {
emit('goLast');
};
const printHandle = () => {
if (!tableData.value.length) return ElMessage.warning('样本打印数据为空')
};
const open = () => {
ybh.value = labPat.value.ybh
show.value = true;
};
const handleClose = () => {
ybh.value = ''
newSqh.value = ''
prevSpecimen.value = {};
tableData.value = [];
currentScanCount.value = 0;
};
const formatDict = (v: string, dictType: string) => {
return props.dictData[dictType]?.find((item: any) => item.value == v)?.label || v;
}
defineExpose({
open,
});
</script>
<style scoped>
.container {
display: flex;
flex-direction: column;
gap: 16px;
}
.prev-specimen-info {
background-color: #e6f7ff;
position: relative;
padding: 20px 0;
.text {
width: 12.5rem;
}
.title {
position: absolute;
top: -10px;
font-family: SourceHanSansCN, SourceHanSansCN;
padding-left: 30px;
margin-bottom: 5px;
color: #000;
}
}
.sum {
font-family: SourceHanSansCN, SourceHanSansCN;
font-size: 16px;
.c_text {
color: #f00;
}
.sum_text {
color: #0000ff;
}
}
</style>

View File

@ -3,7 +3,7 @@
<div class="flex-between mb5">
<el-input v-model="sqhValue" placeholder="条码号" ref="sqhRef" :size="aotuSize" class="mr10" style="width:100%"
@keyup.enter="handleInputFocus" />
<el-button type="primary" :size="aotuSize">打印条码</el-button>
<el-button type="primary" :size="aotuSize" @click="batchHandle">扫码</el-button>
</div>
<el-form :model="labPat" label-width="5rem" class="compact-form" label-position="right">
<div :class="['sh_box', getColor(lastJgbz)]" v-if="lastJgbz != null && lastJgbz != 0 && lastJgbz != 'C'">
@ -73,11 +73,11 @@ import { changepatcolumn, updateLabPat, checkYsUser } from "@/api/liswork/work/L
import SelectTable from '@/components/SelectTable/index.vue';
import YhVerification from './yhVerification.vue';
import { PropType } from 'vue';
import emitter from '@/utils/mitt';
import { classCom } from '@/utils/classCom';
import { use } from 'vxe-pc-ui';
const aotuSize = classCom.useAutoSize();
interface LabSysItem {
kj: string;
dict: string;
@ -112,12 +112,13 @@ const lastJgbz = ref();
const sqhValue = ref(''); // 条码号
const sqhRef = ref();
watch(() => props.labPat, (newVal) => {
// console.log('newVal==>', newVal);
lastValue.value = JSON.stringify(newVal);
lastJgbz.value = newVal.jgbz;
lastJgbz.value = newVal?.jgbz;
sqhValue.value = '';
})
const emit = defineEmits(['update:labPat', 'changeStatus']);
const emit = defineEmits(['update:labPat', 'changeStatus', 'batchShow']);
const lastValue = ref('');
const brlyFields = ref([
@ -154,6 +155,10 @@ const handleInputFocus = () => {
// 表单引用
const formRef = ref();
// 批量扫码
const batchHandle = () => {
emit('batchShow')
};
// 处理确定按钮点击
const handleConfirm = async () => {
form.value.mm = ''
@ -218,6 +223,7 @@ const handleFieldChange = async () => {
}
}
};
// 保存病人信息
const saveLabPat = async (changedField: any) => {
if (props.labPat.id) {
@ -298,7 +304,7 @@ const getLableType = (type: string) => {
case '4':
return '二报';
case '5':
return '锁定';
return '已锁定';
default:
return '';
}
@ -478,7 +484,7 @@ onMounted(() => {
}
.sd_color {
color: rgba(128, 128, 128, 0.25);
color: rgb(233, 126, 32, .25);
}
.default {

View File

@ -8,7 +8,6 @@
<!-- 完成状态列 -->
<template #finish="{ row }">
<svg-icon v-if="row.finish == 1" icon-class="lvgou" />
<svg-icon v-else icon-class="hongcha" />
</template>
<template #jgbz="{ row }">
<el-checkbox :model-value="row.jgbz == '2'" readonly />
@ -48,7 +47,7 @@
</template>
<template #fslx="{ row }">
<el-checkbox :model-value="row.dybz === '1'" readonly />
<el-checkbox :model-value="row.fslx === '1'" readonly />
</template>
<template #yljg="{ row }">
@ -129,7 +128,7 @@ const closeHandle = () => {
}
const contextMenuItems = computed<ContextMenuItem[]>(() => [
{ label: '标准结果作为某标本复查结果', action: 'view' }
{ label: '本标本结果作其复查结果', action: 'view' }
]);
const handleMenuSelect = ((item: ContextMenuItem) => {
show.value = true
@ -137,10 +136,10 @@ const handleMenuSelect = ((item: ContextMenuItem) => {
})
// 表格列配置
const tableColumns = ref([
{ field: 'finish', title: '完', width: 20, align: 'center', slotName: 'finish', resizable: true },
{ field: 'jgbz', title: '审', width: 20, align: 'center', slotName: 'jgbz', resizable: true },
{ field: 'alarmflag', title: '警', width: 20, align: 'center', slotName: 'alarmflag', resizable: true },
{ field: 'autojgbz', title: '自', width: 20, align: 'center', slotName: 'autojgbz', resizable: true },
{ field: 'finish', title: '完', width: 30, align: 'center', slotName: 'finish', resizable: true },
{ field: 'jgbz', title: '审', width: 30, align: 'center', slotName: 'jgbz', resizable: true },
{ field: 'alarmflag', title: '警', width: 30, align: 'center', slotName: 'alarmflag', resizable: true },
{ field: 'autojgbz', title: '自', width: 30, align: 'center', slotName: 'autojgbz', resizable: true },
{ field: 'brly', title: '类型', width: 50, align: 'center', slotName: 'brly', resizable: true },
{ field: 'ybh', title: '样本号', width: 45, align: 'center', resizable: true },
{ field: 'brxm', title: '姓名', width: 40, align: 'center', resizable: true, slotName: 'brxm' },
@ -151,7 +150,7 @@ const tableColumns = ref([
{ field: 'nldw', title: '龄', width: 20, align: 'center', slotName: 'nldw', resizable: true },
{ field: 'ksdh', title: '科室', width: 80, align: 'center', slotName: 'ksdh', resizable: true },
{ field: 'yblx', title: '标本', width: 50, align: 'center', resizable: true, slotName: 'yblx' },
{ field: 'dybz', title: '印', width: 20, align: 'center', slotName: 'dybz', resizable: true },
{ field: 'dybz', title: '印', width: 30, align: 'center', slotName: 'dybz', resizable: true },
{ field: 'fslx', title: '发送', width: 30, align: 'center', slotName: 'fslx', resizable: true },
{ field: 'shcs', title: '次数', width: 30, align: 'center', resizable: true },
{ field: 'sqh', title: '申请号/条码', width: 100, align: 'center', resizable: true, },

View File

@ -180,26 +180,98 @@
<el-col :span="8">
<div> <el-checkbox>只显示同一申请单号</el-checkbox> </div>
<div>
<el-button type="primary">确定</el-button>
<el-button type="primary">合并</el-button>
<el-button>取消</el-button>
</div>
</el-col>
</el-row>
<CustomTable :data="mTableData" :columns="mColumns" :config="mTableConfig" :enable-column-drag="true"
@column-drag-end="mDragEnd" @selection-change="mSelectionChange">
<template #brxb="{ row }">
{{ formatDict(row.brxb, 'SX') }}
</template>
<template #nldw="{ row }">
{{ formatDict(row.nldw, 'AU') }}
</template>
</CustomTable>
</el-dialog>
<!-- 用户校验 -->
<userVerification ref="formRef" :title="verTitle" :form-value="formData" :userList="userList"
@confirm="handleConfirm" @cancel="handleCancel" />
<YhVerification ref="formRef" title="请输入锁定人员账号密码" :form-value="formData" @confirm="handleConfirm"
@cancel="handleCancel" :labelShow="false" />
<!-- 双工流水线 -->
<el-dialog v-model="dlShow" title="双工流水线申请单列表" width="40vw" :close-on-click-modal="false" :draggable="true">
<div class="mb10">
<el-button type="primary" @click="getDlList">刷新</el-button>
<el-button type="primary" @click="cfHandle">重发申请单</el-button>
<el-button @click="closeHandle">取消申请单</el-button>
</div>
<CustomTable :data="dlTableData" :columns="dlColumns" :config="dlTableConfig" :enable-column-drag="true"
@column-drag-end="dlDragEnd" @selection-change="dlSelectionChange">
<template #instrid="{ row }">
{{ row.instrid ? dlObj[row.instrid] : '未发送指令' }}
</template>
<template #brxb="{ row }">
{{ formatDict(row.brxb, 'SX') }}
</template>
<template #nldw="{ row }">
{{ formatDict(row.nldw, 'AU') }}
</template>
</CustomTable>
<div class="mt5" style="text-align: center;color:blue;">样本总数:{{ dlTableData.length }}</div>
</el-dialog>
<!-- 查看备份数据 -->
<ViewBackup ref="backRef" :backLabInfo="backLabInfo" :backTableData="backTableData" :userList="userList"
:dictData="dictData" />
<!-- 未建项目结果 -->
<el-dialog v-model="builtShow" title="检验结果对照" width="40vw" :close-on-click-modal="false" :draggable="true">
<div class="tips mb10">字典中不存在项目</div>
<el-row :gutter="10">
<el-col :span="16">
<el-table :data="builtTableData" height="50vh" border show-overflow-tooltip>
<el-table-column label="接口/通道号" prop="xmdh" />
<el-table-column label="结果" prop="csjg" />
<el-table-column label="对应检验项目" width="180">
<template #default="{ row }">
<el-select v-model="row.xmdh0" placeholder="" filterable @change="" size="small"
class="full-width-input">
<el-option v-for="item in builtOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
</el-table-column>
</el-table>
</el-col>
<el-col :span="8">
<div class="tips">
提示:<br />
如果结果就是某个检验项目的结果,请在“对应检验项目”列表中直接选择进行对照。<br />
如果不是,<br />
请选择菜单“字典”一>“检验项目”进入检验维护作业后点击按钮<br />
自动加载”加入项目。<br />
</div>
<div class="btns_box">
<div class="btn" @click="cpHandle">存盘</div>
<div class="btn" @click="builtShow = false">退出</div>
<div class="btn" @lcick="clearProHandle">清除未做</div>
</div>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script setup>
import { ref, toRefs, watch, nextTick, onMounted, computed } from "vue";
import YhVerification from "./yhVerification.vue";
import userVerification from "@/components/userVerification/index.vue";
import {
check1, check2, uncheck2, unconfirmlog, checkuser, reglimit, deleteresult, changeresult,
newresult, queryXmVal, printListwork, getresultchangelog, setinputmdl, saveResult, lockSample, unLockSample
check1, check2, uncheck2, unconfirmlog, checkuser, reglimit, deleteresult, changeresult, allPatquery, emrquery, datalink, changeLinkList,
viewBackup, newresult, queryXmVal, printListwork, getresultchangelog, setinputmdl, saveResult, lockSample, unLockSample, clearnotComplete, clearPrintflag,
noiteMresult, queryXmInfo, setitemInter
} from "@/api/liswork/work/LisWork";
import { ElMessageBox, ElMessage } from "element-plus";
import ProjectDetails from "@/components/projectDetails/index.vue";
@ -207,12 +279,10 @@ import projectsJg from "@/components/projectsjg/index.vue"
import { classCom } from '@/utils/classCom'
import CustomTable from '@/components/elTable/index.vue'
import dayjs from 'dayjs';
// @ts-ignore
import { listUser } from '@/api/system/user.js'
import emitter from "@/utils/mitt";
import { useCommonStore } from "@/store/modules/commonStore";
import ContextMenu from "@/components/contextMenu/index.vue";
import ViewBackup from "./viewBackup.vue";
// 组件属性定义
const props = defineProps({
resultSysList: { type: Array, required: true },
@ -222,6 +292,7 @@ const props = defineProps({
},
labPat: { type: Object, required: true },
userList: { type: Array, default: () => [] },
dictData: { type: Object, default: () => ({}) }
});
// 解构props
@ -299,6 +370,16 @@ const contextMenuItems = computed(() => [
{ label: '解除报告锁定', action: 'lift', shortcut: 'W', },
{ type: 'divider' },
// { label: '删除记录', action: 'delete', danger: true, shortcut: 'd', },
{ label: '查看电子病历', action: 'emrquery', shortcut: 'E', },
{ label: '查看360全景视图', action: 'patquery', shortcut: 'Y', },
{ label: '查看备份数据', action: 'viewbackup', shortcut: 'P', },
{ label: '双工流水线', action: 'datalink', shortcut: 'F', },
{ type: 'divider' },
{ label: '解除审核', action: 'unblock', shortcut: 'C', },
{ label: '清除打印标志', action: 'clearPrint', shortcut: 'U', },
{ label: '清除所有未做项目', action: 'clearPro', shortcut: 'T', },
{ type: 'divider' },
{ label: '未建项目结果', action: 'unbuilt', shortcut: 'N', },
]);
// 处理菜单选择
@ -311,14 +392,38 @@ const handleMenuSelect = (item) => {
previewHandle() //PDF报告预览
break;
case 'merge':
jgShow.value = true;
mergeHandle()
// alert(`合并病人当前其他结果`);
break;
case 'Lock':
lockHandle();
lockHandle(); //锁定
break;
case 'lift':
unlockHandle()
unlockHandle() //解锁
break;
case 'emrquery':
emrqueryHandle() //电子病历查询
break;
case 'patquery':
patqueryHandle() //360视图
break;
case 'viewbackup':
viewbackupHandle() //查看备份数据
break;
case 'datalink':
datalinkHandle() //流水线
break;
case 'unblock':
handleCheck(3) //解除审核
break;
case 'clearPrint':
clearPrintHandle() //清除打印标志
break;
case 'clearPro':
clearProHandle() //清除所有未做项目
break;
case 'unbuilt':
unbuiltHandle() //未建项目结果
break;
case 'delete':
if (confirm(`确定要删除患者的记录吗?`)) {
@ -327,6 +432,225 @@ const handleMenuSelect = (item) => {
break;
}
};
const builtShow = ref(false)
const builtTableData = ref([])
const builtOptions = ref([])
const unbuiltHandle = () => {
queryXmInfo({ yq: tableKey.value.yq }).then(res => {
if (res.code == 0) {
builtOptions.value = res.data.map(item => {
return {
value: item.xmdh,
label: item.xmdh + ' - ' + item.xmmc
}
})
}
})
noiteMresult(tableKey.value).then(res => {
builtTableData.value = res.data.map(item => {
return {
...item,
xmdh0: ''
}
})
})
builtShow.value = true
};
const cpHandle = () => {
const validItems = builtTableData.value.filter(item => item.xmdh0);
if (validItems.length === 0) {
console.log("没有需要处理的项");
return;
}
let successCount = 0;
let failCount = 0;
const requests = validItems.map((item, index) => {
return setitemInter({ ...tableKey.value, xmdh0: item.xmdh0, xmdh: item.xmdh })
.then(response => ({
index,
success: true,
data: response
}))
.catch(error => ({
index,
success: false,
error: error
}));
});
Promise.all(requests).then(results => {
results.forEach(result => {
if (result.success) {
successCount++;
// console.log(`第 ${result.index + 1} 项成功:`, result.data);
} else {
failCount++;
// console.error(`第 ${result.index + 1} 项失败:`, result.error);
}
});
// 输出统计结果
ElMessageBox.alert(
`项目与通道号对照已经完成,成功${successCount}个;失败${failCount}个。<br />你可以重新从仪器端传送一遍数据,就可以看到正确的结果了。`,
'信息',
{
dangerouslyUseHTMLString: true,
}
)
})
};
const clearPrintHandle = () => {
clearPrintflag(tableKey.value).then(res => {
if (res.code == 0) {
emits('changeStatus', labPat.value)
}
})
};
const clearProHandle = () => {
clearnotComplete(tableKey.value).then(res => {
if (res.code == 0) {
emits('fetchLabResults')
}
})
};
const mTableData = ref([])
const mColumns = ref([
{ label: "选择", type: 'selection', align: 'center', width: 40, visible: true, },
{ label: "仪器", prop: "yq", visible: true, },
{ label: "检验日期", prop: "jyrq", visible: true, },
{ label: "样本号", prop: "ybh", visible: true, },
{ label: "病历号", prop: "brdh", visible: true, },
{ label: "病人姓名", prop: "brxm", visible: true, },
{ label: "年", prop: "nl", width: 40, visible: true, },
{ label: "龄", prop: "nldw", width: 30, visible: true, slot: "nldw" },
{ label: "检验项目", prop: "xmdh", visible: true, },
{ label: "检验结果", prop: "csjg", width: 60, visible: true, },
{ label: "申请号", prop: "sqh", visible: true, },
])
const mTableConfig = {
border: true
}
const mDragEnd = (data) => {
mColumns.value = data.columns
}
const mSelectionChange = (data) => {
}
const mergeHandle = () => {
jgShow.value = true;
};
const emrqueryHandle = () => {
emrquery(tableKey.value).then(res => {
if (res.data) {
window.open(res.data)
}
})
};
const patqueryHandle = () => {
allPatquery(tableKey.value).then(res => {
if (res.data) {
window.open(res.data)
}
})
};
const backRef = ref()
const backLabInfo = ref({})
const backTableData = ref([])
const viewbackupHandle = () => {
viewBackup(tableKey.value).then(res => {
if (res.data) {
backTableData.value = res.data.labresultbk
backLabInfo.value = res.data.labpatbk
}
})
backRef.value.openDialog()
};
const dlObj = {
0: '申请发送',
1: '已发送指令',
2: '申请撤销中'
}
const dlShow = ref(false)
const dlTableData = ref([])
const dlColumns = ref([
{ label: "选择", type: 'selection', align: 'center', width: 40, visible: true, },
{ label: "动作状态", prop: "instrid", align: 'center', visible: true, slot: 'instrid' },
{ label: "申请号", prop: "sqh", align: 'center', visible: true, },
{ label: "样本号", prop: "ybh", align: 'center', visible: true, },
{ label: "姓名", prop: "brxm", align: 'center', visible: true, },
{ label: "性别", prop: "brxb", width: 30, align: 'center', visible: true, slot: 'brxb' },
{ label: "年", prop: "nl", width: 30, align: 'center', visible: true, },
{ label: "龄", prop: "nldw", width: 30, align: 'center', visible: true, slot: "nldw" },
{ label: "检验目的", prop: "jymd", width: 180, visible: true, },
])
const dlTableConfig = ref({
border: true,
maxHeight: 500,
cellStyle: ({ row, column }) => {
if (row.instrid == 1) {
return { background: '#c0c0c0 !important' }
}
},
})
const dlDragEnd = (data) => {
dlColumns.value = data.columns
}
const dlList = ref([])
const dlSelectionChange = (selection) => {
dlList.value = selection
}
const datalinkHandle = () => {
getDlList()
dlShow.value = true;
};
const getDlList = () => {
datalink(tableKey.value).then(res => {
dlTableData.value = res.data;
})
}
const cfHandle = () => {
if (dlList.value.length < 0) return ElMessage.warning('请选择数据')
const arr = dlList.value.filter(item => item.instrid == 1)
arr.forEach(v => {
v.instrid = null
})
changeLinkList(arr).then(res => {
if (res.code == 0) {
getDlList()
}
})
}
const closeHandle = () => {
dlList.value.forEach(v => {
v.instrid = 2
})
changeLinkList(dlList.value).then(res => {
if (res.code == 0) {
getDlList()
}
})
}
const formRef = ref();
@ -335,16 +659,21 @@ const formData = ref({
userName: '',
mm: '',
})
const verTitle = ref('请输入锁定人员账号密码')
const lockType = ref(1)
// 锁定报告
const lockHandle = () => {
if (props.labPat.jgbz != 0) return ElMessage.warning('样本已审核,不能锁定!')
lockType.value = 1
formRef.value.open()
verTitle.value = '请输入锁定人员账号密码'
}
// 解除锁定报告
// 解除锁定报告
const unlockHandle = () => {
if (props.labPat.jgbz != 5) return ElMessage.warning('目标标本未锁定,不可解除锁定!')
lockType.value = 2
verTitle.value = '请输入解除锁定人员账号密码'
formRef.value.open()
}
@ -359,6 +688,7 @@ const handleConfirm = (data) => {
if (res.code == 0) {
formRef.value?.cancel()
ElMessage.success(res.msg)
emits('fetchLabResults', true)
}
});
} else {
@ -366,6 +696,7 @@ const handleConfirm = (data) => {
if (res.code == 0) {
formRef.value?.cancel()
ElMessage.success(res.msg)
emits('fetchLabResults', true)
}
});
}
@ -445,7 +776,6 @@ const handleColumnDragEnd = (data) => {
};
const lastResult = ref({});
const beforeEnter = (row) => {
console.log('row==>', row);
const data = {
...tableKey.value,
xmdh: row.xmdh,
@ -729,6 +1059,7 @@ const handleCsjgEnter = async (row) => {
}
})
} else {
if (!row) return
if (row && row.id) {
emitter.emit('saveResult');
newresult(row).then(response => {
@ -892,6 +1223,10 @@ const formatYs = (v) => {
return userList.value.find((item) => item.userName == v)?.nickName || v
};
const formatDict = (v, dictType) => {
return props.dictData[dictType]?.find((item) => item.value == v)?.label || v;
}
</script>
<style scoped lang="scss">
@ -910,4 +1245,43 @@ const formatYs = (v) => {
.custom-table-container {
height: 100%;
}
.tips {
font-family: SourceHanSansCN, SourceHanSansCN;
}
.btns_box {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
margin-top: 1.875rem;
.btn {
width: 80%;
height: 2.5rem;
line-height: 2.5rem;
margin-bottom: 0.5rem;
font-size: 0.9rem;
font-weight: 500;
border-radius: 0.5rem;
background-color: var(--el-color-primary);
color: var(--el-color-white);
cursor: pointer;
&:hover {
background-color: var(--el-color-primary-light-2);
}
&:last-child {
margin-bottom: 0;
}
&.disabled {
background-color: var(--el-color-primary-light-5);
cursor: not-allowed;
}
}
}
</style>

View File

@ -0,0 +1,154 @@
<!-- 备份数据详情弹窗 -->
<template>
<div>
<el-dialog v-model="backShow" title="查看标本备份数据" width="35vw" :close-on-click-modal="false" :draggable="true">
<div>
<el-button type="primary">确定</el-button>
<el-button @click="backShow = false">取消</el-button>
</div>
<el-row :gutter="10">
<el-col :span="12">
<el-form :model="backLabInfo" label-width="70px" class="compact-form" label-position="right">
<el-form-item label="病人来源">
<el-col :span="14">
<SelectTable v-model:data="backLabInfo.brly" :fields="brlyFields" :tableData="dictData.PT || []"
label="label" value="value" objKey="value" :border="true" placeholder="请选择" size="small" />
</el-col>
<el-col :span="10">
<el-switch v-model="backLabInfo.jzbz" active-text="急诊" active-color="#FD0101" active-value="1"
inactive-value="0"></el-switch>
</el-col>
</el-form-item>
<el-form-item label="病 历 号">
<el-input v-model="backLabInfo.brdh" placeholder="请输入病历号" size="small" />
</el-form-item>
<el-form-item label="姓 名">
<el-input v-model="backLabInfo.brxm" placeholder="请输入姓名" size="small" />
</el-form-item>
<el-form-item label="性 别">
<el-select v-model="backLabInfo.brxb" placeholder="请选择" style="width: 100%;" size="small">
<el-option v-for="item in dictData.SX" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="年龄">
<el-row :gutter="5">
<el-col :span="14">
<el-input v-model="backLabInfo.nl" placeholder="年龄" style="width:100%" size="small" />
</el-col>
<el-col :span="10">
<el-select v-model="backLabInfo.nldw" placeholder="请选择" style="width: 100%;" filterable size="small">
<el-option v-for="item in dictData.AU" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="送检科室">
<SelectTable v-model:data="backLabInfo.ksdh" :fields="ksdhFields" :tableData="dictData.DP || []"
label="label" value="value" objKey="value" :border="true" placeholder="请选择" size="small" />
</el-form-item>
<el-form-item label="床 号">
<el-input v-model="backLabInfo.ch" placeholder="请输入床号" size="small" />
</el-form-item>
<el-form-item label="样本类型">
<SelectTable v-model:data="backLabInfo.yblx" :fields="ksdhFields" :tableData="dictData.BT || []"
label="label" value="value" objKey="value" :border="true" placeholder="请选择" size="small" />
</el-form-item>
<el-form-item label="申请医生">
<SelectTable v-model:data="backLabInfo.sjys" :fields="ksdhFields" :tableData="dictData.SRD || []"
label="label" value="value" objKey="value" :border="true" placeholder="请选择" size="small" />
</el-form-item>
<el-form-item label="上机时间">
<el-date-picker v-model="backLabInfo.sqsj" type="datetime" placeholder="上机时间" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" size="small" style="width: 100%;" />
</el-form-item>
<el-form-item label="采样时间">
<el-date-picker v-model="backLabInfo.cyrq" type="datetime" placeholder="采样时间" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" size="small" style="width: 100%;" />
</el-form-item>
<el-form-item label="报告时间">
<el-date-picker v-model="backLabInfo.dysj" type="datetime" placeholder="报告时间" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" size="small" style="width: 100%;" />
</el-form-item>
<el-form-item label="临床诊断">
<el-input v-model="backLabInfo.zd" placeholder="请输入临床诊断" size="small" />
</el-form-item>
<el-form-item label="备 注">
<el-input v-model="backLabInfo.bz" placeholder="请输入备注" size="small" />
</el-form-item>
<el-form-item label="检验医生">
<SelectTable v-model:data="backLabInfo.yhdh" :fields="ysFields" :tableData="userList || []"
label="nickName" value="userName" objKey="userName" :border="true" placeholder="请选择" size="small" />
</el-form-item>
<el-form-item label="审核医生">
<SelectTable v-model:data="backLabInfo.hdys" :fields="ysFields" :tableData="userList || []"
label="nickName" value="userName" objKey="userName" :border="true" placeholder="请选择" size="small" />
</el-form-item>
<el-form-item label="审核状态">
<el-radio-group v-model="backLabInfo.jgbz">
<el-radio :label="'0'">未审核</el-radio>
<el-radio :label="'2'">已审核</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-col>
<el-col :span="12">
<el-table :data="backTableData" height="100%" border>
<el-table-column label="检验项目" prop="xmdh" />
<el-table-column label="检验结果" prop="csjg" />
</el-table>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import SelectTable from '@/components/SelectTable/index.vue';
const props = defineProps({
backTableData: {
type: Array,
default: () => [],
},
backLabInfo: {
type: Object,
default: () => { },
},
userList: {
type: Array as PropType<object[]>,
default: () => [],
},
dictData: {
type: Object,
default: () => ({})
}
})
const brlyFields = ref([
{ prop: 'value', label: '代号', width: 80, enablePinyinSearch: true },
{ prop: 'label', label: '名称', width: 120, enablePinyinSearch: true },
])
const ksdhFields = ref([
{ prop: 'value', label: '代号', width: 80, enablePinyinSearch: true },
{ prop: 'label', label: '名称', width: 150, enablePinyinSearch: true },
])
const ysFields = ref([
{ prop: 'userName', label: '用户代号', width: 80, enablePinyinSearch: true },
{ prop: 'nickName', label: '用户姓名', width: 150, enablePinyinSearch: true },
])
const backShow = ref(false)
const backTableData = ref([])
const backLabInfo: any = ref({})
const openDialog = () => {
backShow.value = true
}
defineExpose({
openDialog
})
</script>
<style scoped></style>

View File

@ -42,18 +42,22 @@ import * as echarts from 'echarts';
import { historyInfo } from '@/api/liswork/work/LisWork'
import dayjs from 'dayjs';
import CustomTable from '@/components/elTable/index.vue'
import { getGroupInstrdList } from '@/api/liswork/work/LisWork'
const props = defineProps({
// 主键
queryParams: {
type: Object,
default: {}
}
},
dictData: {
type: Object,
default: () => ({})
},
})
// 解构 props
const { queryParams } = toRefs(props);
const instrOptions = ref<Array<{ yq: string, yqmc: string }>>([])
const tableData: any = ref([]);
const tableRef = ref();
const columns = ref([
@ -119,13 +123,23 @@ const formatHeader = (column: any, prefix: string) => {
const yljgKey = `${prefix}yljg`;
const dateKey = `${prefix}Date`;
const ybhKey = `${prefix}ybh`;
const yqdlKey = `${prefix}yqdl`;
const yqKey = `${prefix}yq`;
const brxbKey = `${prefix}brxb`;
const nlKey = `${prefix}nl`;
const item = tableData.value[index];
return `${item[yljgKey]} <br /> ${item[dateKey]} <br /> ${item[yqdlKey]}(${item[ybhKey]})`;
return `${item[yljgKey]} <br /> ${item[dateKey]} <br /> ${formatYq(item[yqKey])}(${item[ybhKey]}) <br /> ${item[brxbKey]},${item[nlKey]}`;
}
return column.label;
};
const formatDict = (v: string, dictType: string) => {
return props.dictData[dictType]?.find((item: any) => item.value == v)?.label || v;
}
const formatYq = (yq: string) => {
return instrOptions.value?.find((item: any) => item.yq == yq.trim())?.yqmc || yq;
}
const getList = () => {
historyInfo(queryParams.value).then((res: any) => {
const periods = ['first', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
@ -139,13 +153,15 @@ const getList = () => {
map.set(item.xmdh, {
csjg: item.csjg,
jyrq: dayjs(item.jyrq).format('YY/MM/DD'),
yqdl: item.yqdl,
yq: item.yq,
ybh: item.ybh,
yljg: item.yljg,
result_flag: item.result_flag,
xmmc: item.xmmc,
cksx: item.cksx,
ckxx: item.ckxx
ckxx: item.ckxx,
brxb: item.brxb,
nl: item.nl,
});
});
dataMaps.set(period, map);
@ -168,9 +184,11 @@ const getList = () => {
if (item) {
row[`${period}Csjg`] = item.csjg;
row[`${period}Date`] = item.jyrq;
row[`${period}yqdl`] = item.yqdl;
row[`${period}yq`] = item.yq;
row[`${period}ybh`] = item.ybh;
row[`${period}yljg`] = item.yljg;
row[`${period}brxb`] = item.brxb;
row[`${period}nl`] = item.nl;
row[`${period}ResultFlag`] = item.result_flag;
if (!row.xmmc) {
@ -196,7 +214,6 @@ watch(() => props.queryParams, (newValue) => {
}, { immediate: true })
const handleRowClick = (row: any) => {
console.log('row==>', row);
nextTick(() => {
getEcharts(row)
})
@ -204,10 +221,10 @@ const handleRowClick = (row: any) => {
const myEcharts = ref()
const getEcharts = (data: any) => {
const periods = ['first', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
const periods = ['nine', 'eight', 'seven', 'six', 'five', 'four', 'three', 'two', 'one', 'first']
const xData = periods.map(period => { return data[`${period}Date`] || ''; })
const yData = periods.map(period => { return data[`${period}Csjg`] || ''; })
const xData = periods.map(period => { return data[`${period}Date`] }).filter(Boolean) //过滤掉空值
const yData = periods.map(period => { return data[`${period}Csjg`] }).filter(Boolean)
const Intance = echarts.init(myEcharts.value);
@ -251,7 +268,10 @@ const getEcharts = (data: any) => {
data: xData,
axisLabel: {
interval: 0,
rotate: 30 // 日期标签旋转,避免重叠
rotate: 30, // 日期标签旋转,避免重叠
},
axisTick: {
alignWithLabel: true // 让刻度线与标签对齐
}
},
yAxis: {
@ -320,6 +340,16 @@ const getEcharts = (data: any) => {
Intance.setOption(option);
}
onMounted(() => {
getGroupInstrdList().then((res: any) => {
if (res.code == 0) {
instrOptions.value = res.data.map((item: any) => ({
yq: item.yq.trim(),
yqmc: item.yqmc
}))
}
})
})
</script>
<style scoped lang="scss">

View File

@ -48,11 +48,11 @@
<el-row :gutter="5">
<el-col :span="8">
<LabPat ref="labPatRef" v-model:labPat="labPat" :labPatKey="queryParams" :labSysList="labInputcolList"
:userList="userList" @changeStatus="changeStatus" />
:userList="userList" @changeStatus="changeStatus" @batchShow="handleBatchScan" />
</el-col>
<el-col :span="16">
<LabResult ref="labResultRef" v-model:labPat="labPat" :tableData="labResuts" :tableKey="queryParams"
:userList="userList" :resultSysList="resultConfig" @fetchLabResults="fetchLabResults"
<LabResult ref="labResultRef" :labPat="labPat" :tableData="labResuts" :tableKey="queryParams"
:userList="userList" :resultSysList="resultConfig" @fetchLabResults="resultsHandle" :dictData="dictData"
@changeStatus="changeStatus" @previewHandle="previewHandle" />
</el-col>
</el-row>
@ -63,7 +63,7 @@
<div>
<tabView :tabList="tabList" v-model:activeTab="activeTab" />
<div class="box-shadow right_box">
<template v-if="activeTab == 1">
<template v-if="activeTab == 'LabPatList'">
<div class="flex-between">
<div>
<el-button type="primary" :size="aotuSize" icon="RefreshRight" @click="fetchlabPatList">刷新</el-button>
@ -87,44 +87,20 @@
<div class="text2">未审:<span>{{ ws }}</span></div>
<div class="text3">危:<span>{{ wjs }}</span></div>
</div>
</template>
<component :is="activeTabName" :queryParams="queryParams" :dictData="dictData" :instrOptions="instrOptions"
@fetchResults="fetchLabResults" :tablekey="queryParams" />
</template>
<!-- 历史对照 -->
<template v-if="activeTab == 2">
<History :queryParams="queryParams" />
</template>
<!-- 其他结果 -->
<template v-if="activeTab == 3">
<Others :queryParams="queryParams" :dictData="dictData" :instrOptions="instrOptions" />
</template>
<!-- 结果复查 -->
<template v-if="activeTab == 4">
<Reexamination :queryParams="queryParams" @fetchResults="fetchLabResults" :tablekey="queryParams" />
</template>
<!-- 收费信息 -->
<template v-if="activeTab == 5">
<Charge :queryParams="queryParams" :dictData="dictData" />
</template>
<!-- 组合项目 -->
<template v-if="activeTab == 6">
<Combination :queryParams="queryParams" />
</template>
<!-- 临床意义 -->
<template v-if="activeTab == 7">
<Clinical :queryParams="queryParams" />
</template>
<!-- 样本流转 -->
<template v-if="activeTab == 8">
<Sample :queryParams="queryParams" :dictData="dictData" />
</template>
<!-- 结果图形 -->
<template v-if="activeTab == 9">
<ResultGraph :queryParams="queryParams" />
</template>
</div>
</div>
</el-col>
</el-row>
<!-- 批量扫码弹窗 -->
<BatchCode ref="batchRef" v-model:labPat="labPat" :labPatKey="queryParams" :dictData="dictData"
:totalCount="labPatList.length" @goNext="handleNext" @goPrev="handlePrev" @goLast="handleLast"
@queryYbh="ybhChangeTb" @changeStatus="changeStatus" />
<el-dialog v-model="previewShow" title="预览" width="90vw" :close-on-click-modal="false">
<iFrame v-if="pdfUrl" :src="pdfUrl" />
@ -159,6 +135,7 @@ import { getNextNumber, getPreviousNumber } from "@/utils/getNextNumber";
import { useCommonStore } from '@/store/modules/commonStore';
import { classCom } from '@/utils/classCom';
import PatientQueryForm from '@/components/selectSearch/index.vue'
import BatchCode from './components/batchCode.vue';
// @ts-ignore
import { listUser } from '@/api/system/user.js'
@ -177,19 +154,33 @@ const queryParams = ref({
const ybs = ref(0)
const ws = ref(0)
const wjs = ref(0)
const activeTab = ref(1)
const activeTab = ref('LabPatList')
const tabList = ref([
{ label: '标本列表', value: 1 },
{ label: '结果图形', value: 9 },
{ label: '历史对照', value: 2 },
{ label: '其他结果', value: 3 },
{ label: '结果复查', value: 4 },
{ label: '收费信息', value: 5 },
{ label: '组合项目', value: 6 },
{ label: '临床意义', value: 7 },
{ label: '样本流转', value: 8 },
{ label: '标本列表', value: 'LabPatList' },
{ label: '结果图形', value: 'ResultGraph' },
{ label: '历史对照', value: 'History' },
{ label: '其他结果', value: 'Others' },
{ label: '结果复查', value: 'Reexamination' },
{ label: '收费信息', value: 'Charge' },
{ label: '组合项目', value: 'Combination' },
{ label: '临床意义', value: 'Clinical' },
{ label: '样本流转', value: 'Sample' },
])
const labPat = ref<any>({},)
const activeTabMap = {
ResultGraph,
History,
Others,
Reexamination,
Charge,
Combination,
Clinical,
Sample
}
const activeTabName = computed(() => activeTabMap[activeTab.value as keyof typeof activeTabMap] || 'LabPatList');
const labPat = ref<any>({})
const labPatList = ref<Array<{ ybh: string; jgbz: string }>>([]);
const originalLabPatList = ref([]) //原始数据
const loading = ref(false)
@ -340,6 +331,13 @@ const getYqConfig = () => {
})
}
const resultsHandle = (flag: boolean) => {
if (flag) {
fetchLabPat();
}
fetchLabResults()
}
const highlightRowIndex = ref(-1)
const labPatListRef = ref()
//样本列表点击切换样本信息,同步载入左边样本信息表单和中间结果表单
@ -350,8 +348,8 @@ const selectJob = (job: any) => {
queryParams.value.jyrq = job.jyrq;
queryParams.value.yq = job.yq.trim();
queryParams.value.ybh = job.ybh;
fetchLabResults();
fetchLabPat();
fetchLabResults();
highlightRowIndex.value = labPatList.value.findIndex((item: any) => item.ybh == queryParams.value.ybh);
}
const labResuts = ref([])
@ -365,15 +363,20 @@ const fetchLabResults = async () => {
//载入样本编辑表单(左边labpat.vue组件)
const fetchLabPat = () => {
queryLabPat(queryParams.value).then((response: any) => {
labPat.value = response.data[0];
labPat.value = response.data;
})
}
const lastRow: any = ref({})
// 批量扫码ybh同步样本编号
const ybhChangeTb = (val: string) => {
console.log('val==>', val);
queryParams.value.ybh = val
handleQuery();
}
const handleQuery = () => {
if (!labPatList.value.length) return
// fetchlabPatList()
if (!queryParams.value.ybh) {
highlightRowIndex.value = -1;
ElMessage.warning('请输入样本编号')
@ -437,8 +440,15 @@ const delSampleHd = () => {
ElMessage.success('删除成功')
labPatList.value = labPatList.value.filter((item: any) => item.ybh != lastRow.value.ybh)
getTotals()
// 删除跳下一个样本
handleNext()
// 删除跳当前页面下一个样本
// handleNext()
if (highlightRowIndex.value > labPatList.value.length - 1) {
highlightRowIndex.value--;
}
const row = labPatList.value[highlightRowIndex.value];
labPatListRef.value.setCurrentRow(row);
selectJob(row);
}
})
})
@ -496,18 +506,21 @@ const handleNext = () => {
handleCreate();
}
}
}
// 最后一个样本
const handleLast = () => {
}
const batchRef = ref()
// 批量扫码
const handleBatchScan = () => {
batchRef.value.open()
}
// 改变样本列表中样本状态
const changeStatus = (updatedPat: any, flag: boolean) => {
console.log('changeStatusflag==>', flag, updatedPat);
queryLabPat(queryParams.value).then((response: any) => {
if (response.code == 0) {
labPat.value = response.data[0];
labPat.value = response.data;
const index = labPatList.value.findIndex((item: any) => item.ybh == updatedPat.ybh);
console.log('index==>', index);
if (index !== -1) {
labPatList.value = labPatList.value.map((item, i) =>
i === index ? { ...labPat.value } : item
@ -517,7 +530,6 @@ const changeStatus = (updatedPat: any, flag: boolean) => {
nextTick(() => {
labPatListRef.value.setCurrentRow(labPat.value);
});
console.log('changeStatusflag==>', flag);
// 条码号输入后操作
if (flag) {
setTimeout(() => { handleNext() }, 10)
@ -561,7 +573,6 @@ const fetchlabPatList = () => {
loading.value = false;
if (res.data.length > 0) {
highlightRowIndex.value = 0;
labPat.value = res.data[0];
setTimeout(() => { labPatListRef.value.setCurrentRow(res.data[0]); }, 100)
selectJob(res.data[0])
getTotals()

View File

@ -11,7 +11,7 @@
</el-col>
<el-col :span="16">
<CustomTable ref="tableDetailRef" :columns="columns" :data="tableDataDetail" :config="config"
@row-click="handleRowClick" :enable-column-drag="true" @column-drag-end="handleColumnDragEnd">
:enable-column-drag="true" @column-drag-end="handleColumnDragEnd">
<template #firstCsjg="{ column }">
<div v-html="formatHeader(column, 'first')"></div>
</template>
@ -147,7 +147,7 @@ const formatHeader = (column: any, prefix: string) => {
const brxbKey = `${prefix}brxb`;
const nlKey = `${prefix}nl`;
const item = tableDataDetail.value[index];
return ` ${item[dateKey]} <br /> (${item[ybhKey]}) <br /> ${item[yqdlKey]} <br />${item[brxbKey]},${item[nlKey]}`;
return ` ${item[dateKey]} <br /> (${item[ybhKey]}) <br /> ${formatyq(item[yqKey])} <br />${item[brxbKey]},${item[nlKey]}`;
}
return column.label;
};