docs(release-notes): 添加住院护士站划价功能说明和发版记录

- 新增住院护士站划价服务流程说明文档,详细描述了从参数预处理到结果响应的五大阶段流程
- 包含耗材类医嘱和诊疗活动类医嘱的差异化处理逻辑
- 添加完整的发版内容记录,涵盖新增菜单功能和各模块优化点
- 记录了住院相关功能的新增和门诊业务流程的修复
```
This commit is contained in:
2025-12-25 14:13:14 +08:00
parent 85fcb7c2e2
commit abc0674531
920 changed files with 107068 additions and 14495 deletions

View File

@@ -0,0 +1,844 @@
<template>
<div class="main">
<PatientList :selected-patient="patientInfo" :on-select="handlePatientSelect" />
<el-container style="height: 100%">
<el-main style="padding: 0">
<div style="margin-bottom: 10px">
<el-date-picker
v-model="intervalTime"
type="daterange"
range-separator="~"
start-placeholder="起始时间"
end-placeholder="结束时间"
:size="medium"
value-format="YYYY-MM-DD"
/>
<el-button style="margin-left: 10px" type="primary" size="default" @click="onSearch"
>搜索</el-button
>
<el-button type="primary" size="default" @click="onAddRecord">新增</el-button>
<el-button type="primary" size="default" @click="printNursingRecord">打印</el-button>
</div>
<div class="header">
<div class="header-item" v-for="(item, index) in personInfo1" :key="index">
<div class="header-title">
<el-text>{{ item.title }}</el-text>
</div>
<div class="header-content">
<el-text>{{ item.text }}</el-text>
</div>
</div>
<!-- <div class="header-item">
<div class="header-title"><el-text></el-text></div>
<div class="header-content"><el-text>20</el-text></div>
<div class="header-title"><el-text></el-text></div>
</div> -->
</div>
<div class="table-contanier">
<el-table
:data="tableData"
:span-method="arraySpanMethod"
border
style="width: 100%"
class="custom-header-table"
height="100%"
>
<!-- 日期与时间合并表头 -->
<el-table-column align="center" class-name="date-time-header" width="150px">
<template #header>
<div class="date-time-container">
<div class="date-label">日期</div>
<div class="time-label">时间</div>
</div>
</template>
<template #default="scope">
<div class="date-time-cell">
<div
v-if="
recordsData[scope.$index].id === null ||
recordsData[scope.$index].id === undefined
"
>
<div style="color: red; font-weight: bold">
总入量为:{{ scope.row.input }}、总出量为:{{ scope.row.output }}
</div>
</div>
<div v-else style="display: flex">
<div class="date-cell">{{ scope.row.date }}</div>
/
<div class="time-cell">{{ scope.row.time }}</div>
</div>
</div>
</template>
</el-table-column>
<!-- 一般column -->
<!-- <el-table-column
v-for="column in averageColumn"
:key="column.id"
:label="column.title"
align="center"
>
<template #default="scope">
{{ averageColumn($index).prop == 'temperature' ? scope.temperature : '' }}
</template>
</el-table-column> -->
<!-- 嵌套column -->
<!-- <el-table-column
v-for="column in nestingColumn"
:key="column.id"
:label="column.title"
align="center"
>
<el-table-column
v-for="column in column.child"
:prop="column.prop"
:key="column.id"
:label="column.title"
align="center"
></el-table-column>
</el-table-column> -->
<el-table-column label="意识" align="center" width="200px">
<template #default="scope">
<!-- <el-select
v-model="scope.row.consciousnessCodeList"
placeholder=""
multiple
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="99"
disabled=""
>
<el-option
v-for="item in ysOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<el-tag
style="margin: 2px"
type=""
v-for="item in filterYs(scope.row.consciousnessCodeList)"
:key="item.value"
>{{ item.label }}</el-tag
>
</template>
</el-table-column>
<el-table-column label="体温(℃)" align="center" width="100px">
<template #default="scope">
<el-text> {{ scope.row.temperature }}</el-text>
</template>
</el-table-column>
<el-table-column label="脉搏(次/分)" align="center" width="100px">
<template #default="scope">
<el-text> {{ scope.row.pulse }}</el-text>
</template>
</el-table-column>
<el-table-column label="呼吸(次/分)" align="center" width="100px">
<template #default="scope">
<el-text> {{ scope.row.breathe }}</el-text>
</template>
</el-table-column>
<el-table-column label="血压(mmHg)" align="center" width="100px">
<template #default="scope">
<el-text> {{ scope.row.bloodPressure }}</el-text>
</template>
</el-table-column>
<el-table-column label="血氧饱和度(%)" align="center" width="110px">
<template #default="scope">
<el-text> {{ scope.row.bloodOxygen }}</el-text>
</template>
</el-table-column>
<el-table-column label="吸氧升/分" align="center" width="110px">
<template #default="scope">
<el-text> {{ scope.row?.oxygen }}</el-text>
</template>
</el-table-column>
<!-- 入量列组 -->
<el-table-column label="入量(ml)" align="center">
<el-table-column label="名称用法" align="center">
<template #default="scope">
<el-text> {{ scope.row.inputName }}</el-text>
</template>
</el-table-column>
<el-table-column label="量" align="center">
<template #default="scope">
<el-text> {{ scope.row.input }}</el-text>
</template>
</el-table-column>
</el-table-column>
<!-- 出量列组 -->
<el-table-column label="出量" align="center">
<el-table-column label="名称" align="center">
<template #default="scope">
<el-text> {{ scope.row.outputName }}</el-text>
</template>
</el-table-column>
<el-table-column label="量" align="center">
<template #default="scope">
<el-text> {{ scope.row.output }}</el-text>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="skin" label="皮肤" align="center" width="200px">
<template #default="scope">
<!-- <el-select
placeholder=""
v-model="scope.row.skinconditionCodeList"
multiple
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="99"
disabled=""
>
<el-option
v-for="item in skinconditionOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<el-tag
style="margin: 2px"
type=""
v-for="item in filterPf(scope.row.skinconditionCodeList)"
:key="item.value"
>{{ item.label }}</el-tag
>
</template>
</el-table-column>
<el-table-column prop="tube" label="管路" align="center" width="200px">
<template #default="scope">
<!-- <el-select
placeholder=""
v-model="scope.row.pipelinecare"
multiple
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="99"
disabled=""
>
<el-option
v-for="item in pipelinecareOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<el-tag
style="margin: 2px"
type=""
v-for="item in filterGl(scope.row.pipelinecare)"
:key="item.value"
>{{ item.label }}</el-tag
>
</template>
</el-table-column>
<el-table-column prop="observation" label="病情观察及措施" align="center" width="120px">
<template #default="scope">
<el-text> {{ scope.row.condition }}</el-text>
</template>
</el-table-column>
<el-table-column
prop="nurse"
label="护士签名"
align="center"
width="100px"
></el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="150px">
<template #default="scope" style="display: flex">
<el-button
type="primary"
size="small"
plain
@click="onEdit(scope.row, scope.$index)"
>编辑</el-button
>
<el-button
type="danger"
size="small"
plain
@click="onDelete(scope.row, scope.$index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="tip-text">
<el-text
>备注:以下项目在相应表格中填写序号:一意识(1、意识清 2、嗜睡3、意识模糊 4、昏睡5.浅昏迷
6.深昏迷)二、管路(1.尿管2.鼻饲管3.胃肠减压管4.
外周静脉置管)5.中心静脉置管6.胸腔闭式引流管 7.腹腔引流管 8.头部引流管 9.其他引流管 10
其他置管)三、皮肤(1.完好 2压疮 3.出血点 4.破损 5. 水肿)。</el-text
>
</div>
</el-main>
</el-container>
<!-- 弹出框 -->
<el-dialog v-model="dialogTableVisible" :show-close="false" width="85%" style="height: 700px">
<OperationRecord
@cancleDialog="onCancle"
@refreshData="refreshFn"
ref="redordRef"
></OperationRecord>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, nextTick, watch } from 'vue';
import OperationRecord from './operationrecord.vue';
import { patientInfo, updatePatientInfo } from '../../inpatientDoctor/home/store/patient';
import { getTemperatureType } from '../tprsheet/api/api';
import { getSummaryList } from './api';
import { getRecordByEncounterIdList } from '../../inpatientDoctor/home/emr/api';
import { deleteRecord } from '../../inpatientDoctor/home/emr/api';
import printUtils, { PRINT_TEMPLATE } from '@/utils/printUtils';
import PatientList from '@/components/PatientList/patient-list.vue';
import { ElMessage } from 'element-plus';
// 处理患者选择
const handlePatientSelect = (patient) => {
updatePatientInfo(patient);
};
const dialogTableVisible = ref(false);
const intervalTime = ref([]);
const redordRef = ref();
const isTemplate = ref(false);
const editForm = ref({
definitionId: '',
startTime: '',
endTime: '',
});
const recordsData = ref([]);
watch(patientInfo, (newVal) => {
const dataArr = [
{ title: '科别', text: newVal.inHospitalOrgName ?? '' },
{ title: '姓名', text: newVal.patientName ?? '' },
{ title: '年龄', text: newVal.age ?? '' },
{ title: '性别', text: newVal.genderEnum_enumText ?? '' },
{ title: '床号', text: newVal.bedName ?? '' },
{ title: '住院', text: '人民医院' },
{ title: '入院日期', text: newVal.inHospitalTime ?? '' },
{ title: '诊断', text: newVal.regDiagnosisName ?? '' },
];
Object.assign(personInfo1, dataArr);
getDefinitionIdNet();
});
// 意识
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 filterYs = (row) => {
let dats = [];
(row || []).forEach((str) => {
ysOptions.forEach((item) => {
if (item.value == str) {
dats.push(item);
}
});
});
return dats;
};
// 过滤皮肤
const filterPf = (row) => {
let dats = [];
(row || []).forEach((str) => {
skinconditionOption.forEach((item) => {
if (item.value == str) {
dats.push(item);
}
});
});
return dats;
};
// 过滤管路
const filterGl = (row) => {
let dats = [];
(row || []).forEach((str) => {
pipelinecareOption.forEach((item) => {
if (item.value == str) {
dats.push(item);
}
});
});
return dats;
};
// 获取护理记录单类型
const getDefinitionIdNet = async () => {
const res = await getTemperatureType({ menuEnum: '3' });
//默认选中第一个
if (res.data?.length > 0) {
isTemplate.value = true;
const obj = res.data[0];
editForm.value.definitionId = obj.id;
getTableList();
} else {
isTemplate.value = false;
}
};
const refreshFn = () => {
getTableList();
};
// 获取列表数据
const getTableList = async () => {
const res = await getSummaryList({
...editForm.value,
encounterId: patientInfo.value.encounterId,
patientId: patientInfo.value.patientId,
});
console.log('getTableList========>', JSON.stringify(res.data));
recordsData.value = res.data || [];
const tables = [];
(res.data || []).forEach((item) => {
const obj = JSON.parse(item.contentJson);
tables.push(obj);
});
tableData.value = tables;
};
// 个人信息
const personInfo1 = reactive([
{ title: '科别', text: '' },
{ title: '姓名', text: '' },
{ title: '年龄', text: '' },
{ title: '性别', text: '' },
{ title: '床号', text: '' },
{ title: '住院', text: '' },
{ title: '入院日期', text: '' },
{ title: '诊断', text: '' },
]);
// 普通表头配置
const averageColumn = [
{
id: '0',
prop: 'consciousness',
title: '意识',
},
{
id: '1',
prop: 'temperature',
title: '体温(℃)',
},
{
id: '2',
prop: 'pulse',
title: '脉搏(次/分)',
},
{
id: '3',
prop: 'respiration',
title: '呼吸(次/分)',
},
{
id: '4',
prop: 'bloodPressure',
title: '血压(mmHg)',
},
{
id: '5',
prop: 'bloodOxygen',
title: '血氧饱和度(%)',
},
{
id: '6',
prop: 'oxygenFlow',
title: '吸氧(升/分)',
},
];
//
const nestingColumn = ref([
{
id: '7',
prop: '',
title: '入量(ml)',
child: [
{
id: '7-1',
prop: 'name',
title: '名称用法',
},
{
id: '7-2',
prop: 'plan',
title: '量',
},
],
},
{
id: '8',
prop: '',
title: '出量',
child: [
{
id: '8-1',
prop: 'name',
title: '名称',
},
{
id: '8-2',
prop: 'plan',
title: '量',
},
],
},
]);
// 表格数据
const tableData = ref([]);
// 合并单元格
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
const obj = recordsData.value[rowIndex];
if (obj.id === undefined || obj.id === null) {
if (columnIndex == 0) {
return {
rowspan: 1,
colspan: 17,
};
} else {
return {
rowspan: 0,
colspan: 0,
};
}
}
return {
rowspan: 1,
colspan: 1,
};
// if (rowIndex == 1) {
// if (columnIndex == 0) {
// return {
// rowspan: 1,
// colspan: 17,
// };
// } else {
// return {
// rowspan: 0,
// colspan: 0,
// };
// }
// }
// return {
// rowspan: 1,
// colspan: 1,
// };
};
// 编辑
const onEdit = (row, index) => {
const item = recordsData.value[index];
dialogTableVisible.value = true;
nextTick(() => {
if (redordRef) {
redordRef.value.editEmit(item);
}
});
};
// 新增
const onAddRecord = () => {
if (!patientInfo.value) {
ElMessage({
type: 'error',
message: '请选择患者',
});
return;
}
if (!isTemplate.value) {
ElMessage({
type: 'error',
message: '护理记录未配置,请联系管理员',
});
return;
}
dialogTableVisible.value = true;
nextTick(() => {
if (redordRef) {
redordRef.value.reset();
}
});
};
// 搜索
const onSearch = () => {
if (typeof intervalTime === 'object' && intervalTime === null) {
editForm.value.startTime = '';
editForm.value.endTime = '';
getTableList();
} else {
if (intervalTime.value?.length > 0) {
editForm.value.startTime = intervalTime.value[0];
editForm.value.endTime = intervalTime.value[1];
getTableList();
} else {
editForm.value.startTime = '';
editForm.value.endTime = '';
getTableList();
}
}
};
// 删除
const onDelete = async (row, index) => {
const ids = recordsData.value[index].id;
debugger;
// recordsData.value
await deleteRecord([ids]);
getTableList();
};
// 关闭弹出曾次
const onCancle = () => {
dialogTableVisible.value = false;
};
</script>
<style lang="scss" scoped>
.main {
padding-top: 10px;
display: flex;
height: 100%;
.header {
// background: red;
display: flex;
justify-content: space-between;
padding: 0 10px;
.header-item {
display: flex;
align-items: center;
}
}
.table-contanier {
margin-top: 10px;
background: red;
height: calc(100vh - 280px);
.custom-header-table ::v-deep .el-table__header-wrapper th {
background-color: #f5f7fa;
font-weight: normal;
}
/* 日期时间表头样式 */
.date-time-header {
width: 120px;
}
.date-time-container {
position: relative;
width: 100%;
height: 100%;
min-height: 60px;
}
.date-label {
position: absolute;
top: 5px;
left: 5px;
z-index: 1;
}
.time-label {
position: absolute;
bottom: 5px;
right: 5px;
z-index: 1;
}
.date-time-container::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
154deg,
transparent 49.5%,
#dcdfe6 49.5%,
#dcdfe6 50.5%,
transparent 50.5%
);
pointer-events: none;
}
/* 日期时间单元格样式 */
.date-time-cell {
// position: relative;
display: flex;
// flex-direction: column;
align-items: center;
// height: 100%;
// min-height: 48px;
}
.date-cell {
// position: absolute;
// top: 5px;
// left: 5px;
// background: red;
}
.time-cell {
// position: absolute;
// bottom: 5px;
// right: 5px;
height: 100%;
// width: 100%;
text-align: left;
}
}
.tip-text {
padding: 0 10px;
}
}
</style>