Fix Bug #503: AI修复
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package com.openhis.web.inpatient.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 住院发退药数据访问层
|
||||
* 修复 Bug #503:统一明细单与汇总单的状态过滤条件,消除触发时机不一致导致的业务脱节风险
|
||||
*/
|
||||
@Mapper
|
||||
public interface InpatientDispensingMapper {
|
||||
|
||||
/**
|
||||
* 查询发药明细单
|
||||
* @param wardId 病区ID
|
||||
* @param statusList 统一的状态过滤列表 (需申请模式: ['SUBMITTED'], 自动模式: ['EXECUTED', 'SUBMITTED'])
|
||||
*/
|
||||
@Select("<script>" +
|
||||
"SELECT d.id, d.patient_name, d.patient_no, d.drug_name, d.spec, d.dosage, d.quantity, d.apply_status " +
|
||||
"FROM phm_dispensing_detail d " +
|
||||
"WHERE d.ward_id = #{wardId} " +
|
||||
"AND d.apply_status IN " +
|
||||
"<foreach item='status' collection='statusList' open='(' separator=',' close=')'>" +
|
||||
" #{status} " +
|
||||
"</foreach>" +
|
||||
"ORDER BY d.create_time DESC" +
|
||||
"</script>")
|
||||
List<Map<String, Object>> selectDispensingDetails(@Param("wardId") Long wardId,
|
||||
@Param("statusList") List<String> statusList);
|
||||
|
||||
/**
|
||||
* 查询发药汇总单
|
||||
* @param wardId 病区ID
|
||||
* @param statusList 统一的状态过滤列表
|
||||
*/
|
||||
@Select("<script>" +
|
||||
"SELECT s.id, s.ward_name, s.total_items, s.total_quantity, s.apply_status " +
|
||||
"FROM phm_dispensing_summary s " +
|
||||
"WHERE s.ward_id = #{wardId} " +
|
||||
"AND s.apply_status IN " +
|
||||
"<foreach item='status' collection='statusList' open='(' separator=',' close=')'>" +
|
||||
" #{status} " +
|
||||
"</foreach>" +
|
||||
"ORDER BY s.create_time DESC" +
|
||||
"</script>")
|
||||
List<Map<String, Object>> selectDispensingSummaries(@Param("wardId") Long wardId,
|
||||
@Param("statusList") List<String> statusList);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.openhis.web.inpatient.service.impl;
|
||||
|
||||
import com.openhis.web.inpatient.mapper.InpatientDispensingMapper;
|
||||
import com.openhis.web.inpatient.service.InpatientDispensingService;
|
||||
import com.openhis.web.system.service.SysDictDataService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 住院发退药业务实现
|
||||
* 修复 Bug #503:根据字典配置统一明细与汇总单的查询触发时机,确保数据状态同步
|
||||
*/
|
||||
@Service
|
||||
public class InpatientDispensingServiceImpl implements InpatientDispensingService {
|
||||
|
||||
private final InpatientDispensingMapper dispensingMapper;
|
||||
private final SysDictDataService dictDataService;
|
||||
|
||||
public InpatientDispensingServiceImpl(InpatientDispensingMapper dispensingMapper,
|
||||
SysDictDataService dictDataService) {
|
||||
this.dispensingMapper = dispensingMapper;
|
||||
this.dictDataService = dictDataService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryPharmacyDispensingData(Long wardId) {
|
||||
// 1. 获取字典配置:病区护士执行提交药品模式 (默认: 1-需申请模式, 2-自动模式)
|
||||
String submitMode = dictDataService.getDictValueByType("ward_nurse_drug_submit_mode");
|
||||
if (submitMode == null || submitMode.isBlank()) {
|
||||
submitMode = "1"; // 默认需申请模式
|
||||
}
|
||||
|
||||
// 2. 统一数据触发状态条件,彻底解决“明细先显、汇总后显”的逻辑脱节
|
||||
// 需申请模式(1):仅查询已汇总申请的数据 (apply_status = 'SUBMITTED')
|
||||
// 自动模式(2):查询护士已执行的数据 (apply_status = 'EXECUTED' 或 'SUBMITTED')
|
||||
List<String> statusFilter = "1".equals(submitMode)
|
||||
? Arrays.asList("SUBMITTED")
|
||||
: Arrays.asList("EXECUTED", "SUBMITTED");
|
||||
|
||||
// 3. 同步查询明细与汇总单,确保药房端接收到的数据触发时机完全一致
|
||||
List<Map<String, Object>> detailList = dispensingMapper.selectDispensingDetails(wardId, statusFilter);
|
||||
List<Map<String, Object>> summaryList = dispensingMapper.selectDispensingSummaries(wardId, statusFilter);
|
||||
|
||||
return Map.of(
|
||||
"details", detailList,
|
||||
"summaries", summaryList,
|
||||
"mode", submitMode
|
||||
);
|
||||
}
|
||||
}
|
||||
100
openhis-ui-vue3/src/views/pharmacy/PharmacyDispensing.vue
Normal file
100
openhis-ui-vue3/src/views/pharmacy/PharmacyDispensing.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<div class="pharmacy-dispensing-container">
|
||||
<el-card class="header-card">
|
||||
<div class="header-actions">
|
||||
<el-button type="primary" @click="fetchData" data-cy="refresh-btn">刷新数据</el-button>
|
||||
<span class="mode-tag">当前模式: {{ mode === '1' ? '需申请模式' : '自动模式' }}</span>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-row :gutter="20" class="content-row">
|
||||
<el-col :span="12">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>发药明细单</span>
|
||||
<span class="count-badge" data-cy="detail-count">({{ details.length }})</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="details" border v-loading="loading" data-cy="dispensing-detail-table" style="width: 100%">
|
||||
<el-table-column prop="patient_name" label="患者姓名" width="120" />
|
||||
<el-table-column prop="drug_name" label="药品名称" />
|
||||
<el-table-column prop="spec" label="规格" width="100" />
|
||||
<el-table-column prop="quantity" label="数量" width="80" align="center" />
|
||||
<el-table-column prop="apply_status" label="状态" width="100" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>发药汇总单</span>
|
||||
<span class="count-badge" data-cy="summary-count">({{ summaries.length }})</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="summaries" border v-loading="loading" data-cy="dispensing-summary-table" style="width: 100%">
|
||||
<el-table-column prop="ward_name" label="病区" width="120" />
|
||||
<el-table-column prop="total_items" label="总项数" width="100" align="center" />
|
||||
<el-table-column prop="total_quantity" label="总数量" width="100" align="center" />
|
||||
<el-table-column prop="apply_status" label="状态" width="100" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getDispensingData } from '@/api/pharmacy/dispensing'
|
||||
|
||||
const loading = ref(false)
|
||||
const details = ref([])
|
||||
const summaries = ref([])
|
||||
const mode = ref('1')
|
||||
|
||||
const fetchData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
// 统一调用单一接口获取明细与汇总,确保数据源与触发逻辑完全同步
|
||||
const res = await getDispensingData()
|
||||
details.value = res.data.details || []
|
||||
summaries.value = res.data.summaries || []
|
||||
mode.value = res.data.mode || '1'
|
||||
} catch (error) {
|
||||
console.error('获取发药数据失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(fetchData)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pharmacy-dispensing-container {
|
||||
padding: 20px;
|
||||
}
|
||||
.header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.mode-tag {
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.count-badge {
|
||||
color: #909399;
|
||||
font-size: 13px;
|
||||
}
|
||||
.content-row {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user