docs(release-notes): 添加住院护士站划价功能说明和发版记录 - 新增住院护士站划价服务流程说明文档,详细描述了从参数预处理到结果响应的五大阶段流程 - 包含耗材类医嘱和诊疗活动类医嘱的差异化处理逻辑 - 添加完整的发版内容记录,涵盖新增菜单功能和各模块优化点 - 记录了住院相关功能的新增和门诊业务流程的修复 ```
622 lines
17 KiB
Vue
622 lines
17 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<el-row :gutter="10">
|
||
<el-form :model="queryParams" ref="queryRef" inline="true">
|
||
<el-form-item label="入院病区" prop="wardId" style="width: 240px">
|
||
<el-select
|
||
v-model="queryParams.wardId"
|
||
@change="changeWardLocationId"
|
||
filterable
|
||
clearable
|
||
>
|
||
<el-option
|
||
v-for="item in initInfoOptions.wardListOptions"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:value="item.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="入院病房" prop="houseId">
|
||
<el-select
|
||
v-model="queryParams.houseId"
|
||
style="width: 240px"
|
||
@change="handleQuery"
|
||
filterable
|
||
clearable
|
||
>
|
||
<el-option
|
||
v-for="item in wardLocationList"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:value="item.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="住院状态" prop="encounterStatus">
|
||
<el-select
|
||
v-model="queryParams.encounterStatus"
|
||
style="width: 240px"
|
||
@change="handleQuery"
|
||
filterable
|
||
clearable
|
||
>
|
||
<el-option label="全部" value="" />
|
||
<el-option
|
||
v-for="item in initInfoOptions.encounterStatusOptions"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="床位状态" prop="bedStatus" style="width: 240px">
|
||
<el-select v-model="bedStatusFilter" filterable clearable @change="handleQuery">
|
||
<el-option label="全部" value="" />
|
||
<el-option
|
||
v-for="item in initInfoOptions.bedStatusOptions"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-row>
|
||
<el-row :gutter="10">
|
||
<el-col :span="4">
|
||
<el-card shadow="never">
|
||
<template #header>
|
||
<div class="card-header">
|
||
<span>新入院患者</span>
|
||
</div>
|
||
</template>
|
||
<el-input
|
||
v-model="queryParams.searchKey"
|
||
placeholder="请输入住院号"
|
||
clearable
|
||
style="width: 100%; margin-bottom: 10px"
|
||
@keyup.enter="handleQuery"
|
||
>
|
||
<template #append>
|
||
<el-button icon="Search" @click="handleQuery" />
|
||
</template>
|
||
</el-input>
|
||
<el-scrollbar height="700px">
|
||
<div
|
||
v-for="(item, index) in patientList"
|
||
:class="item.active ? 'patient-card actived' : 'patient-card'"
|
||
:key="item.id"
|
||
@click="handleCardClick(item, index)"
|
||
@dblclick="handleCardDblClick(item)"
|
||
>
|
||
<div class="main-info-container">
|
||
<div class="name-container">
|
||
<!-- 患者姓名 -->
|
||
<div class="name" style="max-width: 90px">
|
||
<el-text class="name" width="auto">{{ item.patientName || '未知' }}</el-text>
|
||
</div>
|
||
</div>
|
||
<div class="name-container">
|
||
<!-- 患者性别/年龄 -->
|
||
<div class="age">
|
||
<el-text class="name" width="auto">
|
||
{{ item.genderEnum_enumText }}/{{ item.age }}/{{ item.priorityEnum_enumText }}
|
||
</el-text>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="patient-tag" :class="getPatientTagClass(item)">
|
||
{{ item.encounterStatus_enumText }}
|
||
</div>
|
||
</div>
|
||
<div style="margin-left: 15px; color: #333; font-size: 14px">
|
||
{{ item.contractName }}
|
||
</div>
|
||
<div class="doctor-parent-line" />
|
||
<div class="personal-info-container">
|
||
<div class="name-container">
|
||
<div class="name">
|
||
<el-text class="name" width="auto">入院时间:</el-text>
|
||
<el-text class="name" width="auto">
|
||
{{ item.startTime ? formatDate(item.startTime) : '-' }}
|
||
</el-text>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="personal-info-container">
|
||
<div class="name-container">
|
||
<el-text class="name" width="auto">入院科室:</el-text>
|
||
<el-text class="name" width="auto">
|
||
{{ item.organizationName ? item.organizationName : '-' }}
|
||
</el-text>
|
||
</div>
|
||
</div>
|
||
<div class="personal-info-container">
|
||
<div class="name-container">
|
||
<el-text class="name" width="auto">住院号:</el-text>
|
||
<el-text class="name" width="auto">
|
||
{{ item.busNo ? item.busNo : '-' }}
|
||
</el-text>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-scrollbar>
|
||
</el-card>
|
||
</el-col>
|
||
<el-col :span="20">
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="Plus"
|
||
@click="handleAddFeeItemm"
|
||
:disabled="!selectPatient"
|
||
>
|
||
新增滚费项目
|
||
</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
<el-table :data="rollInfoPageList" ref="table" border>
|
||
<el-table-column label="滚费项目" prop="definitionName" align="center" />
|
||
<el-table-column label="单位" prop="unitCodeName" align="center" />
|
||
<el-table-column label="数量" prop="quantity" align="center" />
|
||
<el-table-column label="状态" prop="statusEnum_enumText" align="center">
|
||
<template #default="scope">
|
||
<el-tag v-if="scope.row.statusEnum_enumText === '启用'" type="success">
|
||
{{ scope.row.statusEnum_enumText }}
|
||
</el-tag>
|
||
<el-tag v-else type="warning">
|
||
{{ scope.row.statusEnum_enumText }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" align="center">
|
||
<template #default="scope">
|
||
<el-button
|
||
link
|
||
type="success"
|
||
icon="Edit"
|
||
@click="handleEnable(scope.row)"
|
||
v-if="scope.row.statusEnum_enumText === '停用'"
|
||
>
|
||
启用
|
||
</el-button>
|
||
<el-button
|
||
link
|
||
type="warning"
|
||
icon="Edit"
|
||
@click="handleStop(scope.row)"
|
||
v-if="scope.row.statusEnum_enumText === '启用'"
|
||
>
|
||
停用
|
||
</el-button>
|
||
<el-button link icon="Edit" type="danger" @click="handleDelete(scope.row)">
|
||
删除
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-col>
|
||
</el-row>
|
||
<el-dialog
|
||
title="新增滚费配置"
|
||
v-model="dialogVisible"
|
||
width="400px"
|
||
:before-close="handleClose"
|
||
append-to-body
|
||
>
|
||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||
<el-form-item label="滚费项目" prop="instanceId">
|
||
<el-select
|
||
v-model="form.instanceId"
|
||
placeholder="请选择"
|
||
filterable
|
||
clearable
|
||
style="width: 100%"
|
||
@change="handleChageInstanceId"
|
||
>
|
||
<el-option
|
||
v-for="item in feeItemOptions"
|
||
:key="item.instanceId"
|
||
:label="item.instanceName"
|
||
:value="item.instanceId"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="数量" prop="quantity">
|
||
<el-input-number
|
||
v-model="form.quantity"
|
||
placeholder="请输入数量"
|
||
controls-position="right"
|
||
style="width: 100%"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="单位" prop="unit">
|
||
<el-input v-model="form.unit" placeholder="请输入" disabled style="width: 100%" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button @click="handleClose">取 消</el-button>
|
||
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
<script setup>
|
||
import { onBeforeMount, onMounted, reactive, ref, getCurrentInstance } from 'vue';
|
||
import {
|
||
getPendingInfo,
|
||
getBedInfo,
|
||
getInit,
|
||
childLocationList,
|
||
getPractitionerWard,
|
||
getDataSource,
|
||
saveInpatientRoll,
|
||
getRollInfoPage,
|
||
enableRoll,
|
||
stopRoll,
|
||
deleteRoll,
|
||
} from './components/api.js';
|
||
import { formatDate } from '@/utils/index';
|
||
import { ElMessage } from 'element-plus';
|
||
const { proxy } = getCurrentInstance();
|
||
|
||
const transferInDialogVisible = ref(false);
|
||
const dialogVisible = ref(false);
|
||
const state = reactive({});
|
||
const loading = ref(false);
|
||
const total = ref();
|
||
const badList = ref([]);
|
||
const patientList = ref([]);
|
||
const pendingInfo = ref({});
|
||
const wardLocationList = ref([]);
|
||
const priorityOptions = ref([]);
|
||
const initInfoOptions = ref({
|
||
encounterStatusOptions: [],
|
||
bedStatusOptions: [],
|
||
priorityOptions: [],
|
||
wardListOptions: [],
|
||
});
|
||
|
||
// 新增床状态筛选字段
|
||
const bedStatusFilter = ref('');
|
||
|
||
onBeforeMount(() => {});
|
||
const queryParams = ref({
|
||
pageNo: 1,
|
||
pageSize: 50,
|
||
searchKey: '',
|
||
wardId: '',
|
||
houseId: '',
|
||
encounterStatus: '',
|
||
bedStatus: '', // 这个字段现在只用于床位查询,不再用于患者列表查询
|
||
});
|
||
const formRef = ref(null);
|
||
const form = reactive({
|
||
instanceId: undefined,
|
||
unit: undefined,
|
||
quantity: 1,
|
||
});
|
||
|
||
const rules = {
|
||
instanceId: [{ required: true, message: '请选择滚费项目', trigger: 'change' }],
|
||
quantity: [
|
||
{ required: true, message: '请输入数量', trigger: 'blur' },
|
||
{ type: 'number', min: 0, message: '数量必须大于等于0', trigger: 'blur' },
|
||
],
|
||
};
|
||
onMounted(() => {
|
||
getInit().then((res) => {
|
||
initInfoOptions.value = res.data;
|
||
priorityOptions.value = res.data.priorityOptions || [];
|
||
getList();
|
||
});
|
||
getPractitionerWard().then((res) => {
|
||
queryParams.value.wardId = res[0].id;
|
||
initInfoOptions.value.wardListOptions = res;
|
||
changeWardLocationId(res[0].id);
|
||
});
|
||
});
|
||
defineExpose({ state });
|
||
const feeItemOptions = ref([]);
|
||
async function getInitDataSourceOptions() {
|
||
const res = await getDataSource();
|
||
feeItemOptions.value = res.data;
|
||
}
|
||
const getList = () => {
|
||
getPatientList();
|
||
// 床位查询不使用encounterStatus参数,只使用基本的查询参数
|
||
const bedQueryParams = {
|
||
...queryParams.value,
|
||
encounterStatus: undefined, // 移除encounterStatus,确保不影响床位列表查询
|
||
};
|
||
getBedInfo(bedQueryParams).then((res) => {
|
||
badList.value = res.data.records;
|
||
});
|
||
};
|
||
function handleEnable(row) {
|
||
proxy
|
||
.$confirm('确定启用吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => {
|
||
enableRoll([row.id]).then((res) => {
|
||
if (res.code == 200) {
|
||
proxy.$modal.msgSuccess('启用成功');
|
||
getRollInfoPageList();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
function handleStop(row) {
|
||
proxy
|
||
.$confirm('确定停用吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => {
|
||
stopRoll([row.id]).then((res) => {
|
||
if (res.code == 200) {
|
||
proxy.$modal.msgSuccess('停用成功');
|
||
getRollInfoPageList();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
function handleDelete(row) {
|
||
proxy
|
||
.$confirm('确定删除吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => {
|
||
deleteRoll([row.id]).then((res) => {
|
||
if (res.code == 200) {
|
||
proxy.$modal.msgSuccess('删除成功');
|
||
getRollInfoPageList();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
// 重置查询条件
|
||
function resetQuery() {
|
||
queryParams.value = {
|
||
pageNo: 1,
|
||
pageSize: 50,
|
||
searchKey: '',
|
||
wardId: '',
|
||
houseId: '',
|
||
encounterStatus: '',
|
||
bedStatus: '',
|
||
};
|
||
bedStatusFilter.value = '';
|
||
getList();
|
||
}
|
||
|
||
function changeWardLocationId(id) {
|
||
let params = {
|
||
locationId: id,
|
||
locationForm: 10,
|
||
};
|
||
queryParams.value.houseId = '';
|
||
childLocationList(params).then((res) => {
|
||
wardLocationList.value = res;
|
||
});
|
||
handleQuery();
|
||
}
|
||
|
||
// 获新入院患者列表
|
||
function getPatientList() {
|
||
// 为患者列表查询创建一个新的参数对象,不包含bedStatus
|
||
const patientQueryParams = {
|
||
...queryParams.value,
|
||
bedStatus: undefined, // 移除bedStatus,确保不影响患者列表查询
|
||
};
|
||
|
||
getPendingInfo(patientQueryParams).then((res) => {
|
||
loading.value = false;
|
||
// 为每个患者项初始化 active 属性
|
||
patientList.value = res.data.records.map((item) => ({
|
||
...item,
|
||
active: false,
|
||
}));
|
||
total.value = res.data.total;
|
||
});
|
||
}
|
||
// 选中患者
|
||
const selectPatient = ref(null);
|
||
function handleCardClick(item, index) {
|
||
// 清除所有项的激活状态
|
||
patientList.value.forEach((patient) => {
|
||
patient.active = false;
|
||
});
|
||
// 设置当前项为激活状态
|
||
item.active = true;
|
||
console.log(item);
|
||
selectPatient.value = item;
|
||
getRollInfoPageList();
|
||
}
|
||
function handleChageInstanceId(value) {
|
||
form.unit = feeItemOptions.value.find(
|
||
(item) => item.instanceId === value
|
||
).permittedUnitCode_dictText;
|
||
}
|
||
function handleClose() {
|
||
dialogVisible.value = false;
|
||
// 重置表单
|
||
form.name = '';
|
||
form.unit = '';
|
||
form.quantity = 1;
|
||
formRef.value?.resetFields();
|
||
}
|
||
// 获取滚费信息列表
|
||
const rollInfoPageList = ref([]);
|
||
function getRollInfoPageList() {
|
||
const encounterId = selectPatient.value.encounterId;
|
||
loading.value = true;
|
||
getRollInfoPage(encounterId).then((res) => {
|
||
rollInfoPageList.value = res.data;
|
||
loading.value = false;
|
||
});
|
||
}
|
||
function handleSubmit() {
|
||
formRef.value?.validate((valid) => {
|
||
if (valid) {
|
||
const param = {
|
||
encounterId: selectPatient.value.encounterId,
|
||
instanceId: form.instanceId,
|
||
quantity: form.quantity,
|
||
};
|
||
proxy
|
||
.$confirm('确认保存吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => {
|
||
saveInpatientRoll(param).then((res) => {
|
||
ElMessage.success('新增成功');
|
||
handleClose();
|
||
getRollInfoPageList();
|
||
});
|
||
})
|
||
.catch(() => {});
|
||
} else {
|
||
ElMessage.warning('请完善表单信息');
|
||
}
|
||
});
|
||
}
|
||
|
||
// 双击患者卡片事件
|
||
function handleCardDblClick(item) {
|
||
if (item.encounterStatus == 2) {
|
||
ElMessage({
|
||
message: '请分配病床!',
|
||
type: 'warning',
|
||
grouping: true,
|
||
showClose: true,
|
||
});
|
||
} else {
|
||
pendingInfo.value = {
|
||
...item,
|
||
entranceType: 1,
|
||
};
|
||
transferInDialogVisible.value = true;
|
||
}
|
||
}
|
||
|
||
function handleQuery() {
|
||
getList();
|
||
}
|
||
function handleAddFeeItemm() {
|
||
dialogVisible.value = true;
|
||
getInitDataSourceOptions();
|
||
}
|
||
|
||
function getPatientTagClass(item) {
|
||
if (item.encounterStatus == 2) {
|
||
return 'blue-tag';
|
||
} else if (item.encounterStatus == 5) {
|
||
return 'green-tag';
|
||
}
|
||
return '';
|
||
}
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.patient-card {
|
||
width: 100%;
|
||
overflow: hidden;
|
||
background-color: #fff;
|
||
border: 1px solid;
|
||
border-color: #eee;
|
||
border-radius: 4px;
|
||
box-shadow: 0 2px 2px 0 rgba(57.55, 69.04, 86.28, 20%);
|
||
margin-bottom: 10px;
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
|
||
&.actived {
|
||
background-color: rgb(7, 155, 140, 5%);
|
||
border-color: var(--el-color-primary);
|
||
}
|
||
|
||
&.dragging {
|
||
opacity: 0.5;
|
||
transform: rotate(5deg);
|
||
}
|
||
|
||
.doctor-parent-line {
|
||
margin: 0 16px;
|
||
border-bottom: 1px dashed #ddd;
|
||
}
|
||
|
||
.personal-info-container {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin: 8px 0;
|
||
padding: 0 16px;
|
||
|
||
.name-container {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 18px;
|
||
|
||
.name {
|
||
color: #333;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.age {
|
||
margin-left: 10px;
|
||
color: #666;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.main-info-container {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
height: 32px;
|
||
margin: 7px 0;
|
||
padding: 0 16px;
|
||
margin-right: 48px;
|
||
position: relative;
|
||
|
||
.patient-tag {
|
||
position: absolute;
|
||
top: -7px;
|
||
right: -48px;
|
||
font-size: 14px;
|
||
padding: 2px 8px;
|
||
border-radius: 4px;
|
||
|
||
&.blue-tag {
|
||
background-color: #1890ff;
|
||
color: white;
|
||
}
|
||
|
||
&.green-tag {
|
||
background-color: #52c41a;
|
||
color: white;
|
||
}
|
||
}
|
||
}
|
||
</style>
|