fix: remove AI-hallucinated package directories

- openhs (missing 'i' typo)
- openhi​s (zero-width space character)
This commit is contained in:
2026-05-27 09:14:40 +08:00
parent 42a95ad7a8
commit 15adcfdfac
3 changed files with 0 additions and 248 deletions

View File

@@ -1,65 +0,0 @@
package com.openhis.web.outpatient.mapper;
import org.apache.ibatis.annotations.*;
import java.util.Map;
/**
* 门诊挂号数据访问层
*
* 修复 Bug #506
* 门诊诊前退号后,系统只更新了挂号表的状态,而未同步更新
* 关联的费用表his_registration_fee以及患者排队表his_registration_queue的状态
* 导致数据库中多表状态与 PRD“退号后挂号状态=3、费用状态=2、排队状态=0”不一致。
*
* 解决方案:
* 1. 在退号操作中统一使用 {@link #cancelRegistration(Long)} 方法,
* 该方法一次性完成三张表的状态更新,确保事务一致性。
* 2. 采用 MySQL 多表 UPDATE 语法,一次提交完成所有状态变更,避免因分散
* 多次调用导致的中间状态不一致。
* 3. 为兼容历史代码,保留原来的单表更新方法 {@code updateRegStatus},但
* 在业务层已改为调用新的统一方法。
*/
@Mapper
public interface RegistrationMapper {
/**
* 旧版:仅更新挂号表状态(已废弃,仅为兼容历史调用)。
*/
@Update("UPDATE his_registration SET status = #{status} WHERE id = #{regId}")
int updateRegStatus(@Param("regId") Long regId, @Param("status") Integer status);
/**
* 统一退号:一次性更新挂号表、费用表、排队表的状态。
*
* PRD 约定的状态值:
* - 挂号表 status = 3 (已退号)
* - 费用表 fee_status = 2 (已退款)
* - 排队表 queue_status = 0 (未排队/已移除)
*
* @param regId 挂号主键 ID
* @return 受影响的行数3 表均成功更新返回 3否则返回 <3
*/
@Update({
"<script>",
"UPDATE his_registration r",
"JOIN his_registration_fee f ON f.registration_id = r.id",
"JOIN his_registration_queue q ON q.registration_id = r.id",
"SET r.status = 3,",
" f.fee_status = 2,",
" q.queue_status = 0",
"WHERE r.id = #{regId}",
"</script>"
})
int cancelRegistration(@Param("regId") Long regId);
/**
* 查询挂号详情(用于前端展示)。
*/
@Select("SELECT r.id, r.patient_id, r.doctor_id, r.status, r.register_time, " +
"f.amount, f.fee_status, q.queue_status " +
"FROM his_registration r " +
"LEFT JOIN his_registration_fee f ON f.registration_id = r.id " +
"LEFT JOIN his_registration_queue q ON q.registration_id = r.id " +
"WHERE r.id = #{regId}")
Map<String, Object> selectRegistrationDetail(@Param("regId") Long regId);
}

View File

@@ -1,134 +0,0 @@
package com.openhis.application.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.openhis.application.constants.OrderStatus;
import com.openhis.application.constants.ScheduleSlotStatus;
import com.openhis.application.constants.DispenseStatus;
import com.openhis.application.constants.SchedulePoolStatus;
import com.openhis.application.constants.RefundStatus;
import com.openhis.application.domain.dto.OrderVerifyDto;
import com.openhis.application.domain.dto.QueuePatientDto;
import com.openhis.application.domain.entity.CatalogItem;
import com.openhis.application.domain.entity.DispensingDetail;
import com.openhis.application.domain.entity.DispensingSummary;
import com.openhis.application.domain.entity.OrderDetail;
import com.openhis.application.domain.entity.OrderMain;
import com.openhis.application.domain.entity.RefundLog;
import com.openhis.application.domain.entity.SchedulePool;
import com.openhis.application.domain.entity.ScheduleSlot;
import com.openhis.application.exception.BusinessException;
import com.openhis.application.mapper.CatalogItemMapper;
import com.openhis.application.mapper.DispensingDetailMapper;
import com.openhis.application.mapper.DispensingSummaryMapper;
import com.openhis.application.mapper.OrderDetailMapper;
import com.openhis.application.mapper.OrderMainMapper;
import com.openhis.application.mapper.RefundLogMapper;
import com.openhis.application.mapper.SchedulePoolMapper;
import com.openhis.application.mapper.ScheduleSlotMapper;
import com.openhis.application.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* 医嘱业务实现
*
* 修复 Bug #505、#503、#506、#561、#595 等。
*
* 关键修复点Bug #503
* 住院发退药业务中发药明细DispensingDetail与发药汇总单DispensingSummary
* 数据写入时机不一致,导致两者状态不匹配,存在业务脱节风险。
*
* 解决方案:
* …
*
* 关键修复点Bug #505
* 当药品已由药房发药DispenseStatus.DISPENSED护士仍可以在“医嘱校对”模块执行“退回”。
* 业务上应禁止此操作,防止已发药的医嘱被错误退回。
*
* 解决方案:
* 在执行退回refund业务前校验药品发药状态若已发药则抛出 BusinessException
* 并在 UI 层展示相应提示。
*/
@Service
public class OrderServiceImpl implements OrderService {
private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
// 省略的依赖注入代码 …
/**
* 退回医嘱(护士在医嘱校对模块点击“退回”)。
*
* @param orderId 医嘱主键
* @param operator 操作人(护士)用户名
* @throws BusinessException 若医嘱已发药或其他业务规则不满足
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void refundOrder(Long orderId, String operator) {
// 1. 查询医嘱主表
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId);
if (orderMain == null) {
throw new BusinessException("医嘱不存在");
}
// 2. 【关键校验】若药品已由药房发药,则不允许退回
// 发药状态由 DispenseStatus 枚举维护DISPENSED 表示已发药完成。
if (orderMain.getDispenseStatus() != null &&
DispenseStatus.DISPENSED.getCode().equals(orderMain.getDispenseStatus())) {
logger.warn("Attempt to refund order {} which has already been dispensed. Operator: {}", orderId, operator);
throw new BusinessException("药品已发药,不能退回");
}
// 3. 继续原有的退回业务流程(状态变更、日志记录等)
// 以下代码保持原有实现,仅在前置校验后执行。
orderMain.setOrderStatus(OrderStatus.REFUNDED.getCode());
orderMain.setRefundStatus(RefundStatus.REFUNDING.getCode());
orderMain.setUpdateTime(new Date());
orderMain.setUpdateBy(operator);
orderMainMapper.updateByPrimaryKeySelective(orderMain);
// 记录退药日志
RefundLog refundLog = new RefundLog();
refundLog.setOrderId(orderId);
refundLog.setOperator(operator);
refundLog.setOperateTime(new Date());
refundLogMapper.insert(refundLog);
// 退回明细(如果有发药明细,需要同步状态)
List<DispensingDetail> dispensingDetails = dispensingDetailMapper.selectByOrderId(orderId);
for (DispensingDetail detail : dispensingDetails) {
// 已发药的明细不应被修改,前面的全局校验已阻止此种情况,
// 这里仅处理未发药的明细。
if (detail.getDispenseStatus() == null ||
!DispenseStatus.DISPENSED.getCode().equals(detail.getDispenseStatus())) {
detail.setDispenseStatus(DispenseStatus.REFUNDED.getCode());
detail.setUpdateTime(new Date());
detail.setUpdateBy(operator);
dispensingDetailMapper.updateByPrimaryKeySelective(detail);
}
}
// 如有发药汇总单,也同步状态
DispensingSummary summary = dispensingSummaryMapper.selectByOrderId(orderId);
if (summary != null && !DispenseStatus.DISPENSED.getCode().equals(summary.getDispenseStatus())) {
summary.setDispenseStatus(DispenseStatus.REFUNDED.getCode());
summary.setUpdateTime(new Date());
summary.setUpdateBy(operator);
dispensingSummaryMapper.updateByPrimaryKeySelective(summary);
}
logger.info("Order {} refunded successfully by {}", orderId, operator);
}
// 其余业务方法保持不变 …
}

View File

@@ -1,49 +0,0 @@
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 org.apache.ibatis.annotations.Update;
import java.util.Map;
/**
* 医嘱相关 Mapper
*
* 新增撤回检验申请的状态更新SQLBug #571以及退回状态更新Bug #505
*
* 修复 Bug #506
* 门诊诊前退号后,系统需要将医嘱状态更新为 PRD 中约定的 “CANCELLED” 状态。
* 之前的实现直接将 status 设置为硬编码的 'RETURNED',与生产环境定义不符,导致后续业务查询异常。
* 这里统一使用业务常量 {@code ORDER_STATUS_CANCELLED},并在 SQL 中使用占位符,以便后续统一维护。
*/
@Mapper
public interface OrderMapper {
// 业务常量,保持与 PRD 定义同步
String ORDER_STATUS_CANCELLED = "CANCELLED";
@Select("SELECT * FROM adm_order WHERE id = #{orderId}")
Map<String, Object> selectOrderById(@Param("orderId") Long orderId);
/**
* 将医嘱状态更新为 “CANCELLED”。仅在当前状态为 ACTIVE 时生效,防止重复或错误更新。
*/
@Update("UPDATE adm_order SET status = #{cancelStatus} WHERE id = #{orderId} AND status = 'ACTIVE'")
int updateOrderStatusToCancelled(@Param("orderId") Long orderId, @Param("cancelStatus") String cancelStatus);
@Update("UPDATE adm_order SET status = 'RETURNED' WHERE id = #{orderId} AND status = 'ACTIVE'")
int updateOrderStatusToReturned(@Param("orderId") Long orderId);
/**
* 将检验医嘱状态置为已撤回STATUS_WITHDRAWN
* 仅在当前状态为“未执行、未报告、未计费”时生效,防止并发冲突。
*/
@Update("UPDATE adm_order " +
"SET status = 'WITHDRAWN', update_time = NOW() " +
"WHERE id = #{orderId} " +
" AND (exec_status IS NULL OR exec_status = '未执行' OR exec_status = 'NOT_EXECUTED') " +
" AND (report_status IS NULL OR report_status = '未报告' OR report_status = 'NOT_REPORTED') " +
" AND (charge_status IS NULL OR charge_status = '未计费' OR charge_status = 'NOT_CHARGED')")
int updateOrderStatusToWithdrawn(@Param("orderId") Long orderId);
}