医生站-患者列表

This commit is contained in:
Zhang.YC
2025-03-28 17:47:45 +08:00
parent 485c649686
commit 06fd548447
19 changed files with 1896 additions and 20 deletions

View File

@@ -0,0 +1,20 @@
// 表格上滑滚轮滚动条横向滚动,在只有横向滚动条时使用
export default {
mounted: (el) => {
const container = el.querySelector('.el-scrollbar__wrap')
if (!container) return
const handleWheel = (e) => {
// 组织默认事件
e.preventDefault()
const delta = e.deltaY || e.detail || (-e.wheelDelta)
container.scrollLeft += delta * 0.6
}
container.addEventListener('wheel', handleWheel, { passive: false })
el._horizontalScrollCleanup = () => container.removeEventListener('wheel', handleWheel)
},
unmounted: (el) => {
el._horizontalScrollCleanup?.()
}
}

View File

@@ -1,9 +1,11 @@
import hasRole from './permission/hasRole'
import hasPermi from './permission/hasPermi'
import copyText from './common/copyText'
import horizontalScroll from './common/horizontalScroll'
export default function directive(app){
app.directive('hasRole', hasRole)
app.directive('hasPermi', hasPermi)
app.directive('copyText', copyText)
app.directive('horizontal-scroll', horizontalScroll)
}

View File

@@ -0,0 +1,81 @@
<template>
<div>
<el-table
ref="adviceBaseRef"
height="400"
:data="adviceBaseList"
row-key="patientId"
@cell-click="clickRow"
>
<el-table-column label="名称" align="center" prop="productName" />
<el-table-column
label="类型"
align="center"
prop="activityType_enumText"
/>
<el-table-column
label="包装单位"
align="center"
prop="unitCode_dictText"
/>
<el-table-column
label="最小单位"
align="center"
prop="minUnitCode_dictText"
/>
<el-table-column label="规格" align="center" prop="volume" />
<el-table-column label="用法" align="center" prop="methodCode_dictText" />
<el-table-column label="频次" align="center" prop="rateCode_dictText" />
<el-table-column label="单次剂量" align="center" prop="dose" />
<el-table-column
label="剂量单位"
align="center"
prop="doseUnitCode_dictText"
/>
<el-table-column label="生产厂家" align="center" prop="manufacturer" />
<el-table-column label="诊断名称" align="center" prop="name" />
</el-table>
</div>
</template>
<script setup>
import { getAdviceBaseInfo } from "./api";
const props = defineProps({
searchkey: {
type: String,
default: "",
},
});
const emit = defineEmits(["selsectAdviceBase"]);
const total = ref(0);
const queryParams = ref({});
const adviceBaseList = ref([]);
watch(
() => props.searchkey,
(newValue) => {
queryParams.value.searchKey = newValue;
getList();
},
{ immdiate: true }
);
getList();
function getList() {
getAdviceBaseInfo(queryParams.value).then((res) => {
adviceBaseList.value = res.data.records;
total.value = res.data.total;
});
}
function clickRow(row) {
emit("selsectAdviceBase", row);
}
</script>
<style scoped>
::v-deep .el-table__row:hover > td {
background-color: #cde5ff !important; /* 设置为透明或其他你想要的颜色 */
}
</style>

View File

@@ -0,0 +1,172 @@
import request from '@/utils/request'
// 病历相关接口
/**
* 获取患者列表
*/
export function getList(queryParams) {
return request({
url: '/doctor-station/main/patient-info',
method: 'get',
params: queryParams
})
}
/**
* 获取患者历史病历
*/
export function getEmrHistoryList(queryParams) {
return request({
url: '/doctor-station/emr/emr-page',
method: 'get',
params: queryParams
})
}
/**
* 获取病历模板列表
*/
export function getEmrTemplateList(queryParams) {
return request({
url: '/doctor-station/emr/emr-template-page',
method: 'get',
params: queryParams
})
}
/**
* 接诊
*/
export function receiveEncounter(encounterId) {
return request({
url: '/doctor-station/main/receive-encounter?encounterId=' + encounterId,
method: 'get',
})
}
/**
* 保存病历
*/
export function saveEmr(data) {
return request({
url: '/doctor-station/emr/emr',
method: 'post',
data: data
})
}
/**
* 删除病历模板
*/
export function deleteEmrTemplte(id){
return request({
url: '/doctor-station/emr/emr-template?id=' + id,
method: 'delete',
})
}
/**
* 获取病历详情
*/
export function getEmrDetail(encounterId){
return request({
url: '/doctor-station/emr/emr-detail?encounterId=' + encounterId,
method: 'get',
})
}
/**
* 保存病历模板
*/
export function saveEmrTemplate(data){
return request({
url: '/doctor-station/emr/emr-template',
method: 'post',
data: data
})
}
// 诊断相关接口
/**
* 保存诊断
*/
export function saveDiagnosis(data) {
return request({
url: '/doctor-station/diagnosis/save-doctor-diagnosis',
method: 'post',
data: data
})
}
/**
* 添加诊断绑定
*/
export function saveDiagnosisBind(data) {
return request({
url: '/doctor-station/diagnosis/diagnosis-belong-binding',
method: 'post',
data: data
})
}
/**
* 删除诊断绑定
*/
export function deleteDiagnosisBind(id) {
return request({
url: '/doctor-station/diagnosis/diagnosis-belong-binding?id=' + id,
method: 'delete',
})
}
/**
* 获取诊断定义列表
*/
export function getDiagnosisDefinitionList(queryParams) {
return request({
url: '/doctor-station/diagnosis/condition-definition-metadata',
method: 'get',
params: queryParams
})
}
/**
* 获取诊断分类数据,历史诊断/个人常用诊断/科室常用诊断
*/
export function getConditionDefinitionInfo(patientId) {
return request({
url: '/doctor-station/diagnosis/get-condition-definition-class?patientId=' + patientId,
method: 'get',
})
}
/**
* 获取诊断基础下拉数据
*/
export function diagnosisInit() {
return request({
url: '/doctor-station/diagnosis/init',
method: 'get',
})
}
// 处方相关接口
/**
* 获取药品列表
*/
export function getAdviceBaseInfo(queryParams) {
return request({
url: '/doctor-station/advice/advice-base-info',
method: 'get',
params: queryParams
})
}
/**
* 保存处方
*/
export function savePrescription(data) {
return request({
url: '/doctor-station/advice/save-advice',
method: 'post',
data: data
})
}

View File

@@ -0,0 +1,126 @@
<template>
<el-dialog
:title="title"
v-model="props.openDiagnosis"
width="600px"
append-to-body
destroy-on-close
@close="close"
>
<div>
<el-row :gutter="24" class="mb8">
<el-col :span="12">
<el-input
v-model="queryParams.searchKey"
placeholder="诊断名称/拼音码"
clearable
style="width: 100%; margin-bottom: 10px"
@keyup.enter="queryDiagnosisUse"
>
<template #append>
<el-button icon="Search" @click="queryDiagnosisUse" />
</template>
</el-input>
</el-col>
<!-- <el-col :span="12">
<span>使用范围</span>
<el-radio-group v-model="radio">
<el-radio :label="1" size="default">个人</el-radio>
<el-radio :label="2" size="default">科室</el-radio>
</el-radio-group>
</el-col> -->
</el-row>
<el-table
ref="diagnosisDefinitionRef"
:data="diagnosisDefinitionList"
row-key="patientId"
@cell-click="clickRow"
highlight-current-row
@selection-change="handleSelectionChange"
>
<el-table-column label="诊断名称" align="center" prop="name" />
<el-table-column label="医保编码" align="center" prop="ybNo" />
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submit"> </el-button>
<el-button @click="close"> </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { computed } from "vue";
import { getDiagnosisDefinitionList, saveDiagnosisBind } from "./api";
const radio = ref(1);
const props = defineProps({
openDiagnosis: {
type: Boolean,
default: false,
},
radio: {
type: String,
default: true,
},
});
const emit = defineEmits(["close"]);
const total = ref(0);
const queryParams = ref({
pageNum: 1,
pageSize: 10,
});
const diagnosisDefinitionList = ref([]);
const selectRow = ref({});
const title = computed(() => {
return props.radio == "个人" ? "个人常用诊断" : "科室常用诊断";
});
getList();
function getList() {
getDiagnosisDefinitionList(queryParams.value).then((res) => {
diagnosisDefinitionList.value = res.data.records;
total.value = res.data.total;
});
}
function submit() {
saveDiagnosisBind({
definitionId: selectRow.value.id,
definitionName: selectRow.value.name,
bindingEnum: props.radio == "个人" ? 1 : 2,
}).then((res) => {
if (res.code == 200) {
emit("close", "success");
}
});
}
function queryDiagnosisUse() {
getList();
}
function close() {
emit("close");
}
function clickRow(row) {
selectRow.value = row;
}
</script>
<style scoped>
::v-deep .pagination-container .el-pagination {
right: 20px !important;
}
</style>

View File

@@ -0,0 +1,56 @@
<template>
<div>
<el-table
ref="diagnosisDefinitionRef"
:data="diagnosisDefinitionList"
row-key="patientId"
@cell-click="clickRow"
@selection-change="handleSelectionChange"
>
<el-table-column label="诊断名称" align="center" prop="name" />
<el-table-column label="医保编码" align="center" prop="ybNo" />
</el-table>
</div>
</template>
<script setup>
import { getDiagnosisDefinitionList } from "./api";
const props = defineProps({
diagnosisSearchkey: {
type: String,
default: "",
},
});
const emit = defineEmits(["selsectDiagnosis"]);
const total = ref(0);
const queryParams = ref({});
const diagnosisDefinitionList = ref([]);
watch(
() => props.diagnosisSearchkey,
(newValue) => {
queryParams.value.searchKey = newValue;
getList();
},
{ immdiate: true }
);
getList();
function getList() {
getDiagnosisDefinitionList(queryParams.value).then((res) => {
diagnosisDefinitionList.value = res.data.records;
total.value = res.data.total;
});
}
function clickRow(row) {
emit("selsectDiagnosis", row);
}
</script>
<style scoped>
::v-deep .el-table__row:hover > td {
background-color: #cde5ff !important; /* 设置为透明或其他你想要的颜色 */
}
</style>

View File

@@ -0,0 +1,56 @@
<template>
<div>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd"
>新增
</el-button>
</el-col>
</el-row>
<el-table
ref="emrHistoryRef"
:data="emrHistory"
row-key="patientId"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="诊断" align="left" prop="name" />
<el-table-column label="时间" align="center" prop="typeEnum" />
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="handelEdit(scope.row)"
v-hasPermi="['system:dict:edit']"
>修改
</el-button>
</template>
</el-table-column>
</el-table>
<!-- <pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/> -->
</div>
</template>
<script>
import { getEmrHistoryList } from "./api";
const queryParams = ref({
pageNum: 1,
pageSize: 10,
});
const emrHistory = ref([]);
getList();
function getList() {
getEmrHistoryList(queryParams.value).then((res) => {
emrHistory.value = res.data.records;
});
}
</script>

View File

@@ -0,0 +1,68 @@
<template>
<div>
<el-table
ref="emrTemplateRef"
:data="emrTemplate"
row-key="id"
highlight-current-row
@cell-click="clickRow"
>
<el-table-column label="模板名称" align="center" prop="templateName" />
<el-table-column label="使用范围" align="center" prop="useScopeCode" />
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button link type="primary" @click.stop="handelDelete(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script setup>
import { getEmrTemplateList, deleteEmrTemplte } from "./api";
const queryParams = ref({});
const emrTemplate = ref([]);
const emrTemplateRef = ref();
const emits = defineEmits(["selectRow"]);
const { proxy } = getCurrentInstance();
const selectRow = ref({});
const props = defineProps({
open: {
type: Boolean,
required: true,
},
});
getList();
function getList() {
queryParams.value.useScopeCode = 1;
getEmrTemplateList(queryParams.value).then((res) => {
emrTemplate.value = res.data.records;
});
}
function clickRow(row) {
console.log(2123);
selectRow.value = JSON.parse(row.contextJson);
emits("selectRow", selectRow.value);
}
function handelDelete(row) {
deleteEmrTemplte(row.id.toString()).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess("删除成功");
getList();
}
});
}
</script>

View File

@@ -0,0 +1,144 @@
<template>
<el-input
v-model="queryParams.patientName"
placeholder="请输入患者名"
clearable
style="width: 100%; margin-bottom: 10px"
@keyup.enter="handleQuery"
>
<template #append>
<el-button icon="Search" @click="handleQuery" />
</template>
</el-input>
<div
style="justify-content: space-between; display: flex; margin-bottom: 10px"
>
<div>
<el-date-picker
v-model="queryParams.createTime"
placeholder="请选择挂号日期"
type="date"
size="default"
placement="bottom"
@change="handleQuery"
/>
</div>
<div>
<el-button type="primary" @click="handleReceive()">接诊</el-button>
<el-button type="primary" @click="handleDisabled(scope.row.id)">
暂离
</el-button>
</div>
</div>
<el-table
ref="patientTableRef"
:data="patient"
row-key="id"
@cell-click="clickRow"
v-loading="loading"
highlight-current-row
@selection-change="handleSelectionChange"
>
<el-table-column label="序号" type="index" width="50" />
<el-table-column label="患者" align="center" prop="name">
<template #default="scope">
<div
style="
display: flex;
justify-content: flex-start;
align-items: center;
"
>
<div style="padding-top: 5px">
<el-avatar
:size="40"
src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"
/>
</div>
<div style="font-size: 12px; text-align: left; padding-left: 20px">
<div>
<span style="margin-right: 10px">{{
scope.row.patientName
}}</span>
<span style="margin-right: 10px">年龄{{ scope.row.age }}</span>
<span>性别{{ scope.row.genderEnum_enumText }}</span>
</div>
<div>
<span>挂号时间{{ "2025-03-19 15:30:30" }}</span>
</div>
</div>
</div>
</template>
</el-table-column>
</el-table>
<!-- <pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getPatientList"
/> -->
</template>
<script setup>
import { getList, receiveEncounter } from "./api";
const queryParams = ref({
pageNum: 1,
pageSize: 10,
});
const patient = ref([]);
const loading = ref(false);
const patientTableRef = ref();
const total = ref(0);
const emits = defineEmits(["cellClick", "toCurrent"]);
const props = defineProps({
status: {
type: Number,
required: true,
},
});
const encounterId = ref();
getPatientList();
function getPatientList() {
queryParams.value.statusEnum = props.status;
loading.value = true;
console.log(queryParams.value.statusEnum);
getList(queryParams.value).then((res) => {
patient.value = res.data.records;
total.value = res.data.total;
loading.value = false;
});
}
function clickRow(row, column) {
encounterId.value = row.encounterId;
emits("cellClick", row);
}
/**
* 接诊并跳到现诊tab页
*/
function handleReceive() {
receiveEncounter(encounterId.value).then(() => {
emits("toCurrent");
});
}
function handleQuery() {
// 清空表格选中状态
patientTableRef.value.setCurrentRow(null);
getPatientList();
}
function handleSelectionChange() {}
</script>
<style scoped>
.custom-date-picker.el-picker__popper {
width: 285px !important;
}
.el-table__body tr.current-row > td.el-table__cell {
background-color: #cde5ff;
}
</style>

View File

@@ -0,0 +1,273 @@
<template>
<div style="width: 1250px">
<el-button type="primary" plain @click="handleAddPrescription()">
新增处方
</el-button>
<el-button type="primary" plain @click="handleSave()"> 发送处方 </el-button>
<el-table
v-horizontal-scroll
ref="prescriptionRef"
:data="prescriptionList"
row-key="patientId"
border
@cell-click="clickRow"
@selection-change="handleSelectionChange"
>
<el-table-column label="组号" align="center" prop="name">
<template #default="scope">
<el-input v-model="scope.row.name" placeholder="" />
</template>
</el-table-column>
<el-table-column
label="名称"
align="center"
prop="productName"
width="200"
>
<template #default="scope">
<el-popover
:popper-style="{ padding: '0' }"
placement="bottom-start"
:visible="scope.row.showPopover"
trigger="manual"
:width="1200"
>
<advicebaselist
:searchkey="searchkey"
@selsectAdviceBase="selsectAdviceBase"
/>
<template #reference>
<el-input
v-model="scope.row.productName"
placeholder=""
@input="handleChange"
@focus="handleFocus(scope.row, scope.$index)"
@blur="handleBlur(scope.row)"
/>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="批次号"
align="center"
prop="lotNumber"
width="180"
>
<template #default="scope">
<el-select v-model="scope.row.lotNumber" placeholder=" ">
<el-option
v-for="item in scope.row.stockList"
:key="item.lotNumber"
:label="
item.lotNumber +
' ' +
item.locationName +
' 库存:' +
item.baseQuantity +
item.baseUnitCode +
' 单价:' +
item.price +
'/' +
item.unitCode
"
:value="item.lotNumber"
@click="handleNumberClick(item, scope.$index)"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="规格" align="center" prop="volume" width="180" />
<el-table-column label="单价" align="center" prop="" />
<el-table-column label="单次计量" align="center" prop="dose">
<template #default="scope">
<el-input v-model="scope.row.name" placeholder="" />
</template>
</el-table-column>
<el-table-column
label="单位"
align="center"
prop="doseUnitCode_dictText"
width="90"
>
<template #default="scope">
<el-select v-model="scope.row.name" placeholder=" " >
<el-option
v-for="dict in unit_code"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column
label="用法"
align="center"
prop="methodCode_dictText"
width="130"
>
<template #default="scope">
<el-select v-model="scope.row.name" placeholder=" " clearable>
<el-option
v-for="dict in method_code"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="组套" align="center" prop="" />
<el-table-column
label="频次"
align="center"
prop="rateCode_dictText"
width="110"
>
<template #default="scope">
<el-select v-model="scope.row.name" placeholder="">
<el-option
v-for="dict in rate_code"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="滴速" align="center" prop="" />
<el-table-column label="用药天数" align="center" prop="">
<template #default="scope">
<el-input v-model="scope.row.name" placeholder="" />
</template>
</el-table-column>
<el-table-column label="药品总量" align="center" prop="">
<template #default="scope">
<el-input v-model="scope.row.name" placeholder="" />
</template>
</el-table-column>
<el-table-column label="单位" align="center" prop="" />
<el-table-column label="金额" align="center" prop="" />
<el-table-column label="皮试" align="center" prop="">
<template #default="scope">
<el-select v-model="scope.row.name" placeholder="" />
</template>
</el-table-column>
<el-table-column label="留观" align="center" prop="">
<template #default="scope">
<el-select v-model="scope.row.name" placeholder="" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right">
<template #default="scope">
<el-button link type="primary" @click="handleDelete(scope.$index)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup>
import { getDiagnosisDefinitionList, savePrescription } from "./api";
import advicebaselist from "./advicebaselist";
import { getCurrentInstance } from "vue";
const emit = defineEmits(["selsectDiagnosis"]);
const total = ref(0);
const queryParams = ref({});
const prescriptionList = ref([]);
const searchkey = ref("");
const rowIndex = ref(-1);
const props = defineProps({
patientInfo: {
type: Object,
required: true,
},
});
const prescriptionRef = ref();
const stockList = ref([]);
const { proxy } = getCurrentInstance();
const { method_code, unit_code, rate_code } = proxy.useDict(
"method_code",
"unit_code",
"rate_code"
);
getList();
function getList() {
getDiagnosisDefinitionList(queryParams.value).then((res) => {
// prescriptionList.value = res.data.records;
total.value = res.data.total;
});
}
function handleAddPrescription() {
prescriptionList.value.push({ showPopover: false });
}
/**
* 点击行赋值
*/
function clickRow(row) {
emit("selsectDiagnosis", row);
}
function handleFocus(row, index) {
rowIndex.value = index;
row.showPopover = true;
}
function handleBlur(row) {
row.showPopover = false;
}
function handleChange(value) {
searchkey.value = value;
}
/**
* 选择药品回调
*/
function selsectAdviceBase(row) {
prescriptionList.value[rowIndex.value] = JSON.parse(JSON.stringify(row));
// 库存列表 + 价格列表拼成批次号的下拉框
prescriptionList.value[rowIndex.value].stockList = row.inventoryList.map(
(item, index) => {
return { ...item, ...row.priceList[index] };
}
);
}
function handleDelete(index) {
prescriptionList.value.splice(index, 1);
}
function handleNumberClick(value, index) {
console.log(value);
prescriptionList.value[index];
}
/**
* 保存处方
*/
function handleSave() {
prescriptionList.value.forEach((item) => {
item.patientId = props.patientInfo.patientId;
item.encounterId = props.patientInfo.encounterId;
});
savePrescription({ adviceSaveList: prescriptionList.value }).then((res) => {
if (res.code === 200) {
proxy.$modal.msgSuccess("保存成功");
}
});
}
</script>
<style scoped>
::v-deep .el-table__row:hover > td {
background-color: #cde5ff !important; /* 设置为透明或其他你想要的颜色 */
}
</style>

View File

@@ -0,0 +1,818 @@
<template>
<div
style="
display: flex;
justify-content: flex-start;
align-items: flex-start;
height: 85vh;
width: 100%;
"
>
<el-tabs
type="border-card"
v-model="activeTab"
style="width: 30%; height: 100%; margin: 20px 10px 0px 20px"
>
<el-tab-pane label="待诊" name="wait">
<patientlist
@cellClick="cellClick"
@toCurrent="toCurrent"
:status="1"
/>
</el-tab-pane>
<el-tab-pane label="现诊" name="current">
<patientlist
@cellClick="cellClick"
@toCurrent="toCurrent"
:status="2"
/>
</el-tab-pane>
<el-tab-pane label="完诊" name="finish">
<patientlist
@cellClick="cellClick"
@toCurrent="toCurrent"
:status="2"
/>
</el-tab-pane>
<el-tab-pane label="暂离" name="leave">
<patientlist
@cellClick="cellClick"
@toCurrent="toCurrent"
:status="2"
/>
</el-tab-pane>
</el-tabs>
<el-tabs
type="border-card"
addable
style="width: 100%; height: 100%; margin: 20px 10px 0px 0px"
>
<el-tab-pane label="病历" v-loading="emrLoading">
<div style="margin-bottom: 15px; padding-left: 40px">
<el-row :gutter="24">
<el-col :span="12">
<el-descriptions>
<el-descriptions-item label="门诊号"
>1234567890</el-descriptions-item
>
<el-descriptions-item label="就诊科室"
>内科</el-descriptions-item
>
<el-descriptions-item label="支付类型"
>全自费</el-descriptions-item
>
</el-descriptions>
</el-col>
<el-col :span="12">
<el-button
type="primary"
@click="addEmr()"
style="margin-left: 20px"
:disabled="buttonDisabled"
>保存病历</el-button
>
<el-button
type="primary"
@click="handleEmrTemplate()"
style="margin-left: 20px"
:disabled="buttonDisabled"
>病历模板</el-button
>
<el-button
type="primary"
@click="handleSaveTemplate()"
style="margin-left: 20px"
:disabled="buttonDisabled"
>另存模板</el-button
>
<el-button
type="primary"
@click="handleEmrHistory()"
style="margin-left: 20px"
:disabled="buttonDisabled"
>历史病历</el-button
>
<el-button
type="primary"
@click="handleReceive()"
style="margin-left: 20px"
:disabled="buttonDisabled"
>打印病历</el-button
>
</el-col>
</el-row>
</div>
<el-form ref="emrRef" :model="form" :rules="rules" label-width="80px">
<el-row :gutter="24">
<el-col :span="6">
<el-form-item label="身高" prop="height" style="width: 100%">
<el-input
placeholder=""
v-model="form.height"
class="input-with-bottom-border"
>
<template #suffix>cm</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="体重" prop="weight" style="width: 100%">
<el-input
placeholder=""
v-model="form.weight"
class="input-with-bottom-border"
>
<template #suffix>kg</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="体温" prop="temperature" style="width: 100%">
<el-input
placeholder=""
v-model="form.temperature"
class="input-with-bottom-border"
>
<template #suffix></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="脉搏" prop="pulse" style="width: 100%">
<el-input
placeholder=""
v-model="form.pulse"
class="input-with-bottom-border"
>
<template #suffix>/</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<!-- <el-col :span="6">
<el-form-item
label="血糖"
prop="chiefComplaint"
style="width: 100%"
>
<el-input placeholder="" class="input-with-bottom-border">
<template #suffix></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="血糖"
prop="chiefComplaint"
style="width: 100%"
>
<el-input placeholder="" class="input-with-bottom-border">
<template #suffix>mmol/L</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="收缩压"
prop="chiefComplaint"
style="width: 100%"
>
<el-input placeholder="" class="input-with-bottom-border">
<template #suffix>mmHg</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="舒张压"
prop="chiefComplaint"
style="width: 100%"
>
<el-input placeholder="" class="input-with-bottom-border">
<template #suffix>mmHg</template>
</el-input>
</el-form-item>
</el-col> -->
</el-row>
<el-row :gutter="24">
<el-col :span="18">
<el-form-item label="主诉" prop="chiefComplaint">
<el-input
v-model="form.chiefComplaint"
type="textarea"
:rows="1"
placeholder=""
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="发病日期" prop="onsetDate">
<el-date-picker
v-model="form.onsetDate"
type="date"
size="default"
style="width: 100% !important"
placement="bottom"
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="现病史" prop="currentIllnessHistory">
<el-input
v-model="form.currentIllnessHistory"
type="textarea"
:rows="2"
placeholder=""
/>
</el-form-item>
<el-form-item label="既往史" prop="pastMedicalHistory">
<el-input
v-model="form.pastMedicalHistory"
type="textarea"
:rows="2"
placeholder=""
/>
</el-form-item>
<el-form-item label="月经史" prop="menstrualHistory">
<el-input
v-model="form.menstrualHistory"
type="textarea"
:rows="2"
placeholder=""
/>
</el-form-item>
<el-form-item label="过敏史" prop="allergyHistory">
<el-input
v-model="form.allergyHistory"
type="textarea"
:rows="2"
placeholder=""
/>
</el-form-item>
<el-form-item label="查体" prop="physicalExamination">
<el-input
v-model="form.physicalExamination"
type="textarea"
:rows="2"
placeholder=""
/>
</el-form-item>
<el-form-item label="处理" prop="treatment">
<el-input
v-model="form.treatment"
type="textarea"
:rows="2"
placeholder=""
/>
</el-form-item>
<el-form-item label="辅助检查" prop="auxiliaryExamination">
<el-input
v-model="form.auxiliaryExamination"
type="textarea"
:rows="2"
placeholder=""
/>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="诊断" v-loading="emrLoading">
<el-row :gutter="24">
<el-col :span="4" :xs="24">
<el-input
v-model="form.phone"
placeholder="诊断名称"
clearable
style="width: 100%; margin-bottom: 10px"
@keyup.enter="queryDiagnosisUse"
>
<template #append>
<el-button icon="Search" @click="queryDiagnosisUse" />
</template>
</el-input>
<el-tree
:data="tree"
:props="{ label: 'name', children: 'children' }"
highlight-current
default-expand-all
@node-click="handleNodeClick"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<span>{{ node.label }}</span>
<span class="tree-node-actions">
<el-button
style="color: #000000"
v-if="
node.level === 1 &&
data.name != '常用' &&
data.name != '历史'
"
type="text"
size="mini"
@click.stop="addChild(data)"
>
<el-icon><Plus /></el-icon>
</el-button>
<el-button
style="color: #000000"
v-if="
node.level === 2 &&
node.parent.data.name != '常用' &&
node.parent.data.name != '历史'
"
type="text"
size="mini"
@click.stop="deleteChild(data)"
>
<el-icon><Minus /></el-icon>
</el-button>
</span>
</span>
</template>
</el-tree>
</el-col>
<el-col :span="20" :xs="24">
<div style="margin-bottom: 10px">
<el-button type="primary" plain @click="handleAddDiagnosis()">
新增诊断
</el-button>
<el-button type="primary" plain @click="handleSaveDiagnosis()">
保存诊断
</el-button>
</div>
<el-table
ref="diagnosisTableRef"
:data="diagnosisList"
@cell-click="clickRow"
@selection-change="handleSelectionChange"
height="650"
>
<el-table-column label="序号" type="index" width="50" />
<el-table-column label="诊断名称" align="center" prop="name">
<template #default="scope">
<el-popover
:popper-style="{ padding: '0' }"
placement="bottom-start"
:visible="scope.row.showPopover"
trigger="manual"
:width="500"
>
<diagnosislist
:diagnosisSearchkey="diagnosisSearchkey"
@selsectDiagnosis="handleSelsectDiagnosis"
/>
<template #reference>
<el-input
v-model="scope.row.name"
placeholder="请选择诊断"
@input="handleChange"
@focus="handleFocus(scope.row, scope.$index)"
@blur="handleBlur(scope.row)"
/>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column label="医保码" align="center" prop="ybNo" />
<el-table-column
label="诊断类型"
align="center"
prop="maindiseFlag"
>
<template #default="scope">
<el-checkbox
label="主诊断"
v-model:value="scope.row.maindiseFlag"
border
size="small"
@change="(value) => handleMaindise(value, scope.$index)"
/>
<el-select
v-model="scope.row.verificationStatusEnum"
placeholder=" "
style="width: 40%; padding-bottom: 5px; padding-left: 10px"
size="small"
@change="handle"
>
<el-option
v-for="item in diagnosisOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="handleDeleteDiagnosis(scope.$index)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="处方" v-loading="emrLoading">
<prescriptionlist :patientInfo="patientInfo" />
</el-tab-pane>
<template #addIcon>
<!-- 特殊操作展示用户信息 -->
<el-button class="plain-button">
{{
patientInfo
? patientInfo.patientName +
" / " +
patientInfo.age +
" / " +
patientInfo.genderEnum_enumText
: ""
}}
</el-button>
</template>
</el-tabs>
<el-dialog
:title="emrTitle"
v-model="openEmrTemplate"
width="600px"
append-to-body
destroy-on-close
>
<emrtemplate
v-if="showDialog == 'emrTemplate'"
@selectRow="templateSelect"
/>
<emrhistory v-if="showDialog == 'emrHistory'" />
<div v-if="showDialog == 'saveTemplate'">
<span>模板名称:<el-input v-model="templateName" /></span>
<el-radio-group v-model="radio">
<el-radio :label="1">个人</el-radio>
<el-radio :label="2">科室</el-radio>
<el-radio :label="3">全院</el-radio>
</el-radio-group>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submit">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
<diagnosisdialog
:openDiagnosis="openDiagnosis"
@close="closeDiagnosisDialog"
:radio="orgOrUser"
/>
</div>
</template>
<script setup name="doctorstation">
import patientlist from "./components/patientlist.vue";
import {
saveEmr,
getEmrDetail,
saveEmrTemplate,
getConditionDefinitionInfo,
saveDiagnosis,
diagnosisInit,
deleteDiagnosisBind,
} from "./components/api";
import prescriptionlist from "./components/prescriptionlist.vue";
import emrtemplate from "./components/emrtemplate.vue";
import emrhistory from "./components/emrhistory.vue";
import diagnosisdialog from "./components/diagnosisdialog.vue";
import diagnosislist from "./components/diagnosislist.vue";
import { computed, ref } from "vue";
import { data } from "province-city-china/data";
const activeTab = ref("wait");
const form = ref({});
const patientInfo = ref();
const { proxy } = getCurrentInstance();
const openEmrTemplate = ref(false);
const templateName = ref("");
const showDialog = ref("");
const emrTitle = ref("");
const emrLoading = ref(false);
const diagnosisList = ref([]);
const openDiagnosis = ref(false);
const tree = ref([]);
const buttonDisabled = computed(() => {
return !patientInfo.value;
});
const rowIndex = ref(-1);
const diagnosisSearchkey = ref("");
// const emrContext = ref({});
const radio = ref(1);
const rules = ref({
chiefComplaint: [{ required: true, message: "请输入主诉", trigger: "blur" }],
});
const diagnosisOptions = ref([]);
const orgOrUser = ref();
/**
* 患者列表行点击回调
* @param column 患者信息
*/
function cellClick(column) {
patientInfo.value = column;
console.log(column);
if (activeTab.value == "wait") {
form.value = {};
} else {
emrLoading.value = true;
getEmrDetail(column.encounterId).then((res) => {
if (res.data) {
form.value = JSON.parse(res.data.contextJson);
} else {
form.value = {};
}
setTimeout(() => {
emrLoading.value = false;
}, 100);
});
getTree();
}
}
init();
function init() {
diagnosisInit().then((res) => {
if (res.code == 200) {
diagnosisOptions.value = res.data.verificationStatusOptions;
}
});
}
function handleMaindise(value, index) {
diagnosisList.value[index].maindiseFlag = value ? 1 : 0;
console.log(diagnosisList.value);
}
/**
* 保存病历
*/
function addEmr() {
saveEmr({
patientId: patientInfo.value.patientId,
encounterId: patientInfo.value.encounterId,
contextJson: form.value,
}).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess("保存成功");
}
});
}
function handleChange(value) {
diagnosisSearchkey.value = value;
}
function handleNodeClick(data) {
diagnosisList.value.push({
ybNo: data.ybNo,
name: data.name,
verificationStatusEnum: 4,
});
}
/**
* 病历模板
*/
function handleEmrTemplate() {
emrTitle.value = "病历模板";
showDialog.value = "emrTemplate";
openEmrTemplate.value = true;
}
/**
* 选择病历模板
*/
function templateSelect(row) {
form.value = row;
}
/**
* 添加子节点
*/
function addChild(data) {
orgOrUser.value = data.name;
openDiagnosis.value = true;
}
/**
* 删除子节点
*/
function deleteChild(data) {
console.log(data);
deleteDiagnosisBind(data.id).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess("删除成功");
getTree();
}
});
}
function cancel() {
openEmrTemplate.value = false;
openDiagnosis.value = false;
}
/**
* 历史病历
*/
function handleEmrHistory() {
emrTitle.value = "历史病历";
showDialog.value = "emrHistory";
openEmrTemplate.value = true;
}
/**
* 保存病历模板
*/
function handleSaveTemplate() {
emrTitle.value = "保存模板";
showDialog.value = "saveTemplate";
openEmrTemplate.value = true;
}
/**
* 弹窗确认操作,包括保存病历模板/选择病历模板/选择历史病历
*/
function submit() {
switch (showDialog.value) {
case "saveTemplate":
saveEmrTemplate({
templateName: templateName.value,
useScopeCode: radio.value,
contextJson: form.value,
}).then((res) => {
if (res.code == 200) {
openEmrTemplate.value = false;
proxy.$modal.msgSuccess("保存成功");
}
});
break;
case "emrTemplate":
openEmrTemplate.value = false;
break;
case "emrHistory":
break;
}
}
/**
* 获取诊断树列表
*/
function getTree() {
getConditionDefinitionInfo(
patientInfo.value ? patientInfo.value.patientId : ""
).then((res) => {
if (res.code == 200) {
// 手动构造树列表
tree.value[0] = {
name: "历史",
children: res.data.patientHistoryList,
};
tree.value[1] = {
name: "常用",
children: res.data.doctorCommonUseList,
};
tree.value[2] = {
name: "个人",
children: res.data.userPersonalList,
};
tree.value[3] = {
name: "科室",
children: res.data.organizationList,
};
console.log(tree.value);
}
});
}
/**
* 添加诊断
*/
function handleAddDiagnosis() {
diagnosisList.value.push({
showPopover: false,
name: undefined,
verificationStatusEnum: 4,
});
}
/**
* 删除诊断
*/
function handleDeleteDiagnosis(index) {
diagnosisList.value.splice(index, 1);
}
/**
* 保存诊断
*/
function handleSaveDiagnosis() {
if (diagnosisList.value.length == 0) {
proxy.$modal.msgWarning("诊断不能为空");
} else if (1 != 1) {
proxy.$modal.msgWarning("至少添加条主诊断");
} else {
saveDiagnosis({
patientId: patientInfo.value.patientId,
encounterId: patientInfo.value.encounterId,
diagnosisChildList: diagnosisList.value,
}).then((res) => {
if (res.code == 200) {
getTree();
proxy.$modal.msgSuccess("保存成功");
}
});
}
}
/**
* 关闭诊断弹窗
*/
function closeDiagnosisDialog(str) {
if (str === "success") {
proxy.$modal.msgSuccess("操作成功");
}
openDiagnosis.value = false;
getTree();
}
function queryDiagnosisUse(value) {}
/**
* 选择诊断并赋值到列表
*/
function handleSelsectDiagnosis(row) {
diagnosisList.value[rowIndex.value].ybNo = row.ybNo;
diagnosisList.value[rowIndex.value].name = row.name;
}
/**获取焦点时 打开列表 */
function handleFocus(row, index) {
rowIndex.value = index;
row.showPopover = true;
}
/**失去焦点时 关闭列表 */
function handleBlur(row) {
row.showPopover = false;
}
function toCurrent() {
activeTab.value = "current";
}
</script>
<style lang="scss" scoped>
// .el-tabs--card {
// height: calc(100vh - 100px);
// }
// .el-tab-pane {
// height: calc(100vh - 200px);
// overflow-y: auto;
// }
/* ::v-deep .el-tabs__item.is-top:last-child {
float: right;
} */
::v-deep .el-tabs__new-tab {
/* position: relative;
right: 10%; */
border: none;
}
.plain-button {
margin-right: 300px;
border: none;
background-color: transparent;
color: #909399;
font-size: 16px;
padding: 0;
cursor: pointer;
}
.el-popover.el-popper {
padding: 0px !important;
}
::v-deep .el-table__row:hover > td {
background-color: #cde5ff !important; /* 设置为透明或其他你想要的颜色 */
}
.custom-tree-node {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.tree-node-actions {
display: flex;
align-items: center;
}
</style>