Files
his/openhis-ui-vue3/src/template/FallBedFallAssessment.vue
2025-12-27 15:30:40 +08:00

938 lines
26 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>
<div class="business">
<!-- <el-table
:data="tableDataSource"
border
stripe
fit
:header-cell-style="{ background: '#f2f2f2', color: 'black' }"
>
<el-table-column prop="content.recordTime" label="记录时间" />
<el-table-column prop="content.totalScore" label="评估分数" />
<el-table-column prop="content.patientCareSessionsTableList" label="护理措施" />
<el-table-column prop="content.nurseSignature" label="责任护士" />
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
plain
type="primary"
size="small"
@click="handleUpdate(scope.row)"
:disabled="admissionDataForm !== undefined"
>
编辑
</el-button>
<el-button
plain
type="danger"
size="small"
@click="handleDelete(scope.row)"
:disabled="admissionDataForm !== undefined"
>
删除
</el-button>
</template>
</el-table-column>
</el-table> -->
<div name="跌倒/坠床评估护理记录单" class="changeMajor" style="width: 99.9%">
<div>
<el-form ref="formRef" :model="form" style="width: 99.9%">
<el-form-item style="text-align: center">
<div
style="
width: 100%;
font-size: 14pt;
color: black;
text-align: center;
font-weight: 600;
line-height: 36px;
"
>
<span class="space">跌倒/坠床评估护理记录单</span>
</div>
</el-form-item>
<el-form-item label="日期:" class="changeMajorFromItem" style="width: 100%">
<el-row :span="20">
<el-col :span="8" style="padding-left: 0px !important">
<el-form-item>
<el-date-picker
v-model="form.ZKDATE"
type="datetime"
placeholder="选择日期"
value-format="YYYY-MM-DD HH:mm:ss"
format="YYYY-MM-DD HH:mm:ss"
style="width: 800px"
:disabled="admissionDataForm !== undefined"
/>
<!-- <span style="margin-left: 5px">时间</span>
<el-time-picker
v-model="form.ZKTIME"
placeholder="选择时间"
value-format="HH:mm:ss"
style="width: 40%"
:disabled="admissionDataForm !== undefined"
/> -->
</el-form-item>
</el-col>
<el-col :span="5">
<el-button
v-if="!updateFlag"
type="primary"
size="medium"
style="margin-left: 25px"
@click="onSubmit"
>
新增记录
</el-button>
<el-button
v-else
type="primary"
size="small"
style="margin-left: 5px"
@click="onSubmit"
>
保存记录
</el-button>
</el-col>
</el-row>
</el-form-item>
<el-form-item style="padding-top: 10px; margin: 0px !important">
<el-table
:data="dangerData"
border
:span-method="handleSpan"
style="text-align: center"
>
<el-table-column
v-for="column in dangerColumns"
:key="column.key"
:prop="column.key"
:width="column.width"
:label="column.title"
align="center"
/>
<el-table-column prop="id" label="选择" width="80" align="center">
<template #default="{ row }">
<el-checkbox v-model="row.checked" @change="handleDangerChange(row)" />
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item
style="text-align: center; margin-bottom: 0px; padding: 0px"
class="changeMajorFromItem"
>
<el-row :span="24">
<el-col :span="24">
<span style="font-size: large">总分</span>
<span>{{ totalScore }}</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item style="padding-top: 10px">
<el-table
:data="nursingData"
border
:span-method="arraySpanMethod"
style="width: 100%"
>
<el-table-column
v-for="column in nursingColumns"
:key="column.key"
:prop="column.key"
:width="column.width"
:label="column.title"
align="center"
/>
<el-table-column prop="id" label="选择" width="80" align="center">
<template #default="{ row }">
<el-checkbox v-model="row.checked" @change="handleNursingChange(row)" />
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item
style="text-align: center; margin-bottom: 0px; padding: 0px"
class="changeMajorFromItem"
>
<el-row
:span="24"
style="display: flex; justify-content: center; align-items: center"
>
<div style="display: flex; align-items: center; gap: 10px">
<span style="font-size: large; margin-left: 10vh">护士签字</span>
<el-input
v-model="form.nurseSignature"
style="width: 300px; padding: 8px"
disabled
/>
</div>
</el-row>
</el-form-item>
<el-form-item>
<el-row :span="20">
<el-col :span="5">
<span>备注</span>
</el-col>
</el-row>
<el-form-item label-width="15px">
<ul class="instructions-list">
<li v-for="(item, index) in instructions" :key="index">{{ item }}</li>
</ul>
</el-form-item>
</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
</template>
<script setup>
defineOptions({
name: 'FallBedFallAssessment',
});
import { ref, reactive, computed, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { useRoute, useRouter } from 'vue-router';
import { patientInfo } from '../views/doctorstation/components/store/patient';
// 定义props和emits
const props = defineProps({
patientInfo: {
type: Object,
default: () => ({}),
},
});
const emits = defineEmits(['submitOk']);
// 响应式数据
const route = useRoute();
const router = useRouter();
const queryRef = ref();
const formRef = ref();
const wardCode = ref('');
const patientId = ref('');
const visitId = ref('');
const type = '跌倒/坠床评估护理记录单';
const updateFlag = ref(false);
const info = ref('返回信息');
const updateId = ref('');
const tableDataSource = ref([]);
const content = ref({});
const totalScore = ref(0);
const lastSubmit = ref('');
const admissionDataForm = ref(route.params.admissionData);
const form = reactive({
ZKDATE: '',
ZKTIME: '',
recordTime: '',
totalScore: 0,
bedFallRiskAssessmentList: [],
nurseSignature: '',
patientCareSessionsCheckedList: [],
});
// 危险因素表格列
const dangerColumns = [
{
key: 'content',
title: '内容',
width: '100',
},
{
key: 'project',
title: '项目',
},
{
key: 'evalContent',
title: '评定内容',
},
{
key: 'score',
title: '分数',
},
];
// 危险因素数据 - 使用ref确保响应性
const dangerData = ref([
{
id: '1',
content: '危险因素',
project: '年龄',
evalContent: '≥80周岁',
score: 5,
checked: false,
},
{ id: '2', content: '', evalContent: '≤3周岁≥3个月', score: 5, checked: false },
{ id: '3', content: '', evalContent: '>70周岁', score: 3, checked: false },
{ id: '4', content: '', evalContent: '≤5周岁', score: 5, checked: false },
{ id: '5', project: '既往史', evalContent: '跌倒史', score: 1, checked: false },
{ id: '6', evalContent: '坠床史', score: 2, checked: false },
{ id: '7', evalContent: '癫痫史', score: 2, checked: false },
{ id: '8', project: '意识状态', evalContent: '嗜睡', score: 2, checked: false },
{ id: '9', evalContent: '意识模糊', score: 2, checked: false },
{ id: '10', evalContent: '谵妄', score: 3, checked: false },
{ id: '11', evalContent: '躁动', score: 3, checked: false },
{ id: '12', project: '感官因素', evalContent: '头晕', score: 4, checked: false },
{ id: '13', evalContent: '听力障碍', score: 2, checked: false },
{ id: '14', evalContent: '视力障碍', score: 2, checked: false },
{
id: '15',
project: '肢体活动',
evalContent: '关节僵硬、变形、疼痛',
score: 1,
checked: false,
},
{ id: '16', evalContent: '借助器械', score: 2, checked: false },
{ id: '17', evalContent: '肢体偏瘫', score: 3, checked: false },
{ id: '18', evalContent: '肌肉震颤麻痹', score: 3, checked: false },
{ id: '19', evalContent: '体质虚弱、乏力', score: 1, checked: false },
{ id: '20', evalContent: '尿频、尿急', score: 1, checked: false },
{ id: '21', evalContent: '腹泻、便秘', score: 2, checked: false },
{ id: '22', project: '药物因素', evalContent: '散瞳剂', score: 1, checked: false },
{ id: '23', evalContent: '降压药', score: 1, checked: false },
{ id: '24', evalContent: '降糖药', score: 1, checked: false },
{ id: '25', evalContent: '镇静安眠药', score: 2, checked: false },
{ id: '26', evalContent: '镇痛抗癫痫', score: 2, checked: false },
{ id: '27', evalContent: '麻醉止痛剂', score: 2, checked: false },
]);
// 护理措施表格列
const nursingColumns = [
{
key: 'content',
width: '100',
title: '',
},
{
key: 'project',
title: '内容',
},
];
// 护理措施数据 - 使用ref确保响应性
const nursingData = ref([
{
id: '1',
content: '护理措施',
project: '告知患者及家属可能导致跌倒、坠床的原因,并采取相应防范措施',
checked: false,
},
{ id: '2', project: '悬挂预防跌倒、坠床标识,必要时班班交接', checked: false },
{ id: '3', project: '患者日常用物放于可及处', checked: false },
{ id: '4', project: '将呼叫器放于可及处,提醒患者下床时若有必要寻求帮助', checked: false },
{ id: '5', project: '依据风险程度,必要时专人陪住', checked: false },
{ id: '6', project: '保持地面无水渍、障碍物,病室及活动区域灯光充足', checked: false },
{ id: '7', project: '指导患者穿长短合适的衣裤及防滑鞋', checked: false },
{ id: '8', project: '适当使用床栏或约束带', checked: false },
]);
// 说明信息
const instructions = [
'1.评估对象:新入患者、术后患者、有病情变化时必须评估;',
'2.评分<5分低度风险无需连续评估无需采取预防措施',
'3.评分≥5高度风险每周至少评估一次需采取适宜的预防措施同时填写《预防患者跌倒/坠床知情告知书》',
];
// 计算属性
const calculate = computed(() => {
return dangerData.value
.filter((option) => option.checked)
.reduce((total, option) => total + option.score, 0);
});
const isFormEmpty = computed(() => {
return (
form.ZKDATE === '' && form.ZKTIME === '' && form.recordTime === '' && form.nurseSignature === ''
);
});
// 方法 - 不再需要handleData方法通过表单输入和按钮加载数据
const handleDangerChange = (row) => {
totalScore.value = calculate.value;
form.bedFallRiskAssessmentList = dangerData.value
.filter((item) => item.checked)
.map((item) => item.id);
};
const handleNursingChange = (row) => {
form.patientCareSessionsCheckedList = nursingData.value
.filter((item) => item.checked)
.map((item) => item.id);
};
const init = async () => {
// 使用模拟数据不再调用后端API
try {
console.log('使用模拟数据初始化表格');
// 生成一些模拟数据
const mockData = [
{
id: '1',
content: {
ZKDATE: '2023-01-15',
ZKTIME: '09:30:00',
recordTime: '2023-01-15 09:30:00',
totalScore: 8,
bedFallRiskAssessmentList: ['1', '5', '12'],
nurseSignature: '张护士',
patientCareSessionsCheckedList: ['1', '2', '3'],
patientCareSessionsTableList: '1,2,3',
},
},
{
id: '2',
content: {
ZKDATE: '2023-01-20',
ZKTIME: '14:20:00',
recordTime: '2023-01-20 14:20:00',
totalScore: 5,
bedFallRiskAssessmentList: ['3', '11'],
nurseSignature: '李护士',
patientCareSessionsCheckedList: ['1', '4'],
patientCareSessionsTableList: '1,4',
},
},
];
tableDataSource.value = [];
if (mockData && mockData.length > 0) {
mockData.forEach((item) => {
tableDataSource.value.push(item);
});
if (admissionDataForm.value !== undefined) {
const rowData = tableDataSource.value.filter(
(item) => item.content.recordTime === JSON.parse(admissionDataForm.value).assessmentDate
);
if (rowData.length > 0) {
handleUpdate(rowData[0]);
}
}
} else {
tableDataSource.value = [];
reset();
}
ElMessage.success('模拟数据加载成功');
} catch (error) {
console.error('初始化失败:', error);
}
};
const handleSpan = ({ row, column, rowIndex, columnIndex }) => {
if (columnIndex === 0) {
if (rowIndex === 0) {
return [dangerData.value.length, 1];
} else if (rowIndex > 0 && rowIndex < 27) {
return [0, 0];
}
if (rowIndex === 27) {
return [1, 4];
}
}
if (columnIndex === 1) {
if (rowIndex === 0) {
return [4, 1];
} else if (rowIndex > 0 && rowIndex < 4) {
return [0, 0];
}
if (rowIndex === 4) {
return [3, 1];
} else if (rowIndex > 0 && rowIndex < 7) {
return [0, 0];
}
if (rowIndex === 7) {
return [4, 1];
} else if (rowIndex > 0 && rowIndex < 11) {
return [0, 0];
}
if (rowIndex === 11) {
return [3, 1];
} else if (rowIndex > 0 && rowIndex < 14) {
return [0, 0];
}
if (rowIndex === 14) {
return [7, 1];
} else if (rowIndex > 0 && rowIndex < 21) {
return [0, 0];
}
if (rowIndex === 21) {
return [6, 1];
} else if (rowIndex > 0 && rowIndex < 27) {
return [0, 0];
}
}
return [1, 1];
};
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
// 护理措施
if (columnIndex === 0) {
if (rowIndex === 0) {
return [nursingData.value.length, 1];
} else if (rowIndex > 0 && rowIndex < 8) {
return [0, 0];
}
// 护士签名
if (rowIndex === 8) {
return [1, 2];
}
}
return [1, 1];
};
const onSubmit = async () => {
// 检查上次提交时间
if (lastSubmit.value && new Date() - lastSubmit.value < 2000) {
ElMessage.error('禁止重复提交!');
return;
}
// 更新上次提交时间
lastSubmit.value = new Date();
// 时间处理
if (form.ZKDATE) {
form.recordTime = form.ZKDATE;
}
if (form.ZKTIME) {
form.recordTime = form.ZKTIME;
}
if (form.ZKDATE && form.ZKTIME) {
form.recordTime = form.ZKDATE + ' ' + form.ZKTIME;
}
form.recordTime ? new Date(form.recordTime) : null;
if (isFormEmpty.value) {
ElMessage.error('请填写跌倒/坠床评估护理记录单后再进行操作');
return;
}
// 表单验证通过,收集数据
form.totalScore = totalScore.value;
try {
// 准备保存的数据
const saveData = {
...form,
// 添加患者相关信息
patientId: patientId.value,
visitId: visitId.value,
wardCode: wardCode.value,
// 确保选中项数组存在
bedFallRiskAssessmentList: form.bedFallRiskAssessmentList || [],
patientCareSessionsCheckedList: form.patientCareSessionsCheckedList || [],
};
// 提交表单数据
console.log('提交保存的数据:', saveData);
emits('submitOk', saveData);
// 更新本地数据
if (updateFlag.value) {
// 更新操作
const updatedIndex = tableDataSource.value.findIndex((item) => item.id === updateId.value);
if (updatedIndex !== -1) {
tableDataSource.value[updatedIndex].content = { ...form };
}
ElMessage.success('更新成功');
} else {
// 新增操作
const newRecord = {
id: Date.now().toString(),
content: { ...form },
};
tableDataSource.value.unshift(newRecord);
ElMessage.success('保存成功');
}
// 处理返回逻辑
if (admissionDataForm.value !== undefined) {
const admissionDataBack = JSON.parse(admissionDataForm.value);
admissionDataBack.project2 = totalScore.value;
if (route.params.updateId !== undefined) {
router.push({
name: 'admissionEvaluation',
params: {
admissionData: JSON.stringify(admissionDataBack),
updateId: route.params.updateId,
},
});
} else {
router.push({
name: 'admissionEvaluation',
params: { admissionData: JSON.stringify(admissionDataBack) },
});
}
}
// 重置表单
reset();
} catch (error) {
console.error('保存失败:', error);
ElMessage.error('保存失败,请重试');
}
};
const handleUpdate = (row) => {
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
if (
row.content.nurseSignature !== loginUser.userName &&
window.localStorage.getItem('editFlg') === '0'
) {
window.confirm('没有操作该数据的权限!');
} else {
reset();
updateFlag.value = true;
// 深拷贝数据
Object.assign(form, JSON.parse(JSON.stringify(row.content)));
totalScore.value = row.content.totalScore;
// 评估项目
dangerData.forEach((item) => {
item.checked = form.bedFallRiskAssessmentList.includes(item.id);
});
nursingData.forEach((item) => {
item.checked = form.patientCareSessionsCheckedList.includes(item.id);
});
updateId.value = row.id;
}
};
const reset = () => {
Object.assign(form, {
ZKDATE: '',
ZKTIME: '',
recordTime: '',
totalScore: 0,
bedFallRiskAssessmentList: [],
nurseSignature: '',
patientCareSessionsCheckedList: [],
});
// 初始化评估项目
dangerData.forEach((session) => {
session.checked = false;
});
// 初始化护理措施
nursingData.forEach((session) => {
session.checked = false;
});
totalScore.value = 0;
updateId.value = '';
updateFlag.value = false;
if (admissionDataForm.value !== undefined) {
const [date, time] = JSON.parse(admissionDataForm.value).assessmentDate.split(' ');
form.ZKDATE = date;
form.ZKTIME = time;
}
};
const handleDelete = (row) => {
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
if (
row.content.nurseSignature !== loginUser.userName &&
window.localStorage.getItem('editFlg') === '0'
) {
window.confirm('没有操作该数据的权限!');
} else {
reset();
// 模拟删除操作不再调用后端API
const index = tableDataSource.value.findIndex((item) => item.id === row.id);
if (index !== -1) {
tableDataSource.value.splice(index, 1);
updateFlag.value = false;
ElMessage.success('模拟删除成功');
} else {
ElMessage.error('删除失败');
}
}
};
const dc_ajax_preview = () => {
var args = {
report: urlAddRandomNo('./grf/NurseRecord_Pressure_208.grf'),
data: transformData(),
type: 'preview',
};
webapp_ws_ajax_run(args);
};
const transformData = () => {
const jsonDate = [...tableDataSource.value];
jsonDate.forEach((element) => {
element.content.bedFallRiskAssessmentList.forEach((i) => {
switch (i) {
case '1':
element.FS1 = '√';
break;
case '2':
element.FS2 = '√';
break;
case '3':
element.FS3 = '√';
break;
case '4':
element.FS4 = '√';
break;
case '5':
element.FS5 = '√';
break;
case '6':
element.FS6 = '√';
break;
case '7':
element.FS7 = '√';
break;
case '8':
element.FS8 = '√';
break;
case '9':
element.FS9 = '√';
break;
case '10':
element.FS10 = '√';
break;
case '11':
element.FS11 = '√';
break;
case '12':
element.FS12 = '√';
break;
case '13':
element.FS13 = '√';
break;
case '14':
element.FS14 = '√';
break;
case '15':
element.FS15 = '√';
break;
case '16':
element.FS16 = '√';
break;
case '17':
element.FS17 = '√';
break;
case '18':
element.FS18 = '√';
break;
case '19':
element.FS19 = '√';
break;
case '20':
element.FS20 = '√';
break;
case '21':
element.FS21 = '√';
break;
case '22':
element.FS22 = '√';
break;
case '23':
element.FS23 = '√';
break;
case '24':
element.FS24 = '√';
break;
case '25':
element.FS25 = '√';
break;
case '26':
element.FS26 = '√';
break;
case '27':
element.FS27 = '√';
break;
}
});
element.countsum = element.content.totalScore;
element.RQ = element.content.ZKDATE;
element.SJ = element.content.ZKTIME;
element.recordTime = element.content.ZKDATE + ' ' + element.content.ZKTIME;
element.SIGN = element.content.nurseSignature;
element.content.patientCareSessionsCheckedList.forEach((i) => {
switch (i) {
case '1':
element.HL1 = '√';
break;
case '2':
element.HL2 = '√';
break;
case '3':
element.HL3 = '√';
break;
case '4':
element.HL4 = '√';
break;
case '5':
element.HL5 = '√';
break;
case '6':
element.HL6 = '√';
break;
case '7':
element.HL7 = '√';
break;
case '8':
element.HL8 = '√';
break;
}
});
});
if (jsonDate.length == 0) {
jsonDate[0] = {};
}
jsonDate[0].RYRQ = patientInfo.value.admissionDateTime;
jsonDate[0].KS = patientInfo.value.deptName;
jsonDate[0].CH = patientInfo.value.bedLabel;
jsonDate[0].name = patientInfo.value.name;
jsonDate[0].sex = patientInfo.value.sex;
jsonDate[0].AGE = patientInfo.value.age;
jsonDate[0].ZYH = patientInfo.value.patientIdAndVisitId;
jsonDate[0].ZD = patientInfo.value.diagnosis;
const transformedData = {
master: jsonDate,
};
return transformedData;
};
// 生命周期钩子
onMounted(() => {
try {
// 安全获取用户信息
let loginUser = {};
const userStr = window.localStorage.getItem('loginUser');
if (userStr) {
loginUser = JSON.parse(userStr);
}
form.nurseSignature = loginUser.userName || '测试护士';
wardCode.value = window.localStorage.getItem('wardInfo') || '';
admissionDataForm.value = route.params.admissionData;
// 获取患者信息
if (patientInfo.value) {
patientId.value = patientInfo.value.patientId || '';
visitId.value = patientInfo.value.visitId || '';
}
// 自动初始化表格数据
// 延迟执行,确保所有数据都已初始化
setTimeout(() => {
init();
}, 100);
} catch (error) {
console.error('初始化错误:', error);
// 即使出错也要初始化表格,显示默认数据
setTimeout(() => {
init();
}, 100);
}
});
// 暴露接口
defineExpose({ form, submit: onSubmit, reset });
</script>
<style scoped>
.business {
background: white;
border-radius: 5px;
padding: 10px 16px;
height: calc(100vh - 250px);
overflow: auto;
display: grid;
grid-row-gap: 16px;
.changeMajor {
border: 2px solid gray;
padding: 20px;
border-radius: 5px;
}
.changeMajorFromItem {
border: 1px solid #ebeef5;
border-radius: 4px;
padding: 5px;
margin-bottom: 1px;
}
.tableBorder {
border: 1px solid #ebeef5;
}
.tableBorderRight {
border-right: 1px solid #ebeef5;
}
.tableBorderRightBottom {
border-right: 1px solid #ebeef5;
border-bottom: 1px solid #ebeef5;
}
.tableBorderBottom {
border-bottom: 1px solid #ebeef5;
}
.el-textarea {
overflow-y: auto;
min-height: 50px;
max-height: 300px;
}
.bed-no-label {
padding-right: 10px;
}
.title-inline {
display: inline-block;
}
.arrowhead {
margin-left: 6px;
font-size: 15px;
padding: 5px 10px;
}
.el-form-item {
margin-bottom: 0px !important;
}
}
</style>