Files
his/openhis-ui-vue3/src/views/drug/inpatientMedicationDispensing/index.vue
2025-12-10 14:20:24 +08:00

456 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-row :gutter="20" style="margin-bottom: 20px">
<el-col :span="4" :xs="24">
<el-button
:type="selectType === 'total' ? 'primary' : 'default'"
@click="handleSelectType('total')"
>汇总</el-button
>
<el-button
:type="selectType === 'drug' ? 'primary' : 'default'"
@click="handleSelectType('drug')"
>发药</el-button
>
</el-col>
<!-- <el-col :span="18" :xs="24">
<el-form ref="queryParams" label-width="100px" :model="queryParams" :inline="true">
<el-form-item label="窗口" prop="windowDataText" label-width="120px">
<el-select
v-model="queryParams.windowDataText"
placeholder="请选择"
clearable
filterable
>
<el-option
v-for="item in windowData"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="摆药单" prop="medicationListText" label-width="120px">
<el-select
v-model="queryParams.medicationListText"
placeholder="请选择"
clearable
filterable
>
<el-option
v-for="item in medicationList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="范围" prop="time" label-width="100px">
<el-radio-group v-model="queryParams.timeRange">
<el-radio v-for="(item, index) in timeRangeList" :key="index" :value="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="时间" prop="time" label-width="100px">
<el-date-picker
v-model="dateRange"
type="datetimerange"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</el-form>
</el-col> -->
</el-row>
<el-row :gutter="20">
<el-col :span="6" class="left-container">
<el-row>
<el-col :span="24">
<el-form
:model="queryParamsPatient"
ref="queryRef"
v-show="showSearch"
label-width="120"
inline="true"
>
<el-form-item label="患者信息" prop="searchKey" label-width="120">
<el-input
v-model="queryParamsPatient.searchKey"
placeholder="请输入姓名/证件号"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item
label="发药状态"
prop="statusEnum"
v-if="selectType !== 'drug'"
label-width="120"
>
<el-select
v-model="queryParamsPatient.statusEnum"
placeholder="请选择"
clearable
filterable
style="width: 240px"
@change="handleQuery"
>
<el-option
v-for="item in dispenseStatusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="就诊日期" prop="startTime">
<el-date-picker
v-model="dateRange"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
style="width: 240px"
@keyup.enter="handleQuery"
@change="handleQuery"
/>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row :gutter="20" style="border-radius: 4px">
<el-col :span="24">
<el-table
:data="patientList"
border
highlight-current-row
style="height: cal(100%-200px); width: 100%"
@row-click="handleCurrentChange"
>
<!-- 汇总状态下显示的字段 -->
<template v-if="selectType === 'total'">
<el-table-column prop="applicantName" label="申请人" align="center" />
<el-table-column prop="sourceLocationName" label="发药药房" align="center" />
<el-table-column prop="statusEnum_enumText" label="状态" align="center" />
<el-table-column prop="applyTime" label="申请日期" align="center">
<template #default="scope">
{{ scope.row.applyTime ? parseTime(scope.row.applyTime, '{y}-{m}-{d}') : '-' }}
</template>
</el-table-column>
</template>
<!-- 明细状态下显示的字段 -->
<template v-else>
<el-table-column prop="patientName" label="姓名" align="center" />
<el-table-column prop="genderEnum_enumText" label="性别" align="center" />
<el-table-column prop="age" label="年龄" align="center" />
<el-table-column prop="startTime" label="就诊日期" align="center">
<template #default="scope">
{{ scope.row.startTime ? parseTime(scope.row.startTime, '{y}-{m}-{d}') : '-' }}
</template>
</el-table-column>
</template>
</el-table>
</el-col>
<el-col :span="24" style="padding: 10px 12px 12px 12px">
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</el-col>
</el-row>
</el-col>
<el-col :span="18" :xs="24">
<!-- 根据当前选中的tab显示不同的表格组件 -->
<MedicationTable v-if="selectType === 'total'" :tableData="tableData" :busNo="busNo" />
<DetailMedicationTable
v-else-if="selectType === 'drug'"
:tableData="detailTableData"
:encounterId="encounterId"
@call-medication-summary-detail="callMedicationSummaryDetail"
/>
</el-col>
</el-row>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import MedicationTable from './components/MedicationTable.vue';
import DetailMedicationTable from './components/DetailMedicationTable.vue';
import { getCurrentInstance } from 'vue';
import {
getFromSummaryList,
getEncounterList,
getMedicationSummaryDetail,
getFromDetailList,
} from './components/api';
// 响应式数据
const loading = ref(false);
const patientList = ref([]);
const total = ref(0);
const showSearch = ref(true);
const { proxy } = getCurrentInstance();
// 查询参数
const queryParams = reactive({
searchKey: '',
statusEnum: '',
pageNo: 1,
pageSize: 10,
windowDataText: '',
medicationListText: '',
timeRange: 1,
});
const queryParamsPatient = ref({
searchKey: '',
statusEnum: '1',
pageNo: 1,
pageSize: 10,
});
// 日期范围
const dateRange = ref([
new Date().toISOString().split('T')[0],
new Date().toISOString().split('T')[0],
]);
// 发药状态选项
const dispenseStatusOptions = ref([
{ label: '待发药', value: '1' },
{ label: '已发药', value: '2' },
{ label: '全部', value: '0' },
]);
// 加载患者列表数据
async function getList() {
if (dateRange.value == null) {
proxy.$message.warning('请选择日期');
return;
}
loading.value = true;
try {
let response;
// 构建查询参数 - 只保留必要的分页和筛选条件
const params = {
searchKey: queryParamsPatient.value.searchKey,
statusEnum: queryParamsPatient.value.statusEnum,
pageNo: queryParamsPatient.value.pageNo,
pageSize: queryParamsPatient.value.pageSize,
startTime: dateRange.value[0],
endTime: dateRange.value[1],
};
// 根据当前标签页调用不同的接口
if (selectType.value === 'total') {
// 汇总标签页
response = await getFromSummaryList(params);
patientList.value = response.data;
total.value = response.data.length || 0;
} else {
// 明细标签页
response = await getEncounterList(params);
patientList.value = response.data.records;
total.value = response.data.total || 0;
}
} catch (error) {
patientList.value = [];
total.value = 0;
} finally {
loading.value = false;
}
}
// 搜索处理
async function handleQuery() {
queryParamsPatient.value.pageNo = 1; // 重置为第一页
await getList();
}
const busNo = ref('');
const encounterId = ref('');
// 处理表格行点击
function handleCurrentChange(row) {
busNo.value = row.busNo;
encounterId.value = row.encounterId;
if (selectType.value === 'total') {
// 汇总标签页
callSummaryMedicationDetail(row.busNo);
} else {
// 明细标签页
callMedicationSummaryDetail(row.encounterId);
}
}
// 明细标签页
async function callMedicationSummaryDetail(encounterId) {
console.log('点击明细标签页', encounterId);
// 显示加载提示
loading.value = true;
try {
const params = {
encounterId,
};
const response = await getMedicationSummaryDetail(params);
// 处理药品汇总详情数据
handleMedicationSummaryDetail(response.data);
} catch (error) {
ElMessage.error('获取药品汇总详情失败:' + (error.message || '未知错误'));
// 发生错误时清空数据
handleMedicationSummaryDetail([]);
} finally {
// 无论成功失败都关闭加载状态
loading.value = false;
}
}
// 汇总标签页
async function callSummaryMedicationDetail(busNo) {
// 显示加载提示
loading.value = true;
try {
const params = {
busNo,
};
const response = await getFromDetailList(params);
// 处理汇总药品详情数据
handleMedicationSummaryDetail(response.data);
} catch (error) {
ElMessage.error('获取汇总药品详情失败:' + (error.message || '未知错误'));
// 发生错误时清空数据
handleMedicationSummaryDetail([]);
} finally {
// 无论成功失败都关闭加载状态
loading.value = false;
}
}
// 窗口数据
const windowData = reactive([
{
label: '窗口1',
value: 1,
},
{
label: '窗口2',
value: 2,
},
{
label: '窗口3',
value: 3,
},
]);
// 摆药单数据
const medicationList = reactive([
{
label: '药单1',
value: 1,
},
{
label: '药单2',
value: 2,
},
{
label: '药单3',
value: 3,
},
]);
// 时间范围选项
const timeRangeList = [
{
label: '全部',
value: 1,
},
{
label: '长期',
value: 2,
},
{
label: '临时',
value: 3,
},
];
// 表格类型
const selectType = ref('total');
// 表格数据用于显示右侧药品列表汇总tab
const tableData = reactive([]);
// 明细表格数据用于明细tab
const detailTableData = reactive([]);
// 切换表格类型
function handleSelectType(type) {
selectType.value = type;
reset();
getList();
}
function reset() {
busNo.value = '';
encounterId.value = '';
patientList.value = [];
total.value = 0;
// 保持响应式引用不变,逐字段还原默认
queryParamsPatient.value.searchKey = '';
queryParamsPatient.value.statusEnum = '1';
queryParamsPatient.value.pageNo = 1;
queryParamsPatient.value.pageSize = 10;
}
// 处理子组件传递的药品汇总详情数据
function handleMedicationSummaryDetail(data) {
// 检查数据是否为数组
const medicationData = Array.isArray(data)
? data
: typeof data === 'object' && data !== null && Array.isArray(data.records)
? data.records
: [];
// 根据当前tab将数据分配到不同的表格
if (selectType.value === 'total') {
// 汇总tab - 清空表格数据
tableData.splice(0, tableData.length);
if (medicationData.length > 0) {
medicationData.forEach((item, index) => {
tableData.push({
currentIndex: index + 1,
...item,
});
});
}
} else {
// 明细tab - 将数据渲染到DetailMedicationTable组件
detailTableData.splice(0, detailTableData.length);
medicationData.forEach((item) => {
detailTableData.push({
...item,
});
});
}
}
// 组件挂载时初始化数据
onMounted(() => {
getList();
});
</script>
<style scoped>
.left-container {
border-radius: 4px;
border: 1px solid #f5f5f5;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
padding: 20px;
}
</style>