- 将CTE查询重构为子查询以提高执行效率 - 为位置和医生查询添加LIMIT 1约束以减少数据量 - 移除不必要的GROUP BY子句以简化查询逻辑 - 在前端组件中实现异步数据加载和错误处理机制 - 使用可选链操作符处理空值情况避免报错 - 添加防抖机制解决单击双击冲突问题 - 优化患者列表和床位列表的并行加载逻辑 - 清理调试用的console.log语句并替换为有意义的信息
664 lines
19 KiB
Vue
664 lines
19 KiB
Vue
<template>
|
||
<div class="main">
|
||
<div class="title">
|
||
<h1>患者护理记录单</h1>
|
||
</div>
|
||
<el-scrollbar height="500px" style="height: 100%">
|
||
<div class="content">
|
||
<el-form :model="rulesFrom" :rules="rules" ref="formRef">
|
||
<el-card>
|
||
<div class="commoncss">
|
||
<el-form-item prop="date" label="日期:" label-width="100px">
|
||
<el-date-picker
|
||
v-model="rulesFrom.date"
|
||
type="date"
|
||
placeholder="请选择"
|
||
format="YYYY/MM/DD"
|
||
value-format="YYYY-MM-DD"
|
||
@change="dateChange"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item prop="time" label="时间:" label-width="100px">
|
||
<el-time-picker
|
||
v-model="rulesFrom.time"
|
||
placeholder="请选择时间"
|
||
format="HH:mm"
|
||
value-format="HH:mm"
|
||
@change="dateChange"
|
||
/>
|
||
</el-form-item>
|
||
</div>
|
||
<!-- 基本信息 -->
|
||
<div class="foundation">
|
||
<div class="commone-title">基本信息:</div>
|
||
<div class="foundation-content">
|
||
<div class="foundation-content-first">
|
||
<el-form-item label="意识:" label-width="100px">
|
||
<el-select
|
||
v-model="rulesFrom.consciousnessCodeList"
|
||
multiple
|
||
collapse-tags
|
||
collapse-tags-tooltip
|
||
:max-collapse-tags="1"
|
||
placeholder="请选择"
|
||
style="width: 220px"
|
||
>
|
||
<el-option
|
||
v-for="item in ysOptions"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="体温:" label-width="100px">
|
||
<div class="commoncss">
|
||
<el-input
|
||
v-model="rulesFrom.temperature"
|
||
placeholder="请输入"
|
||
clearable
|
||
style="width: 220px"
|
||
/>
|
||
<div>℃</div>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="心率:" label-width="100px">
|
||
<div class="commoncss">
|
||
<el-input
|
||
v-model="rulesFrom.heartRate"
|
||
placeholder="请选择"
|
||
clearable
|
||
style="width: 220px"
|
||
/>
|
||
<div class="unit">次/分</div>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
<div class="foundation-content-second">
|
||
<el-form-item label="脉率:" label-width="100px" class="wait-flex">
|
||
<div class="commoncss">
|
||
<el-input
|
||
v-model="rulesFrom.pulse"
|
||
placeholder="请选择"
|
||
clearable
|
||
class="wait-flex"
|
||
style="width: 180px"
|
||
/>
|
||
<div class="unit">次/分</div>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="呼吸:" label-width="100px" class="wait-flex">
|
||
<div class="commoncss">
|
||
<el-input
|
||
v-model="rulesFrom.breathe"
|
||
placeholder="请选择"
|
||
clearable
|
||
class="wait-flex"
|
||
style="width: 180px"
|
||
/>
|
||
<div class="unit">次/分</div>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="血压:" label-width="100px" class="wait-flex">
|
||
<div class="commoncss">
|
||
<el-input
|
||
v-model="rulesFrom.bloodPressure"
|
||
placeholder="请选择"
|
||
clearable
|
||
style="width: 180px"
|
||
/>
|
||
<div class="unit">mmHg</div>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="血氧饱和度:" label-width="100px" class="wait-flex">
|
||
<div class="commoncss">
|
||
<el-input
|
||
v-model="rulesFrom.bloodOxygen"
|
||
placeholder="请选择"
|
||
clearable
|
||
style="width: 180px"
|
||
/>
|
||
<div class="unit">%</div>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
<div>
|
||
<el-form-item label="吸氧升/分:" label-width="100px" class="wait-flex">
|
||
<div class="commoncss">
|
||
<el-input
|
||
v-model="rulesFrom.oxygen"
|
||
placeholder="请选择"
|
||
clearable
|
||
style="width: 180px"
|
||
/>
|
||
<div class="unit">升/分</div>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 氧疗 -->
|
||
<div class="oxygen">
|
||
<div class="oxygen-title commone-title">氧疗/min</div>
|
||
<div class="oxygen-content">
|
||
<el-form-item label="方式:" label-width="100px">
|
||
<el-select
|
||
v-model="rulesFrom.oxygenCodeList"
|
||
multiple
|
||
collapse-tags
|
||
collapse-tags-tooltip
|
||
:max-collapse-tags="1"
|
||
placeholder="请选择"
|
||
style="width: 220px"
|
||
>
|
||
<el-option
|
||
v-for="item in oxygenOptions"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="流量:" label-width="100px">
|
||
<div>
|
||
<el-input
|
||
v-model="rulesFrom.oxygenflow"
|
||
placeholder="请输入"
|
||
clearable
|
||
style="width: 220px"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
</div>
|
||
<!-- 入量 -->
|
||
<div class="input">
|
||
<div class="input-title commone-title">入量</div>
|
||
<div class="input-content">
|
||
<el-form-item label="名称:" label-width="100px">
|
||
<div>
|
||
<el-input
|
||
v-model="rulesFrom.inputName"
|
||
placeholder="请输入"
|
||
clearable
|
||
style="width: 220px"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="ml:" label-width="100px">
|
||
<div>
|
||
<el-input
|
||
v-model="rulesFrom.input"
|
||
placeholder="请输入"
|
||
clearable
|
||
style="width: 220px"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="途径:" label-width="100px">
|
||
<div>
|
||
<el-input
|
||
v-model="rulesFrom.inputvia"
|
||
placeholder="请输入"
|
||
clearable
|
||
style="width: 220px"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
</div>
|
||
<!-- 出量 -->
|
||
<div class="out">
|
||
<div class="out-title commone-title">出量</div>
|
||
<div class="out-content">
|
||
<el-form-item label="名称:" label-width="100px">
|
||
<div>
|
||
<el-input
|
||
v-model="rulesFrom.outputName"
|
||
placeholder="请输入"
|
||
clearable
|
||
style="width: 220px"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="ml:" label-width="100px">
|
||
<div>
|
||
<el-input
|
||
v-model="rulesFrom.output"
|
||
placeholder="请输入"
|
||
clearable
|
||
style="width: 220px"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
</div>
|
||
<!-- 皮肤情况 -->
|
||
<div class="skin">
|
||
<el-form-item label="皮肤情况:" label-width="100px">
|
||
<el-select
|
||
v-model="rulesFrom.skinconditionCodeList"
|
||
multiple
|
||
collapse-tags
|
||
collapse-tags-tooltip
|
||
:max-collapse-tags="3"
|
||
placeholder="请选择"
|
||
style="width: 380px"
|
||
>
|
||
<el-option
|
||
v-for="item in skinconditionOption"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</div>
|
||
<!-- 管路护理 -->
|
||
<div class="nursing">
|
||
<el-form-item label="管路护理:" label-width="100px">
|
||
<el-select
|
||
v-model="rulesFrom.pipelinecare"
|
||
multiple
|
||
collapse-tags
|
||
collapse-tags-tooltip
|
||
:max-collapse-tags="3"
|
||
placeholder="请选择"
|
||
style="width: 380px"
|
||
>
|
||
<el-option
|
||
v-for="item in pipelinecareOption"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</div>
|
||
<!-- 病情措施 -->
|
||
<div class="nursing">
|
||
<el-form-item label="病情措施:" label-width="100px">
|
||
<div>
|
||
<el-input
|
||
type="textarea"
|
||
v-model="rulesFrom.condition"
|
||
placeholder="请选择"
|
||
clearable
|
||
style="width: 380px"
|
||
:rows="10"
|
||
:autosize="{ minRows: 5, maxRows: 10 }"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
<!-- 护士签名 -->
|
||
<div class="nurse">
|
||
<el-form-item label="护士签名:" label-width="100px">
|
||
<div>
|
||
<el-input
|
||
v-model="rulesFrom.nurse"
|
||
placeholder="请选择"
|
||
clearable
|
||
style="width: 380px"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
</el-card>
|
||
</el-form>
|
||
</div>
|
||
</el-scrollbar>
|
||
<div style="display: flex; justify-content: flex-end; margin-top: 10px">
|
||
<el-button @click="onCancle">取消</el-button>
|
||
<el-button type="primary" @click="saveData">保存</el-button>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {computed, reactive, ref, watch} from 'vue';
|
||
import dayjs from 'dayjs';
|
||
import {addRecord, getTemperatureType} from '../tprsheet/api/api';
|
||
import {patientInfo} from '../../inpatientDoctor/home/store/patient';
|
||
import {ElMessage} from 'element-plus';
|
||
|
||
const formRef = ref();
|
||
// 意识
|
||
const ysOptions = [
|
||
{
|
||
value: '1',
|
||
label: '清醒',
|
||
},
|
||
{
|
||
value: '2',
|
||
label: '嗜睡',
|
||
},
|
||
{
|
||
value: '3',
|
||
label: '意识模糊',
|
||
},
|
||
{
|
||
value: '4',
|
||
label: '昏睡',
|
||
},
|
||
{
|
||
value: '5',
|
||
label: '谵妄',
|
||
},
|
||
{
|
||
value: '6',
|
||
label: '浅昏迷',
|
||
},
|
||
{
|
||
value: '7',
|
||
label: '中度昏迷',
|
||
},
|
||
{
|
||
value: '8',
|
||
label: '深昏迷',
|
||
},
|
||
{
|
||
value: '9',
|
||
label: '全麻未醒',
|
||
},
|
||
{
|
||
value: '10',
|
||
label: '镇静',
|
||
},
|
||
];
|
||
// 氧疗
|
||
const oxygenOptions = [
|
||
{
|
||
value: '1',
|
||
label: '鼻导管吸氧',
|
||
},
|
||
{
|
||
value: '2',
|
||
label: '面罩吸氧',
|
||
},
|
||
{
|
||
value: '3',
|
||
label: '高流量氧疗',
|
||
},
|
||
{
|
||
value: '4',
|
||
label: '机械通气',
|
||
},
|
||
];
|
||
// 皮肤情况
|
||
const skinconditionOption = [
|
||
{
|
||
value: '1',
|
||
label: '完好',
|
||
},
|
||
{
|
||
value: '2',
|
||
label: '压疮',
|
||
},
|
||
{
|
||
value: '3',
|
||
label: '出血点',
|
||
},
|
||
{
|
||
value: '4',
|
||
label: '破损',
|
||
},
|
||
{
|
||
value: '5',
|
||
label: '水肿',
|
||
},
|
||
{
|
||
value: '6',
|
||
label: '瘀斑',
|
||
},
|
||
{
|
||
value: '7',
|
||
label: '过敏',
|
||
},
|
||
{
|
||
value: '8',
|
||
label: '其他',
|
||
},
|
||
];
|
||
// 管路护理
|
||
const pipelinecareOption = [
|
||
{
|
||
value: '1',
|
||
label: '胃管',
|
||
},
|
||
{
|
||
value: '2',
|
||
label: '导尿管',
|
||
},
|
||
{
|
||
value: '3',
|
||
label: '静脉置管',
|
||
},
|
||
{
|
||
value: '4',
|
||
label: '吸氧管',
|
||
},
|
||
{
|
||
value: '5',
|
||
label: 'T管',
|
||
},
|
||
{
|
||
value: '6',
|
||
label: '胸腔引流管',
|
||
},
|
||
{
|
||
value: '7',
|
||
label: '腹腔引流管',
|
||
},
|
||
{
|
||
value: '8',
|
||
label: '伤口引流管',
|
||
},
|
||
{
|
||
value: '9',
|
||
label: '脑室引流管',
|
||
},
|
||
{
|
||
value: '10',
|
||
label: '其他',
|
||
},
|
||
];
|
||
const rulesFrom = ref({
|
||
date: '', //日期 年月日
|
||
time: '', //时间 十分
|
||
recordTime: '', //组合日期时间 年月日时分
|
||
consciousnessCodeList: [], //意识code
|
||
temperature: '', //体温
|
||
heartRate: '', //心率
|
||
pulse: '', //脉搏
|
||
breathe: '', //呼吸
|
||
bloodPressure: '', //血压
|
||
bloodOxygen: '', //血氧
|
||
oxygenCodeList: [], //氧疗
|
||
oxygenflow: '', //氧疗流量
|
||
inputName: '', //入量名称
|
||
input: '', //入量
|
||
inputvia: '', //入量途径
|
||
outputName: '', //出量名称
|
||
output: '', //出量
|
||
skinconditionCodeList: [], //皮肤情况
|
||
pipelinecare: [], //管路护理
|
||
condition: '', //病情
|
||
nurse: '', //护士
|
||
oxygen: '',
|
||
});
|
||
const rules = reactive({
|
||
date: [{ required: true, message: '请选择日期', trigger: 'blur' }],
|
||
time: [{ required: true, message: '请选择时间', trigger: 'blur' }],
|
||
});
|
||
const dateChange = () => {
|
||
rulesFrom.value.recordTime = rulesFrom.value.date + ' ' + rulesFrom.value.time + ':00';
|
||
};
|
||
// 计算时间
|
||
rulesFrom.value.recordTime = computed(() => {
|
||
console.log('操作记录时间计算', rulesFrom.value.date + ' ' + rulesFrom.value.time);
|
||
|
||
return rulesFrom.value.date + ' ' + rulesFrom.value.time;
|
||
});
|
||
// 保存form
|
||
const editForm = ref({
|
||
id: '',
|
||
definitionId: '',
|
||
definitionBusNo: '',
|
||
contentJson: '',
|
||
statusEnum: 1, // 0草稿/暂存 1提交 2归档 3修改
|
||
organizationId: 0,
|
||
encounterId: '',
|
||
patientId: '',
|
||
recordTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
||
createBy: '',
|
||
source: '3',
|
||
});
|
||
const emit = defineEmits(['cancleDialog', 'refreshData']);
|
||
const onCancle = () => {
|
||
emit('cancleDialog');
|
||
};
|
||
// 保存数据
|
||
const saveData = () => {
|
||
if (!patientInfo.value) {
|
||
ElMessage({
|
||
type: 'error',
|
||
message: '请选择患者',
|
||
});
|
||
}
|
||
editForm.value.contentJson = JSON.stringify(rulesFrom.value);
|
||
editForm.value.encounterId = patientInfo.value.encounterId;
|
||
editForm.value.patientId = patientInfo.value.patientId;
|
||
editForm.value.recordTime = rulesFrom.value.recordTime;
|
||
console.log('editForm=================>', JSON.stringify(rulesFrom.value));
|
||
formRef.value.validate(async (res) => {
|
||
if (res) {
|
||
await addRecord(editForm.value);
|
||
if (editForm.value.id && editForm.value.id.length > 0) {
|
||
ElMessage.success('护理记录修改成功');
|
||
} else {
|
||
ElMessage.success('护理记录保存成功');
|
||
}
|
||
emit('refreshData');
|
||
}
|
||
});
|
||
};
|
||
// 获取护理记录单类型
|
||
const getDefinitionIdNet = async () => {
|
||
const res = await getTemperatureType({ menuEnum: '3' });
|
||
//默认选中第一个
|
||
if (res.data?.length > 0) {
|
||
const obj = res.data[0];
|
||
editForm.value.definitionId = obj.id;
|
||
editForm.value.definitionBusNo = obj.busNo;
|
||
}
|
||
};
|
||
watch(patientInfo, () => {
|
||
getDefinitionIdNet();
|
||
});
|
||
|
||
// 重置
|
||
const reset = () => {
|
||
rulesFrom.value = {
|
||
date: '', //日期 年月日
|
||
time: '', //时间 十分
|
||
recordTime: '', //组合日期时间 年月日时分
|
||
consciousnessCodeList: [], //意识code
|
||
temperature: '', //体温
|
||
heartRate: '', //心率
|
||
pulse: '', //脉搏
|
||
breathe: '', //呼吸
|
||
bloodPressure: '', //血压
|
||
bloodOxygen: '', //血氧
|
||
oxygenCodeList: [], //氧疗
|
||
oxygenflow: '', //氧疗流量
|
||
inputName: '', //入量名称
|
||
input: '', //入量
|
||
inputvia: '', //入量途径
|
||
outputName: '', //出量名称
|
||
output: '', //出量
|
||
skinconditionCodeList: [], //皮肤情况
|
||
pipelinecare: [], //管路护理
|
||
condition: '', //病情
|
||
nurse: '', //护士
|
||
};
|
||
editForm.value = {
|
||
id: '',
|
||
definitionId: '',
|
||
definitionBusNo: '',
|
||
contentJson: '',
|
||
statusEnum: 1, // 0草稿/暂存 1提交 2归档 3修改
|
||
organizationId: 0,
|
||
encounterId: '',
|
||
patientId: '',
|
||
recordTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
||
createBy: '',
|
||
source: '3',
|
||
};
|
||
getDefinitionIdNet();
|
||
};
|
||
// 编辑
|
||
const editEmit = (row) => {
|
||
console.log('rowwwww=======>', JSON.stringify(row));
|
||
editForm.value.id = row.id;
|
||
editForm.value.definitionId = row.definitionId;
|
||
editForm.value.definitionBusNo = row.definitionBusNo;
|
||
rulesFrom.value = JSON.parse(row.contentJson);
|
||
};
|
||
defineExpose({ reset, editEmit });
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.main {
|
||
display: flex;
|
||
flex-direction: column;
|
||
.title {
|
||
width: 100%;
|
||
text-align: center;
|
||
}
|
||
.foundation {
|
||
.foundation-content {
|
||
.foundation-content-first {
|
||
display: flex;
|
||
}
|
||
.foundation-content-second {
|
||
display: flex;
|
||
}
|
||
}
|
||
}
|
||
.oxygen {
|
||
.oxygen-title {
|
||
}
|
||
.oxygen-content {
|
||
display: flex;
|
||
}
|
||
}
|
||
.input {
|
||
.input-title {
|
||
}
|
||
.input-content {
|
||
display: flex;
|
||
}
|
||
}
|
||
.out {
|
||
.out-title {
|
||
}
|
||
.out-content {
|
||
display: flex;
|
||
}
|
||
}
|
||
}
|
||
.commoncss {
|
||
display: flex;
|
||
}
|
||
.unit {
|
||
width: 50px;
|
||
}
|
||
.wait-flex {
|
||
flex: 1;
|
||
}
|
||
.commone-title {
|
||
font-weight: bold;
|
||
}
|
||
</style>
|