@@ -1,318 +1,87 @@
|
||||
<!--
|
||||
* @Author: sjjh
|
||||
* @Date: 2025-09-05 21:16:06
|
||||
* @Description: 输血申请详情
|
||||
-->
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<div class="report-section">
|
||||
<div class="report-title">
|
||||
<span>输血申请</span>
|
||||
<el-icon
|
||||
class="report-refresh-icon"
|
||||
:class="{ 'is-loading': loading }"
|
||||
@click="handleRefresh"
|
||||
>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="report-table-wrapper">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
border
|
||||
size="small"
|
||||
height="100%"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
||||
<el-table-column prop="name" label="申请单名称" width="140" />
|
||||
<el-table-column prop="createTime" label="创建时间" width="160" />
|
||||
<el-table-column prop="prescriptionNo" label="处方号" width="140" />
|
||||
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
||||
<el-table-column label="操作" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="applicationShow-container">
|
||||
<div class="applicationShow-container-header">
|
||||
<el-button @click="getInfo">刷新</el-button>
|
||||
</div>
|
||||
<div class="applicationShow-container-content">
|
||||
<el-descriptions title="输血申请详情" :column="2">
|
||||
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
|
||||
<el-descriptions-item label="患者姓名">{{ patientInfoValue?.patientName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="患者性别">{{ patientInfoValue?.patientSex || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="患者年龄">{{ patientInfoValue?.patientAge || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="患者手机号">{{ patientInfoValue?.patientPhone || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="患者身份证号">{{ patientInfoValue?.patientIdCard || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="患者地址">{{ patientInfoValue?.patientAddress || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div class="applicationShow-container-table">
|
||||
<el-table :data="dataList">
|
||||
<el-table-column label="医嘱名称" prop="adviceName" />
|
||||
<el-table-column label="输血数量" prop="adviceDefinitionId" />
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 详情弹窗 -->
|
||||
<el-dialog
|
||||
v-model="detailDialogVisible"
|
||||
title="输血申请详情"
|
||||
width="800px"
|
||||
destroy-on-close
|
||||
top="5vh"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div v-if="currentDetail" class="applicationShow-container">
|
||||
<div class="applicationShow-container-content">
|
||||
<el-descriptions title="基本信息" :column="2">
|
||||
<el-descriptions-item label="患者姓名">{{
|
||||
currentDetail.patientName || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单名称">{{
|
||||
currentDetail.name || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{
|
||||
currentDetail.createTime || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="处方号">{{
|
||||
currentDetail.prescriptionNo || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请者">{{
|
||||
currentDetail.requesterId_dictText || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="就诊ID">{{
|
||||
currentDetail.encounterId || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单ID">{{
|
||||
currentDetail.requestFormId || '-'
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div v-if="descJsonData && hasMatchedFields" class="applicationShow-container-content">
|
||||
<el-descriptions title="申请单描述" :column="2">
|
||||
<template v-for="(value, key) in descJsonData" :key="key">
|
||||
<el-descriptions-item v-if="isFieldMatched(key)" :label="getFieldLabel(key)">
|
||||
{{ value || '-' }}
|
||||
</el-descriptions-item>
|
||||
</template>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="currentDetail.requestFormDetailList && currentDetail.requestFormDetailList.length"
|
||||
class="applicationShow-container-table"
|
||||
>
|
||||
<el-table :data="currentDetail.requestFormDetailList" border>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="adviceName" label="医嘱名称" />
|
||||
<el-table-column prop="quantity" label="数量" width="80" align="center" />
|
||||
<el-table-column prop="unitCode_dictText" label="单位" width="100" />
|
||||
<el-table-column prop="totalPrice" label="总价" width="100" align="right" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getCurrentInstance, ref, watch, computed } from 'vue';
|
||||
import { Refresh } from '@element-plus/icons-vue';
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
import { getCurrentInstance, onBeforeMount, onMounted, reactive, ref, computed } from 'vue'
|
||||
import { getBloodTransfusion } from './api';
|
||||
import { getOrgList } from '../../../../doctorstation/components/api.js';
|
||||
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
const { proxy } = getCurrentInstance();
|
||||
const emits = defineEmits([])
|
||||
const props = defineProps({
|
||||
|
||||
const tableData = ref([]);
|
||||
const loading = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
})
|
||||
const state = reactive({
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!patientInfo.value?.encounterId) {
|
||||
tableData.value = [];
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getBloodTransfusion({ encounterId: patientInfo.value.encounterId });
|
||||
if (res.code === 200 && res.data) {
|
||||
const raw = res.data?.records || res.data;
|
||||
const list = Array.isArray(raw) ? raw : [raw];
|
||||
tableData.value = list.filter(Boolean);
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
} catch (e) {
|
||||
proxy.$modal?.msgError?.(e.message || '查询输血申请失败');
|
||||
tableData.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
const handleRefresh = async () => {
|
||||
if (loading.value || !patientInfo.value?.encounterId) return;
|
||||
await fetchData();
|
||||
};
|
||||
|
||||
const labelMap = {
|
||||
categoryType: '项目类别',
|
||||
targetDepartment: '发往科室',
|
||||
symptom: '症状',
|
||||
sign: '体征',
|
||||
clinicalDiagnosis: '临床诊断',
|
||||
otherDiagnosis: '其他诊断',
|
||||
relatedResult: '相关结果',
|
||||
attention: '注意事项',
|
||||
};
|
||||
|
||||
const isFieldMatched = (key) => {
|
||||
return key in labelMap;
|
||||
};
|
||||
|
||||
const getFieldLabel = (key) => {
|
||||
return labelMap[key] || key;
|
||||
};
|
||||
|
||||
const hasMatchedFields = computed(() => {
|
||||
if (!descJsonData.value) return false;
|
||||
return Object.keys(descJsonData.value).some((key) => isFieldMatched(key));
|
||||
// 使用计算属性确保安全访问
|
||||
const patientInfoValue = computed(() => {
|
||||
return patientInfo.value || {};
|
||||
});
|
||||
|
||||
/** 查询科室 */
|
||||
const getLocationInfo = () => {
|
||||
getOrgList().then((res) => {
|
||||
orgOptions.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
const recursionFun = (targetDepartment) => {
|
||||
let name = '';
|
||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||
const obj = orgOptions.value[index];
|
||||
if (obj.id == targetDepartment) {
|
||||
name = obj.name;
|
||||
}
|
||||
const subObjArray = obj['children'];
|
||||
for (let index = 0; index < subObjArray.length; index++) {
|
||||
const item = subObjArray[index];
|
||||
if (item.id == targetDepartment) {
|
||||
name = item.name;
|
||||
const dataList = ref([])
|
||||
const getInfo = () => {
|
||||
if (patientInfo.value?.inHospitalOrgId) {
|
||||
getBloodTransfusion({
|
||||
encounterId: patientInfo.value.encounterId,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
dataList.value = res.data
|
||||
} else {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return name;
|
||||
};
|
||||
onBeforeMount(() => {
|
||||
|
||||
const handleViewDetail = (row) => {
|
||||
currentDetail.value = row;
|
||||
// 解析 descJson
|
||||
if (row.descJson) {
|
||||
try {
|
||||
// descJsonData.value = JSON.parse(row.descJson);
|
||||
const obj = JSON.parse(row.descJson);
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
descJsonData.value = obj;
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
descJsonData.value = null;
|
||||
}
|
||||
} else {
|
||||
descJsonData.value = null;
|
||||
}
|
||||
detailDialogVisible.value = true;
|
||||
};
|
||||
})
|
||||
onMounted(() => {
|
||||
getInfo()
|
||||
})
|
||||
defineExpose({ state })
|
||||
|
||||
watch(
|
||||
() => patientInfo.value?.encounterId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
fetchData();
|
||||
getLocationInfo();
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
refresh: fetchData,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 8px 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.report-section {
|
||||
background: #fff;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.report-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.report-table-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.report-refresh-icon {
|
||||
cursor: pointer;
|
||||
color: #909399;
|
||||
transition: color 0.2s;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.report-refresh-icon:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.report-refresh-icon.is-loading {
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.applicationShow-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 70vh;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
.applicationShow-container-content {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 0px;
|
||||
.applicationShow-container-header{
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap:8px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.applicationShow-container-table {
|
||||
flex-shrink: 0;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
.applicationShow-container-content{
|
||||
flex: 1;
|
||||
}
|
||||
.applicationShow-container-table{
|
||||
height: 400px;
|
||||
flex:auto
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -4,316 +4,42 @@
|
||||
* @Description: 检查申请详情
|
||||
-->
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<div class="report-section">
|
||||
<div class="report-title">
|
||||
<span>检查申请</span>
|
||||
<el-icon
|
||||
class="report-refresh-icon"
|
||||
:class="{ 'is-loading': loading }"
|
||||
@click="handleRefresh"
|
||||
>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="report-table-wrapper">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
border
|
||||
size="small"
|
||||
height="100%"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
||||
<el-table-column prop="name" label="申请单名称" width="140" />
|
||||
<el-table-column prop="createTime" label="创建时间" width="160" />
|
||||
<el-table-column prop="prescriptionNo" label="处方号" width="140" />
|
||||
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
||||
<el-table-column label="操作" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 详情弹窗 -->
|
||||
<el-dialog
|
||||
v-model="detailDialogVisible"
|
||||
title="检查申请详情"
|
||||
width="800px"
|
||||
destroy-on-close
|
||||
top="5vh"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div v-if="currentDetail" class="applicationShow-container">
|
||||
<div class="applicationShow-container-content">
|
||||
<el-descriptions title="基本信息" :column="2">
|
||||
<el-descriptions-item label="患者姓名">{{
|
||||
currentDetail.patientName || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单名称">{{
|
||||
currentDetail.name || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{
|
||||
currentDetail.createTime || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="处方号">{{
|
||||
currentDetail.prescriptionNo || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请者">{{
|
||||
currentDetail.requesterId_dictText || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="就诊ID">{{
|
||||
currentDetail.encounterId || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单ID">{{
|
||||
currentDetail.requestFormId || '-'
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div v-if="descJsonData && hasMatchedFields" class="applicationShow-container-content">
|
||||
<el-descriptions title="申请单描述" :column="2">
|
||||
<template v-for="(value, key) in descJsonData" :key="key">
|
||||
<el-descriptions-item v-if="isFieldMatched(key)" :label="getFieldLabel(key)">
|
||||
{{ value || '-' }}
|
||||
</el-descriptions-item>
|
||||
</template>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="currentDetail.requestFormDetailList && currentDetail.requestFormDetailList.length"
|
||||
class="applicationShow-container-table"
|
||||
>
|
||||
<el-table :data="currentDetail.requestFormDetailList" border>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="adviceName" label="医嘱名称" />
|
||||
<el-table-column prop="quantity" label="数量" width="80" align="center" />
|
||||
<el-table-column prop="unitCode_dictText" label="单位" width="100" />
|
||||
<el-table-column prop="totalPrice" label="总价" width="100" align="right" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<div class="container">
|
||||
<el-button @click="getInfo">查询</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getCurrentInstance, ref, watch, computed } from 'vue';
|
||||
import { Refresh } from '@element-plus/icons-vue';
|
||||
</template>
|
||||
<script setup >
|
||||
import { getCurrentInstance, onBeforeMount, onMounted, reactive } from 'vue'
|
||||
import { getCheck } from './api';
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
import { getCheck } from './api';
|
||||
import { getOrgList } from '../../../../doctorstation/components/api.js';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const tableData = ref([]);
|
||||
const loading = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!patientInfo.value?.encounterId) {
|
||||
tableData.value = [];
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getCheck({ encounterId: patientInfo.value.encounterId });
|
||||
if (res.code === 200 && res.data) {
|
||||
const raw = res.data?.records || res.data;
|
||||
const list = Array.isArray(raw) ? raw : [raw];
|
||||
tableData.value = list.filter(Boolean);
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
} catch (e) {
|
||||
proxy.$modal?.msgError?.(e.message || '查询检查申请失败');
|
||||
tableData.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRefresh = async () => {
|
||||
if (loading.value || !patientInfo.value?.encounterId) return;
|
||||
await fetchData();
|
||||
};
|
||||
|
||||
const labelMap = {
|
||||
categoryType: '项目类别',
|
||||
targetDepartment: '发往科室',
|
||||
symptom: '症状',
|
||||
sign: '体征',
|
||||
clinicalDiagnosis: '临床诊断',
|
||||
otherDiagnosis: '其他诊断',
|
||||
relatedResult: '相关结果',
|
||||
attention: '注意事项',
|
||||
};
|
||||
|
||||
const isFieldMatched = (key) => {
|
||||
return key in labelMap;
|
||||
};
|
||||
|
||||
const getFieldLabel = (key) => {
|
||||
return labelMap[key] || key;
|
||||
};
|
||||
|
||||
const hasMatchedFields = computed(() => {
|
||||
if (!descJsonData.value) return false;
|
||||
return Object.keys(descJsonData.value).some((key) => isFieldMatched(key));
|
||||
});
|
||||
|
||||
/** 查询科室 */
|
||||
const getLocationInfo = () => {
|
||||
getOrgList().then((res) => {
|
||||
orgOptions.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
const recursionFun = (targetDepartment) => {
|
||||
let name = '';
|
||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||
const obj = orgOptions.value[index];
|
||||
if (obj.id == targetDepartment) {
|
||||
name = obj.name;
|
||||
}
|
||||
const subObjArray = obj['children'];
|
||||
for (let index = 0; index < subObjArray.length; index++) {
|
||||
const item = subObjArray[index];
|
||||
if (item.id == targetDepartment) {
|
||||
name = item.name;
|
||||
const { proxy } = getCurrentInstance();
|
||||
const emits = defineEmits([])
|
||||
const props = defineProps({
|
||||
|
||||
})
|
||||
const state = reactive({
|
||||
|
||||
})
|
||||
const getInfo = () => {
|
||||
if (patientInfo.value?.inHospitalOrgId) {
|
||||
getCheck({
|
||||
encounterId: patientInfo.value.encounterId,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const handleViewDetail = (row) => {
|
||||
console.log('targetDepartment========>', JSON.stringify(row));
|
||||
|
||||
currentDetail.value = row;
|
||||
// 解析 descJson
|
||||
if (row.descJson) {
|
||||
try {
|
||||
const obj = JSON.parse(row.descJson);
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
descJsonData.value = obj;
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
descJsonData.value = null;
|
||||
}
|
||||
} else {
|
||||
descJsonData.value = null;
|
||||
}
|
||||
detailDialogVisible.value = true;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => patientInfo.value?.encounterId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
fetchData();
|
||||
getLocationInfo();
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
refresh: fetchData,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 8px 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.report-section {
|
||||
background: #fff;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.report-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.report-table-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.report-refresh-icon {
|
||||
cursor: pointer;
|
||||
color: #909399;
|
||||
transition: color 0.2s;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.report-refresh-icon:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.report-refresh-icon.is-loading {
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.applicationShow-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 70vh;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
.applicationShow-container-content {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.applicationShow-container-table {
|
||||
flex-shrink: 0;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
onBeforeMount(() => {
|
||||
|
||||
})
|
||||
onMounted(() => {
|
||||
getInfo()
|
||||
})
|
||||
defineExpose({ state })
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,238 +0,0 @@
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<div class="report-section">
|
||||
<div class="report-title">
|
||||
<span>检查报告</span>
|
||||
<el-icon
|
||||
class="report-refresh-icon"
|
||||
:class="{ 'is-loading': loadingCheck }"
|
||||
@click="handleRefreshCheck"
|
||||
>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="report-table-wrapper">
|
||||
<el-table
|
||||
v-loading="loadingCheck"
|
||||
:data="checkReportList"
|
||||
border
|
||||
size="small"
|
||||
height="100%"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="adviceName" label="报告名称" width="140" />
|
||||
<el-table-column prop="reportNo" label="报告号" width="140" />
|
||||
<el-table-column label="链接" min-width="140">
|
||||
<template #default="scope">
|
||||
<a
|
||||
v-if="scope.row.requestUrl"
|
||||
class="report-link"
|
||||
:href="scope.row.requestUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
查看报告
|
||||
</a>
|
||||
<span v-else class="report-link-disabled">暂无链接</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-section">
|
||||
<div class="report-title">
|
||||
<span>检验报告</span>
|
||||
<el-icon
|
||||
class="report-refresh-icon"
|
||||
:class="{ 'is-loading': loadingInspection }"
|
||||
@click="handleRefreshInspection"
|
||||
>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="report-table-wrapper">
|
||||
<el-table
|
||||
v-loading="loadingInspection"
|
||||
:data="inspectionReportList"
|
||||
border
|
||||
size="small"
|
||||
height="100%"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="adviceName" label="报告名称" width="140" />
|
||||
<el-table-column prop="reportNo" label="报告号" width="140" />
|
||||
<el-table-column label="链接" min-width="140">
|
||||
<template #default="scope">
|
||||
<a
|
||||
v-if="scope.row.requestUrl"
|
||||
class="report-link"
|
||||
:href="scope.row.requestUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
查看报告
|
||||
</a>
|
||||
<span v-else class="report-link-disabled">暂无链接</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getCurrentInstance, ref, watch } from 'vue';
|
||||
import { Refresh } from '@element-plus/icons-vue';
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
import { getProofResult, getTestResult } from './api';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const checkReportList = ref([]);
|
||||
const inspectionReportList = ref([]);
|
||||
const loadingCheck = ref(false);
|
||||
const loadingInspection = ref(false);
|
||||
|
||||
const fetchCheckReport = async () => {
|
||||
if (!patientInfo.value?.encounterId) return;
|
||||
const res = await getTestResult({ encounterId: patientInfo.value.encounterId });
|
||||
if (res.code === 200 && res.data) {
|
||||
const raw = res.data?.records || res.data;
|
||||
const list = Array.isArray(raw) ? raw : [raw];
|
||||
checkReportList.value = list.filter(Boolean).map((item) => ({
|
||||
reportNo: item.busNo,
|
||||
requestUrl: item.requestUrl,
|
||||
adviceName: item.adviceName,
|
||||
_raw: item,
|
||||
}));
|
||||
} else {
|
||||
checkReportList.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
const fetchInspectionReport = async () => {
|
||||
if (!patientInfo.value?.encounterId) return;
|
||||
const res = await getProofResult({ encounterId: patientInfo.value.encounterId });
|
||||
if (res.code === 200 && res.data) {
|
||||
const raw = res.data?.records || res.data;
|
||||
const list = Array.isArray(raw) ? raw : [raw];
|
||||
inspectionReportList.value = list.filter(Boolean).map((item) => ({
|
||||
reportNo: item.busNo,
|
||||
requestUrl: item.requestUrl,
|
||||
adviceName: item.adviceName,
|
||||
_raw: item,
|
||||
}));
|
||||
} else {
|
||||
inspectionReportList.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
const fetchAll = async () => {
|
||||
if (!patientInfo.value?.encounterId) {
|
||||
checkReportList.value = [];
|
||||
inspectionReportList.value = [];
|
||||
loadingCheck.value = false;
|
||||
loadingInspection.value = false;
|
||||
return;
|
||||
}
|
||||
loadingCheck.value = true;
|
||||
loadingInspection.value = true;
|
||||
try {
|
||||
await Promise.all([fetchCheckReport(), fetchInspectionReport()]);
|
||||
} catch (e) {
|
||||
proxy.$modal?.msgError?.(e.message || '查询报告失败');
|
||||
} finally {
|
||||
loadingCheck.value = false;
|
||||
loadingInspection.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRefreshCheck = async () => {
|
||||
if (loadingCheck.value || !patientInfo.value?.encounterId) return;
|
||||
loadingCheck.value = true;
|
||||
try {
|
||||
await fetchCheckReport();
|
||||
} finally {
|
||||
loadingCheck.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRefreshInspection = async () => {
|
||||
if (loadingInspection.value || !patientInfo.value?.encounterId) return;
|
||||
loadingInspection.value = true;
|
||||
try {
|
||||
await fetchInspectionReport();
|
||||
} finally {
|
||||
loadingInspection.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => patientInfo.value?.encounterId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
fetchAll();
|
||||
} else {
|
||||
checkReportList.value = [];
|
||||
inspectionReportList.value = [];
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 8px 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.report-section {
|
||||
background: #fff;
|
||||
flex: 1;
|
||||
max-height: 55%;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.report-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.report-table-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.report-refresh-icon {
|
||||
cursor: pointer;
|
||||
color: #909399;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.report-refresh-icon:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.report-link {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.report-link-disabled {
|
||||
color: #c0c4cc;
|
||||
}
|
||||
</style>
|
||||
@@ -4,315 +4,33 @@
|
||||
* @Description: 手术申请详情
|
||||
-->
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<div class="report-section">
|
||||
<div class="report-title">
|
||||
<span>手术申请</span>
|
||||
<el-icon
|
||||
class="report-refresh-icon"
|
||||
:class="{ 'is-loading': loading }"
|
||||
@click="handleRefresh"
|
||||
>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="report-table-wrapper">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
border
|
||||
size="small"
|
||||
height="100%"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
||||
<el-table-column prop="name" label="申请单名称" width="140" />
|
||||
<el-table-column prop="createTime" label="创建时间" width="160" />
|
||||
<el-table-column prop="prescriptionNo" label="处方号" width="140" />
|
||||
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
||||
<el-table-column label="操作" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 详情弹窗 -->
|
||||
<el-dialog
|
||||
v-model="detailDialogVisible"
|
||||
title="手术申请详情"
|
||||
width="800px"
|
||||
destroy-on-close
|
||||
top="5vh"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div v-if="currentDetail" class="applicationShow-container">
|
||||
<div class="applicationShow-container-content">
|
||||
<el-descriptions title="基本信息" :column="2">
|
||||
<el-descriptions-item label="患者姓名">{{
|
||||
currentDetail.patientName || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单名称">{{
|
||||
currentDetail.name || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{
|
||||
currentDetail.createTime || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="处方号">{{
|
||||
currentDetail.prescriptionNo || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请者">{{
|
||||
currentDetail.requesterId_dictText || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="就诊ID">{{
|
||||
currentDetail.encounterId || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单ID">{{
|
||||
currentDetail.requestFormId || '-'
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div v-if="descJsonData && hasMatchedFields" class="applicationShow-container-content">
|
||||
<el-descriptions title="申请单描述" :column="2">
|
||||
<template v-for="(value, key) in descJsonData" :key="key">
|
||||
<el-descriptions-item v-if="isFieldMatched(key)" :label="getFieldLabel(key)">
|
||||
{{ value || '-' }}
|
||||
</el-descriptions-item>
|
||||
</template>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="currentDetail.requestFormDetailList && currentDetail.requestFormDetailList.length"
|
||||
class="applicationShow-container-table"
|
||||
>
|
||||
<el-table :data="currentDetail.requestFormDetailList" border>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="adviceName" label="医嘱名称" />
|
||||
<el-table-column prop="quantity" label="数量" width="80" align="center" />
|
||||
<el-table-column prop="unitCode_dictText" label="单位" width="100" />
|
||||
<el-table-column prop="totalPrice" label="总价" width="100" align="right" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<div class="container">
|
||||
<el-button @click="getInfo">查询</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getCurrentInstance, ref, watch, computed } from 'vue';
|
||||
import { Refresh } from '@element-plus/icons-vue';
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
import { getCurrentInstance, onBeforeMount, onMounted, reactive } from 'vue';
|
||||
import { getSurgery } from './api';
|
||||
import { getOrgList } from '../../../../doctorstation/components/api.js';
|
||||
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const tableData = ref([]);
|
||||
const loading = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!patientInfo.value?.encounterId) {
|
||||
tableData.value = [];
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getSurgery({ encounterId: patientInfo.value.encounterId });
|
||||
if (res.code === 200 && res.data) {
|
||||
const raw = res.data?.records || res.data;
|
||||
const list = Array.isArray(raw) ? raw : [raw];
|
||||
tableData.value = list.filter(Boolean);
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
} catch (e) {
|
||||
proxy.$modal?.msgError?.(e.message || '查询手术申请失败');
|
||||
tableData.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRefresh = async () => {
|
||||
if (loading.value || !patientInfo.value?.encounterId) return;
|
||||
await fetchData();
|
||||
};
|
||||
|
||||
const labelMap = {
|
||||
categoryType: '项目类别',
|
||||
targetDepartment: '发往科室',
|
||||
symptom: '症状',
|
||||
sign: '体征',
|
||||
clinicalDiagnosis: '临床诊断',
|
||||
otherDiagnosis: '其他诊断',
|
||||
relatedResult: '相关结果',
|
||||
attention: '注意事项',
|
||||
};
|
||||
|
||||
const isFieldMatched = (key) => {
|
||||
return key in labelMap;
|
||||
};
|
||||
|
||||
const getFieldLabel = (key) => {
|
||||
return labelMap[key] || key;
|
||||
};
|
||||
|
||||
const hasMatchedFields = computed(() => {
|
||||
if (!descJsonData.value) return false;
|
||||
return Object.keys(descJsonData.value).some((key) => isFieldMatched(key));
|
||||
});
|
||||
|
||||
/** 查询科室 */
|
||||
const getLocationInfo = () => {
|
||||
getOrgList().then((res) => {
|
||||
orgOptions.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
const recursionFun = (targetDepartment) => {
|
||||
let name = '';
|
||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||
const obj = orgOptions.value[index];
|
||||
if (obj.id == targetDepartment) {
|
||||
name = obj.name;
|
||||
}
|
||||
const subObjArray = obj['children'];
|
||||
for (let index = 0; index < subObjArray.length; index++) {
|
||||
const item = subObjArray[index];
|
||||
if (item.id == targetDepartment) {
|
||||
name = item.name;
|
||||
const emits = defineEmits([]);
|
||||
const props = defineProps({});
|
||||
const state = reactive({});
|
||||
const getInfo = () => {
|
||||
if (patientInfo.value?.inHospitalOrgId) {
|
||||
getSurgery({
|
||||
encounterId: patientInfo.value.encounterId,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const handleViewDetail = (row) => {
|
||||
currentDetail.value = row;
|
||||
// 解析 descJson
|
||||
if (row.descJson) {
|
||||
try {
|
||||
// descJsonData.value = JSON.parse(row.descJson);
|
||||
const obj = JSON.parse(row.descJson);
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
descJsonData.value = obj;
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
descJsonData.value = null;
|
||||
}
|
||||
} else {
|
||||
descJsonData.value = null;
|
||||
}
|
||||
detailDialogVisible.value = true;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => patientInfo.value?.encounterId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
fetchData();
|
||||
getLocationInfo();
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
refresh: fetchData,
|
||||
onBeforeMount(() => {});
|
||||
onMounted(() => {
|
||||
getInfo();
|
||||
});
|
||||
defineExpose({ state });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 8px 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.report-section {
|
||||
background: #fff;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.report-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.report-table-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.report-refresh-icon {
|
||||
cursor: pointer;
|
||||
color: #909399;
|
||||
transition: color 0.2s;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.report-refresh-icon:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.report-refresh-icon.is-loading {
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.applicationShow-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 70vh;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
.applicationShow-container-content {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.applicationShow-container-table {
|
||||
flex-shrink: 0;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -4,315 +4,34 @@
|
||||
* @Description: 检验申请
|
||||
-->
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<div class="report-section">
|
||||
<div class="report-title">
|
||||
<span>检验申请</span>
|
||||
<el-icon
|
||||
class="report-refresh-icon"
|
||||
:class="{ 'is-loading': loading }"
|
||||
@click="handleRefresh"
|
||||
>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="report-table-wrapper">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
border
|
||||
size="small"
|
||||
height="100%"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
||||
<el-table-column prop="name" label="申请单名称" width="140" />
|
||||
<el-table-column prop="createTime" label="创建时间" width="160" />
|
||||
<el-table-column prop="prescriptionNo" label="处方号" width="140" />
|
||||
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
||||
<el-table-column label="操作" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 详情弹窗 -->
|
||||
<el-dialog
|
||||
v-model="detailDialogVisible"
|
||||
title="检验申请详情"
|
||||
width="800px"
|
||||
destroy-on-close
|
||||
top="5vh"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div v-if="currentDetail" class="applicationShow-container">
|
||||
<div class="applicationShow-container-content">
|
||||
<el-descriptions title="基本信息" :column="2">
|
||||
<el-descriptions-item label="患者姓名">{{
|
||||
currentDetail.patientName || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单名称">{{
|
||||
currentDetail.name || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{
|
||||
currentDetail.createTime || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="处方号">{{
|
||||
currentDetail.prescriptionNo || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请者">{{
|
||||
currentDetail.requesterId_dictText || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="就诊ID">{{
|
||||
currentDetail.encounterId || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单ID">{{
|
||||
currentDetail.requestFormId || '-'
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div v-if="descJsonData && hasMatchedFields" class="applicationShow-container-content">
|
||||
<el-descriptions title="申请单描述" :column="2">
|
||||
<template v-for="(value, key) in descJsonData" :key="key">
|
||||
<el-descriptions-item v-if="isFieldMatched(key)" :label="getFieldLabel(key)">
|
||||
{{ value || '-' }}
|
||||
</el-descriptions-item>
|
||||
</template>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="currentDetail.requestFormDetailList && currentDetail.requestFormDetailList.length"
|
||||
class="applicationShow-container-table"
|
||||
>
|
||||
<el-table :data="currentDetail.requestFormDetailList" border>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="adviceName" label="医嘱名称" />
|
||||
<el-table-column prop="quantity" label="数量" width="80" align="center" />
|
||||
<el-table-column prop="unitCode_dictText" label="单位" width="100" />
|
||||
<el-table-column prop="totalPrice" label="总价" width="100" align="right" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<div class="container">
|
||||
<el-button @click="getInfo">查询</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getCurrentInstance, ref, watch, computed } from 'vue';
|
||||
import { Refresh } from '@element-plus/icons-vue';
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
import { getCurrentInstance, onBeforeMount, onMounted, reactive } from 'vue';
|
||||
import { getInspection } from './api';
|
||||
import { getOrgList } from '../../../../doctorstation/components/api.js';
|
||||
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const tableData = ref([]);
|
||||
const loading = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!patientInfo.value?.encounterId) {
|
||||
tableData.value = [];
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getInspection({ encounterId: patientInfo.value.encounterId });
|
||||
if (res.code === 200 && res.data) {
|
||||
const raw = res.data?.records || res.data;
|
||||
const list = Array.isArray(raw) ? raw : [raw];
|
||||
tableData.value = list.filter(Boolean);
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
} catch (e) {
|
||||
proxy.$modal?.msgError?.(e.message || '查询检验申请失败');
|
||||
tableData.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRefresh = async () => {
|
||||
if (loading.value || !patientInfo.value?.encounterId) return;
|
||||
await fetchData();
|
||||
};
|
||||
|
||||
const labelMap = {
|
||||
categoryType: '项目类别',
|
||||
targetDepartment: '发往科室',
|
||||
symptom: '症状',
|
||||
sign: '体征',
|
||||
clinicalDiagnosis: '临床诊断',
|
||||
otherDiagnosis: '其他诊断',
|
||||
relatedResult: '相关结果',
|
||||
attention: '注意事项',
|
||||
};
|
||||
|
||||
const isFieldMatched = (key) => {
|
||||
return key in labelMap;
|
||||
};
|
||||
|
||||
const getFieldLabel = (key) => {
|
||||
return labelMap[key] || key;
|
||||
};
|
||||
|
||||
const hasMatchedFields = computed(() => {
|
||||
if (!descJsonData.value) return false;
|
||||
return Object.keys(descJsonData.value).some((key) => isFieldMatched(key));
|
||||
});
|
||||
|
||||
/** 查询科室 */
|
||||
const getLocationInfo = () => {
|
||||
getOrgList().then((res) => {
|
||||
orgOptions.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
const recursionFun = (targetDepartment) => {
|
||||
let name = '';
|
||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||
const obj = orgOptions.value[index];
|
||||
if (obj.id == targetDepartment) {
|
||||
name = obj.name;
|
||||
}
|
||||
const subObjArray = obj['children'];
|
||||
for (let index = 0; index < subObjArray.length; index++) {
|
||||
const item = subObjArray[index];
|
||||
if (item.id == targetDepartment) {
|
||||
name = item.name;
|
||||
const emits = defineEmits([]);
|
||||
const props = defineProps({});
|
||||
const state = reactive({});
|
||||
const getInfo = () => {
|
||||
if (patientInfo.value?.inHospitalOrgId) {
|
||||
getInspection({
|
||||
encounterId: patientInfo.value.encounterId,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const handleViewDetail = (row) => {
|
||||
currentDetail.value = row;
|
||||
// 解析 descJson
|
||||
if (row.descJson) {
|
||||
try {
|
||||
const obj = JSON.parse(row.descJson);
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
descJsonData.value = obj;
|
||||
// descJsonData.value = JSON.parse(row.descJson);
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
descJsonData.value = null;
|
||||
}
|
||||
} else {
|
||||
descJsonData.value = null;
|
||||
}
|
||||
detailDialogVisible.value = true;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => patientInfo.value?.encounterId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
fetchData();
|
||||
getLocationInfo();
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
refresh: fetchData,
|
||||
onBeforeMount(() => {});
|
||||
onMounted(() => {
|
||||
getInfo();
|
||||
});
|
||||
defineExpose({ state });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 8px 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.report-section {
|
||||
background: #fff;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.report-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.report-table-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.report-refresh-icon {
|
||||
cursor: pointer;
|
||||
color: #909399;
|
||||
transition: color 0.2s;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.report-refresh-icon:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.report-refresh-icon.is-loading {
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.applicationShow-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 70vh;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
.applicationShow-container-content {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.applicationShow-container-table {
|
||||
flex-shrink: 0;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
Reference in New Issue
Block a user