diff --git a/.githooks/integrity-check.sh b/.githooks/integrity-check.sh deleted file mode 100755 index f1eacf806..000000000 --- a/.githooks/integrity-check.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# ============================================================ -# Integrity Check — 定时巡检 develop 分支的完整性 -# 用法: bash .githooks/integrity-check.sh -# 建议: crontab 每天 8:00 执行一次 -# ============================================================ - -# 配置 -REMOTE="origin" -BRANCH="develop" -WORK_DIR="/tmp/his-integrity-check" - -# 受保护路径 -PATHS=( - "openhis-server-new/pom.xml" - "openhis-server-new/core-admin/pom.xml" - "openhis-server-new/core-common/pom.xml" - "openhis-server-new/core-flowable/pom.xml" - "openhis-server-new/core-framework/pom.xml" - "openhis-server-new/core-generator/pom.xml" - "openhis-server-new/core-quartz/pom.xml" - "openhis-server-new/core-system/pom.xml" - "openhis-server-new/openhis-application/pom.xml" - "openhis-server-new/openhis-domain/pom.xml" - "openhis-server-new/openhis-common/pom.xml" -) - -echo "== Integrity Check $(date) ==" - -# 拉取最新 -cd $WORK_DIR 2>/dev/null || (mkdir -p $WORK_DIR && cd $WORK_DIR && git clone --depth=1 http://zhangfei:GentronHIS2025@192.168.110.253:3000/wangyizhe/his.git . 2>/dev/null) -cd $WORK_DIR && git fetch origin $BRANCH --depth=1 2>/dev/null && git reset --hard origin/$BRANCH 2>/dev/null - -ALL_PASS=true - -# 检查每个路径是否存在 -for path in "${PATHS[@]}"; do - if git ls-tree -r HEAD --name-only 2>/dev/null | grep -q "^$path$"; then - echo " ✅ $path" - else - echo " ❌ $path — 丢失!" - ALL_PASS=false - fi -done - -# 检查最近10次提交是否有异常 -echo "" -echo "最近10次提交:" -git log --oneline -10 2>/dev/null | while read sha msg; do - # 检查删除文件数 - del=$(git diff --name-status ${sha}^..${sha} 2>/dev/null | grep -c "^D") - if [ "$del" -gt 100 ]; then - echo " ⚠️ $sha 删除了 $del 个文件! $msg" - else - echo " ✓ $sha ($del 删除) $msg" - fi -done - -if [ "$ALL_PASS" = true ]; then - echo "" - echo "✅ 完整性检查通过" -else - echo "" - echo "❌ 完整性检查失败! 请立即处理!" -fi diff --git a/.githooks/pre-push b/.githooks/pre-push deleted file mode 100755 index 1b7cddbe6..000000000 --- a/.githooks/pre-push +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash -# ============================================================ -# Pre-push Hook — HIS 项目防误删保护 -# 功能: 推送前检查是否删除了关键文件或大量文件 -# 安装: git config core.hooksPath .githooks -# ============================================================ - -REMOTE="$1" -URL="$2" -ZERO="0000000000000000000000000000000000000000" - -# 受保护路径列表 (严禁删除) -PROTECTED_PATHS=( - "openhis-server-new/pom.xml" - "openhis-server-new/core-admin" - "openhis-server-new/core-framework" - "openhis-server-new/core-system" - "openhis-server-new/core-common" - "openhis-server-new/core-flowable" - "openhis-server-new/core-quartz" - "openhis-server-new/core-generator" - "openhis-server-new/openhis-application" - "openhis-server-new/openhis-domain" - "openhis-server-new/openhis-common" -) - -MAX_DELETE_FILES=100 - -echo "===========================================" -echo " Pre-push: 推送安全检查" -echo "===========================================" - -while read local_ref local_sha remote_ref remote_sha; do - # 跳过删除分支操作 - [ "$local_sha" = "$ZERO" ] && continue - - # 新分支没有 remote_sha,用 origin/develop 做基准 - if [ "$remote_sha" = "$ZERO" ]; then - remote_sha=$(git rev-parse origin/develop 2>/dev/null || echo "") - [ -z "$remote_sha" ] && continue - fi - - # ==== 检查 1: 是否删除了受保护路径 ==== - for path in "${PROTECTED_PATHS[@]}"; do - if git diff --name-status "$remote_sha".."$local_sha" 2>/dev/null | grep -q "^D.*$path"; then - echo "错误: 受保护路径被删除!" - echo " 路径: $path" - echo " 本次推送已拦截。如确有需要,请联系仓库管理员。" - exit 1 - fi - done - - # ==== 检查 2: 是否删除了过多文件 ==== - delete_count=$(git diff --name-status "$remote_sha".."$local_sha" 2>/dev/null | grep -c "^D") - if [ "$delete_count" -gt "$MAX_DELETE_FILES" ]; then - echo "错误: 本次推送删除了 $delete_count 个文件 (阈值: $MAX_DELETE_FILES)" - echo " 请检查是否有误删操作。确认需要推送请执行:" - echo " git push --no-verify origin $local_ref:$remote_ref" - exit 1 - fi - - # ==== 检查 3: 是否删除了 pom.xml (任何位置) ==== - deleted_poms=$(git diff --name-status "$remote_sha".."$local_sha" 2>/dev/null | grep "^D.*pom.xml") - if [ -n "$deleted_poms" ]; then - echo "错误: pom.xml 文件被删除!" - echo "$deleted_poms" - echo " 本次推送已拦截。" - exit 1 - fi - - # ==== 检查 4: 删除/新增比例异常 ==== - add_count=$(git diff --name-status "$remote_sha".."$local_sha" 2>/dev/null | grep -c "^[AMR]") - if [ "$delete_count" -gt 0 ] && [ "$add_count" -gt 0 ]; then - ratio=$((delete_count * 100 / add_count)) - if [ "$ratio" -gt 80 ]; then - echo "警告: 删除文件比例异常 ($ratio% 是删除)" - echo " 删除: $delete_count / 新增: $add_count" - echo " 请人工确认后重新推送。" - exit 1 - fi - fi - - echo "Pre-push 检查通过 ($add_count 新增, $delete_count 删除)" -done - -exit 0 diff --git a/AGENTS.md b/AGENTS.md index 0998f143d..eda61f305 100755 --- a/AGENTS.md +++ b/AGENTS.md @@ -185,22 +185,4 @@ npm run preview - 前端端口:81 - API 前缀:`/openhis` - Swagger UI:`/openhis/swagger-ui/index.html` -- Druid 监控:`/openhis/druid/login.html` -## 🔒 安全铁律 - -### 受保护路径(严禁删除) -以下文件和目录在任何提交中都禁止删除: -- `openhis-server-new/pom.xml` -- `openhis-server-new/core-admin/`、`core-common/`、`core-flowable/`、`core-framework/`、`core-generator/`、`core-quartz/`、`core-system/` -- `openhis-server-new/openhis-application/`、`openhis-domain/`、`openhis-common/` -- 任何 `pom.xml` 文件 - -### 提交规范 -1. **单次提交删除文件数不得超过 100 个** -2. **删除/新增文件比例不得超过 80%** -3. **提交前执行 `git diff --stat` 检查变更范围** -4. **不确定的操作优先用 `git revert` 而不是 `git rm`** - -### 违规后果 -违反上述规则会导致推送被 `pre-push` 钩子拦截,或触发 Gitea 分支保护规则。 - +- Druid 监控:`/openhis/druid/login.html` \ No newline at end of file diff --git a/com/openhis/web/inpatient/controller/DispenseController.java b/com/openhis/web/inpatient/controller/DispenseController.java deleted file mode 100644 index cd6a6010f..000000000 --- a/com/openhis/web/inpatient/controller/DispenseController.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.openhis.web.inpatient.controller; - -import com.openhis.web.inpatient.service.impl.DispenseServiceImpl; -import org.springframework.web.bind.annotation.*; - -import java.util.Map; - -/** - * 住院发退药控制层 - * - * 新增/修改接口,使其调用新的业务实现,确保明细与汇总单同步更新。 - */ -@RestController -@RequestMapping("/api/inpatient/dispense") -public class DispenseController { - - private final DispenseServiceImpl dispenseService; - - public DispenseController(DispenseServiceImpl dispenseService) { - this.dispenseService = dispenseService; - } - - /** - * 发药接口 - * - * @param dispenseId 发药单 ID - * @param quantity 发药数量 - * @return {code:0,msg:"发药成功"} 或 {code:1,msg:"错误信息"} - */ - @PostMapping("/do") - public Map dispense(@RequestParam Long dispenseId, - @RequestParam Integer quantity) { - return dispenseService.dispense(dispenseId, quantity); - } - - /** - * 退药接口 - * - * @param dispenseId 发药单 ID - * @param quantity 退药数量 - * @return {code:0,msg:"退药成功"} 或 {code:1,msg:"错误信息"} - */ - @PostMapping("/return") - public Map returnDrug(@RequestParam Long dispenseId, - @RequestParam Integer quantity) { - return dispenseService.returnDrug(dispenseId, quantity); - } -} diff --git a/com/openhis/web/inpatient/mapper/DispenseMapper.java b/com/openhis/web/inpatient/mapper/DispenseMapper.java deleted file mode 100644 index 22260dc38..000000000 --- a/com/openhis/web/inpatient/mapper/DispenseMapper.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import org.apache.ibatis.annotations.Insert; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Update; - -/** - * 住院发退药数据访问层 - * - * 为了解决 Bug #503,新增两条 SQL: - * 1. {@link #insertDetail(Long, Integer)} – 写入发/退药明细。 - * 2. {@link #updateSummaryAfterDetail(Long, Integer)} – 在同一事务内同步更新 - * 汇总单的累计数量、状态等字段,确保明细与汇总单的触发时机保持一致。 - */ -@Mapper -public interface DispenseMapper { - - /** - * 插入发药(或退药)明细记录。 - * - * @param dispenseId 发药单主键 - * @param quantity 本次(正数为发药,负数为退药)数量 - */ - @Insert("INSERT INTO his_inpatient_dispense_detail (dispense_id, quantity, create_time) " + - "VALUES (#{dispenseId}, #{quantity}, NOW())") - void insertDetail(@Param("dispenseId") Long dispenseId, - @Param("quantity") Integer quantity); - - /** - * 同步更新汇总单统计信息。 - * - * 业务说明: - * - 汇总单表 his_inpatient_dispense_summary 中维护累计发药数量 total_quantity - * 以及发药状态 status(NONE、PARTIAL、COMPLETED)。 - * - 本方法在同事务内执行,使用传入的 quantity(正数/负数)直接累加到 total_quantity, - * 并根据累计值与订单需求量进行状态判定,避免原来通过异步任务或触发器延迟更新导致的时机不一致。 - * - * @param dispenseId 发药单主键 - * @param quantity 本次(正数为发药,负数为退药)数量 - */ - @Update({ - "" - }) - void updateSummaryAfterDetail(@Param("dispenseId") Long dispenseId, - @Param("quantity") Integer quantity); -} diff --git a/com/openhis/web/inpatient/mapper/DispensingDetailMapper.java b/com/openhis/web/inpatient/mapper/DispensingDetailMapper.java deleted file mode 100644 index 577c1911f..000000000 --- a/com/openhis/web/inpatient/mapper/DispensingDetailMapper.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import org.apache.ibatis.annotations.*; - -import java.util.List; -import java.util.Map; - -/** - * 发药明细 Mapper - * - * 新增 batchInsertDetail 方法,统一使用 Map 参数,便于前端传递任意字段。 - */ -@Mapper -public interface DispensingDetailMapper { - - /** - * 批量插入发药明细。 - * - * @param prescriptionId 处方主键 - * @param detailList 明细数据列表,每条记录必须包含: - * - drug_id - * - quantity - * - amount - * - type(DISPENSE / RETURN) - * @return 实际插入的记录数 - */ - @Insert({ - "" - }) - int batchInsertDetail(@Param("prescriptionId") Long prescriptionId, - @Param("detailList") List> detailList); -} diff --git a/com/openhis/web/inpatient/mapper/DispensingMapper.java b/com/openhis/web/inpatient/mapper/DispensingMapper.java deleted file mode 100644 index e62376c2f..000000000 --- a/com/openhis/web/inpatient/mapper/DispensingMapper.java +++ /dev/null @@ -1,61 +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.Update; -import org.apache.ibatis.annotations.Insert; - -/** - * 住院发药/退药数据访问层 - * - * 关键新增/修改方法: - * 1. initDispensingRecord(Long orderId, String submitStatus) - * - 插入发药明细记录,并将 submit_status 设置为 UNAPPLIED 或 APPLIED。 - * 2. generateSummaryRecord(Long orderId) - * - 根据明细生成(或更新)汇总单,submit_status 必须为 APPLIED。 - * 3. updateDispensingDetailStatus(Long orderId, String submitStatus) - * - 在“汇总申请”时把明细状态从 UNAPPLIED 改为 APPLIED。 - * - * 这些方法配合 InpatientDispensingServiceImpl 实现了 Bug #503 的修复。 - */ -@Mapper -public interface DispensingMapper { - - /** - * 更新医嘱执行状态为已执行。 - */ - @Update("UPDATE his_inpatient_order SET exec_status = #{status} WHERE id = #{orderId}") - int updateOrderExecStatus(@Param("orderId") Long orderId, @Param("status") String status); - - /** - * 初始化发药明细记录。 - * - * @param orderId 医嘱ID - * @param submitStatus 初始提交状态:UNAPPLIED 或 APPLIED - */ - @Insert("INSERT INTO dispensing_detail (order_id, submit_status, create_time) " + - "VALUES (#{orderId}, #{submitStatus}, NOW())") - int initDispensingRecord(@Param("orderId") Long orderId, @Param("submitStatus") String submitStatus); - - /** - * 在自动模式或汇总申请后生成/更新汇总单。 - * - * @param orderId 医嘱ID - */ - @Insert("INSERT INTO dispensing_summary (order_id, submit_status, create_time) " + - "SELECT #{orderId}, 'APPLIED', NOW() " + - "FROM dual " + - "ON DUPLICATE KEY UPDATE submit_status = 'APPLIED', update_time = NOW()") - int generateSummaryRecord(@Param("orderId") Long orderId); - - /** - * 汇总申请时,将明细的 submit_status 更新为 APPLIED。 - * - * @param orderId 医嘱ID - * @param submitStatus 目标状态,固定为 'APPLIED' - */ - @Update("UPDATE dispensing_detail SET submit_status = #{submitStatus} " + - "WHERE order_id = #{orderId}") - int updateDispensingDetailStatus(@Param("orderId") Long orderId, - @Param("submitStatus") String submitStatus); -} diff --git a/com/openhis/web/inpatient/mapper/DispensingSummaryMapper.java b/com/openhis/web/inpatient/mapper/DispensingSummaryMapper.java deleted file mode 100644 index 5eb1ddabc..000000000 --- a/com/openhis/web/inpatient/mapper/DispensingSummaryMapper.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import org.apache.ibatis.annotations.*; - -import java.util.Map; - -/** - * 发药汇总单 Mapper - * - * 新增: - * 1. {@code recalculateSummaryByPrescriptionId}:基于明细表重新计算汇总信息,并使用 FOR UPDATE 锁定行。 - * 2. {@code insertInitialSummary}:在首次发药时插入空的汇总记录,防止后续更新失败。 - */ -@Mapper -public interface DispensingSummaryMapper { - - /** - * 重新计算指定处方的发药汇总信息。 - * - * 该 SQL 会: - * - 对 his_dispensing_detail 按 prescription_id 汇总数量、金额等。 - * - 使用 SELECT ... FOR UPDATE 锁定对应的 his_dispensing_summary 行,确保并发安全。 - * - 更新汇总表的 total_quantity、total_amount、status 等字段。 - * - * @param prescriptionId 处方主键 - * @return 更新的记录数(通常为 1) - */ - @Update({ - "" - }) - int recalculateSummaryByPrescriptionId(@Param("prescriptionId") Long prescriptionId); - - /** - * 首次发药时插入一条空的汇总记录。 - * - * @param prescriptionId 处方主键 - */ - @Insert("INSERT INTO his_dispensing_summary (prescription_id, total_quantity, total_amount, status) " + - "VALUES (#{prescriptionId}, 0, 0, 'INIT')") - void insertInitialSummary(@Param("prescriptionId") Long prescriptionId); -} diff --git a/com/openhis/web/inpatient/service/DispensingService.java b/com/openhis/web/inpatient/service/DispensingService.java deleted file mode 100644 index b4005c831..000000000 --- a/com/openhis/web/inpatient/service/DispensingService.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.openhis.web.inpatient.service; - -import java.util.List; -import java.util.Map; - -/** - * 住院发退药业务接口 - */ -public interface DispensingService { - - /** - * 发药或退药核心业务,确保明细与汇总单同步。 - * - * @param prescriptionId 处方ID - * @param detailList 本次操作的明细列表 - */ - void dispense(Long prescriptionId, List> detailList); -} diff --git a/com/openhis/web/inpatient/service/impl/DispenseServiceImpl.java b/com/openhis/web/inpatient/service/impl/DispenseServiceImpl.java deleted file mode 100644 index 1c0d73d42..000000000 --- a/com/openhis/web/inpatient/service/impl/DispenseServiceImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.inpatient.mapper.DispenseMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Map; - -/** - * 住院发退药业务实现 - * - * 修复 Bug #503: - * 住院发药时,发药明细(his_inpatient_dispense_detail)与发药汇总单 - * (his_inpatient_dispense_summary)的数据写入时机不一致,导致先写入明细后 - * 触发汇总单生成的异步任务未能及时感知,出现业务脱节风险。 - * - * 解决思路: - * 1. 将明细写入、汇总单生成、汇总单状态更新全部放在同一个事务中完成; - * 2. 在写入明细后立即调用 {@link DispenseMapper#updateSummaryAfterDetail(Long, Integer)} - * 通过 SQL 直接在同事务内完成汇总统计,避免异步延迟; - * 3. 对外统一返回业务成功/失败结构,保持与其它接口风格一致。 - */ -@Service -public class DispenseServiceImpl { - - private final DispenseMapper dispenseMapper; - - public DispenseServiceImpl(DispenseMapper dispenseMapper) { - this.dispenseMapper = dispenseMapper; - } - - /** - * 发药(包括明细写入与汇总单同步更新)。 - * - * @param dispenseId 发药单主键 - * @param quantity 本次发药数量 - * @return 业务结果映射,key 为 code(0 成功,1 失败),msg 为提示信息 - */ - @Transactional(rollbackFor = Exception.class) - public Map dispense(Long dispenseId, Integer quantity) { - // 1. 写入发药明细 - dispenseMapper.insertDetail(dispenseId, quantity); - - // 2. 同步更新汇总单统计(在同事务内完成,确保时机一致) - dispenseMapper.updateSummaryAfterDetail(dispenseId, quantity); - - // 3. 返回统一结构 - return Map.of("code", 0, "msg", "发药成功"); - } - - /** - * 退药(明细与汇总同步回滚)。 - * - * @param dispenseId 发药单主键 - * @param quantity 本次退药数量 - * @return 业务结果映射 - */ - @Transactional(rollbackFor = Exception.class) - public Map returnDrug(Long dispenseId, Integer quantity) { - // 1. 写入退药明细(负数表示退药) - int returnQty = -Math.abs(quantity); - dispenseMapper.insertDetail(dispenseId, returnQty); - - // 2. 同步更新汇总单统计(在同事务内完成,确保时机一致) - dispenseMapper.updateSummaryAfterDetail(dispenseId, returnQty); - - // 3. 返回统一结构 - return Map.of("code", 0, "msg", "退药成功"); - } -} diff --git a/com/openhis/web/inpatient/service/impl/DispensingServiceImpl.java b/com/openhis/web/inpatient/service/impl/DispensingServiceImpl.java deleted file mode 100644 index d33f9c9cb..000000000 --- a/com/openhis/web/inpatient/service/impl/DispensingServiceImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.inpatient.mapper.DispensingDetailMapper; -import com.openhis.web.inpatient.mapper.DispensingSummaryMapper; -import com.openhis.web.inpatient.service.DispensingService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * 住院发退药业务实现 - * - * 修复 Bug #503: - * 发药明细(DispensingDetail)与发药汇总单(DispensingSummary)在数据触发时机不一致, - * 可能导致明细已写入而汇总单仍保持旧状态,产生业务脱节风险。 - * - * 解决思路: - * 1. 将明细写入与汇总单更新放在同一个事务中,确保原子性。 - * 2. 在插入明细后立即调用 {@link DispensingSummaryMapper#recalculateSummaryByPrescriptionId} - * 重新计算该处方的汇总信息(总数量、总金额、状态等)。 - * 3. 为防止并发导致的脏读,使用数据库行级锁(FOR UPDATE)在汇总计算时锁定对应的汇总记录。 - * - * 这样可以保证:每一次发药/退药操作,明细与汇总单的数据始终保持同步。 - */ -@Service -public class DispensingServiceImpl implements DispensingService { - - private final DispensingDetailMapper detailMapper; - private final DispensingSummaryMapper summaryMapper; - - public DispensingServiceImpl(DispensingDetailMapper detailMapper, - DispensingSummaryMapper summaryMapper) { - this.detailMapper = detailMapper; - this.summaryMapper = summaryMapper; - } - - /** - * 发药(或退药)核心业务 - * - * @param prescriptionId 处方主键 - * @param detailList 本次操作的明细列表 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void dispense(Long prescriptionId, List> detailList) { - if (prescriptionId == null || detailList == null || detailList.isEmpty()) { - throw new IllegalArgumentException("参数非法:处方ID和明细列表不能为空"); - } - - // 1. 批量插入发药明细 - int inserted = detailMapper.batchInsertDetail(prescriptionId, detailList); - if (inserted != detailList.size()) { - throw new RuntimeException("发药明细插入数量不匹配,expected=" + detailList.size() + ", actual=" + inserted); - } - - // 2. 立即重新计算并更新汇总单 - // 此方法内部使用 SELECT ... FOR UPDATE 锁定对应的汇总记录,防止并发冲突。 - int updated = summaryMapper.recalculateSummaryByPrescriptionId(prescriptionId); - if (updated == 0) { - // 汇总记录可能不存在,首次发药时需要插入一条新记录 - summaryMapper.insertInitialSummary(prescriptionId); - // 再次计算 - summaryMapper.recalculateSummaryByPrescriptionId(prescriptionId); - } - } -} diff --git a/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java b/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java deleted file mode 100644 index c78dd12b0..000000000 --- a/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.outpatient.mapper.OrderMapper; -import com.openhis.web.inpatient.mapper.DispenseMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 住院医嘱校对业务实现 - * - * 修复 Bug #505: - * - 增加前置状态校验,拦截已执行或已发药的药品医嘱直接退回。 - * - 在退回成功后,确保对应的发药汇总单状态回滚为 “未完成”,防止状态不一致。 - * - * 同时配合 {@link DispenseMapper#updateDispenseSummaryStatus} 解决 Bug #503。 - */ -@Service -public class OrderVerifyServiceImpl { - - private final OrderMapper orderMapper; - private final DispenseMapper dispenseMapper; - - public OrderVerifyServiceImpl(OrderMapper orderMapper, - DispenseMapper dispenseMapper) { - this.orderMapper = orderMapper; - this.dispenseMapper = dispenseMapper; - } - - /** - * 批量退回已校对医嘱 - * - * @param orderIds 医嘱ID列表 - */ - @Transactional(rollbackFor = Exception.class) - public void returnOrders(List orderIds) { - if (orderIds == null || orderIds.isEmpty()) { - throw new IllegalArgumentException("退回医嘱列表不能为空"); - } - - for (Long orderId : orderIds) { - Map order = orderMapper.selectOrderById(orderId); - if (order == null) { - throw new IllegalArgumentException("医嘱不存在,ID=" + orderId); - } - - String execStatus = String.valueOf(order.get("exec_status")); - String dispenseStatus = String.valueOf(order.get("dispense_status")); - - // 核心状态约束校验:执行状态或物理发药状态已流转,严禁直接退回 - if ("EXECUTED".equals(execStatus) || "DISPENSED".equals(dispenseStatus)) { - throw new RuntimeException("该药品已由药房发放,请先执行退药处理,不可直接退回"); - } - - // 执行退回操作:更新医嘱状态为已退回 - orderMapper.updateOrderStatus(orderId, "RETURNED"); - - // 若该医嘱已生成发药汇总单(状态可能为未完成),需要将其状态恢复为未完成,以保持一致性 - dispenseMapper.updateDispenseSummaryStatus(orderId, "PENDING"); - } - } -} diff --git a/com/openhis/web/outpatient/controller/LabApplyController.java b/com/openhis/web/outpatient/controller/LabApplyController.java deleted file mode 100644 index fa8ba8f4b..000000000 --- a/com/openhis/web/outpatient/controller/LabApplyController.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.openhis.web.outpatient.controller; - -import com.openhis.web.outpatient.service.impl.LabApplyServiceImpl; -import org.springframework.web.bind.annotation.*; - -import java.util.HashMap; -import java.util.Map; - -/** - * 检验申请(实验室)控制层 - * - * 修复 Bug #571:为撤回接口返回统一的成功/错误结构,并捕获业务异常以返回前端可读的错误信息。 - */ -@RestController -@RequestMapping("/api/lab-apply") -public class LabApplyController { - - private final LabApplyServiceImpl labApplyService; - - public LabApplyController(LabApplyServiceImpl labApplyService) { - this.labApplyService = labApplyService; - } - - /** - * 撤回检验申请 - * - * @param applyId 检验申请 ID - * @return {code:0, msg:"撤回成功"} 或 {code:1, msg:"错误信息"} - */ - @PostMapping("/withdraw") - public Map withdraw(@RequestParam Long applyId) { - Map resp = new HashMap<>(); - try { - labApplyService.withdrawApply(applyId); - resp.put("code", 0); - resp.put("msg", "撤回成功"); - } catch (RuntimeException ex) { - resp.put("code", 1); - resp.put("msg", ex.getMessage()); - } catch (Exception ex) { - resp.put("code", 1); - resp.put("msg", "系统异常,请联系管理员"); - } - return resp; - } - - // 其他接口保持不变 -} diff --git a/com/openhis/web/outpatient/mapper/LabApplyMapper.java b/com/openhis/web/outpatient/mapper/LabApplyMapper.java deleted file mode 100644 index c3ea4d370..000000000 --- a/com/openhis/web/outpatient/mapper/LabApplyMapper.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.openhis.web.outpatient.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.List; -import java.util.Map; - -/** - * 检验申请(实验室)数据访问层 - * - * 修复 Bug #571: - * 在检验申请执行“撤回”操作时,原实现直接调用 {@link #updateStatus(Long, String)} 并硬编码 - * 为 'RETURNED',导致前端提示 “撤回失败,请检查状态”。实际业务中撤回应将状态改为 - * PRD 中统一定义的 “CANCELLED”。同时需要在撤回前校验当前状态只能是 “APPLIED”(已申请) 或 - * “PENDING”(待处理),否则抛出明确异常,前端可捕获并展示友好提示。 - * - * 为此做了以下改动: - * 1. 新增常量 {@link #STATUS_CANCELLED},统一使用 PRD 中的取消状态码。 - * 2. 新增方法 {@link #withdrawLabApply(Long)},在内部完成状态合法性校验并将状态更新为 - * {@link #STATUS_CANCELLED}。 - * 3. 将原有的 {@code updateStatus} 方法的 Javadoc 说明为通用状态更新,供内部使用。 - */ -@Mapper -public interface LabApplyMapper { - - /** 检验申请已撤回(取消)状态 */ - String STATUS_CANCELLED = "CANCELLED"; - - /** 检验申请已申请状态(可撤回) */ - String STATUS_APPLIED = "APPLIED"; - - /** 检验申请待处理状态(可撤回) */ - String STATUS_PENDING = "PENDING"; - - /** - * 根据 ID 查询检验申请的完整信息(用于状态校验)。 - * - * @param applyId 检验申请主键 - * @return 包含所有字段的 Map,若不存在返回 null - */ - @Select("SELECT * FROM his_lab_apply WHERE id = #{applyId}") - Map selectApplyById(@Param("applyId") Long applyId); - - /** - * 通用状态更新(内部使用)。 - * - * @param applyId 检验申请主键 - * @param status 新状态码 - */ - @Update("UPDATE his_lab_apply SET status = #{status}, update_time = NOW() WHERE id = #{applyId}") - void updateStatus(@Param("applyId") Long applyId, @Param("status") String status); - - /** - * 撤回检验申请。 - * - *

业务规则: - *

    - *
  • 仅当当前状态为 {@link #STATUS_APPLIED} 或 {@link #STATUS_PENDING} 时允许撤回。
  • - *
  • 撤回后状态统一设为 {@link #STATUS_CANCELLED}。
  • - *
  • 若状态不符合要求,抛出 RuntimeException,前端可捕获并展示错误提示。
  • - *
- * - * @param applyId 检验申请主键 - */ - default void withdrawLabApply(Long applyId) { - Map apply = selectApplyById(applyId); - if (apply == null) { - throw new RuntimeException("检验申请不存在"); - } - String currentStatus = (String) apply.get("status"); - if (!STATUS_APPLIED.equals(currentStatus) && !STATUS_PENDING.equals(currentStatus)) { - throw new RuntimeException("仅在已申请或待处理状态下才能撤回,当前状态为 " + currentStatus); - } - // 更新为取消状态 - updateStatus(applyId, STATUS_CANCELLED); - } - - // 其他已有查询方法保持不变 - @Select("SELECT id, patient_id, item_name, status, apply_time FROM his_lab_apply WHERE patient_id = #{patientId}") - List> selectByPatientId(@Param("patientId") Long patientId); -} diff --git a/com/openhis/web/outpatient/mapper/OrderMapper.java b/com/openhis/web/outpatient/mapper/OrderMapper.java deleted file mode 100644 index 48d0f0b36..000000000 --- a/com/openhis/web/outpatient/mapper/OrderMapper.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.openhis.web.outpatient.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.List; -import java.util.Map; - -/** - * 医嘱(订单)数据访问层 - * - * 修复说明: - * 住院发退药业务中,发药明细(his_dispense_detail)与发药汇总单(his_dispense_summary)在 - * 同一事务内完成,但原有的 SQL 只更新了明细表,导致汇总单的状态延迟更新,出现 - * “发药明细触发时机早于发药汇总单” 的业务脱节风险(Bug #503)。 - * - * 为了保证两张表的状态同步更新,新增了统一的批量更新方法 {@link #updateDispenseStatusBatch} - * 通过一次 SQL 同时更新明细表和汇总表的状态、操作人及更新时间。业务层只需调用该方法即可 - * 保证数据一致性。 - * - * 同时保留原有的单表更新方法,以兼容其他业务场景。 - */ -@Mapper -public interface OrderMapper { - - /** PRD 中定义的医嘱取消状态 */ - String ORDER_STATUS_CANCELLED = "CANCELLED"; - - /** PRD 中定义的已支付状态 */ - String ORDER_STATUS_PAID = "PAID"; - - /** PRD 中定义的已退回状态 */ - String ORDER_STATUS_RETURNED = "RETURNED"; - - /** - * 根据医嘱 ID 查询完整医嘱信息(用于状态校验)。 - * - * @param orderId 医嘱主键 - * @return 包含医嘱所有字段的 Map,若不存在返回 null - */ - @Select("SELECT * FROM his_order WHERE id = #{orderId}") - Map selectOrderById(@Param("orderId") Long orderId); - - /** - * 将医嘱状态更新为指定状态(常用于 CANCELLED、PAID、RETURNED 等)。 - * - * @param orderId 医嘱主键 - * @param status 目标状态,建议使用常量 {@link #ORDER_STATUS_CANCELLED}、{@link #ORDER_STATUS_PAID} 等 - * @param operator 操作人姓名 - */ - @Update("UPDATE his_order SET status = #{status}, updated_by = #{operator}, updated_time = NOW() " + - "WHERE id = #{orderId}") - int updateOrderStatus(@Param("orderId") Long orderId, - @Param("status") String status, - @Param("operator") String operator); - - /** - * 批量更新住院发药明细表和发药汇总单表的状态、操作人及更新时间。 - * - * 业务说明: - * - 当发药完成或退药时,需要同时修改 his_dispense_detail 与 his_dispense_summary 两张表。 - * - 通过一次 SQL 同时更新两张表,避免因事务提交顺序导致的状态不一致。 - * - * @param dispenseIds 需要更新的发药明细 ID 列表(对应 his_dispense_detail.id) - * @param summaryIds 对应的发药汇总单 ID 列表(对应 his_dispense_summary.id) - * @param status 目标状态,例如 'DISPENSED'、'RETURNED' 等 - * @param operator 操作人姓名 - * @return 受影响的行数(明细表 + 汇总表) - */ - @Update({ - "" - }) - int updateDispenseStatusBatch(@Param("dispenseIds") List dispenseIds, - @Param("summaryIds") List summaryIds, - @Param("status") String status, - @Param("operator") String operator); - - // 其余已有方法保持不变 -} diff --git a/com/openhis/web/outpatient/mapper/RegistrationCancelMapper.java b/com/openhis/web/outpatient/mapper/RegistrationCancelMapper.java deleted file mode 100644 index 9b61d73e4..000000000 --- a/com/openhis/web/outpatient/mapper/RegistrationCancelMapper.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.Insert; -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.math.BigDecimal; -import java.util.Map; - -/** - * 门诊退号数据访问层 - * 修复 Bug #506:修正退号流程中多表状态更新 SQL,对齐 PRD 定义 - * - * 新增: - * 1. updatePoolAfterCancel – 退号后更新排班池的 version 与 booked_num。 - * 2. insertRefundLog – 记录退费日志,确保 refund_log 表状态与 PRD 定义保持一致。 - */ -@Mapper -public interface RegistrationCancelMapper { - - /** - * 查询号源关联的排班池ID - */ - @Select("SELECT id, pool_id, status, order_id FROM adm_schedule_slot WHERE order_id = #{orderId} LIMIT 1") - Map selectSlotByOrderId(@Param("orderId") Long orderId); - - /** - * 更新订单主表状态 - * 修复点:status=0, pay_status=3, cancel_time=NOW(), cancel_reason='诊前退号' - */ - @Update("UPDATE order_main " + - "SET status = 0, " + - " pay_status = 3, " + - " cancel_time = NOW(), " + - " cancel_reason = '诊前退号' " + - "WHERE id = #{orderId}") - int updateOrderStatus(@Param("orderId") Long orderId); - - /** - * 回滚号源状态 - * 修复点:status=0(待约), order_id=NULL,释放号源供再次预约 - */ - @Update("UPDATE adm_schedule_slot " + - "SET status = 0, " + - " order_id = NULL " + - "WHERE order_id = #{orderId}") - int rollbackSlotStatus(@Param("orderId") Long orderId); - - /** - * 更新排班池版本与已约数 - * 修复点:version=version+1, booked_num=booked_num-1 - */ - @Update("UPDATE adm_schedule_pool " + - "SET version = version + 1, " + - " booked_num = booked_num - 1 " + - "WHERE id = #{poolId}") - int updatePoolAfterCancel(@Param("poolId") Long poolId); - - /** - * 插入退费日志 - */ - @Insert("INSERT INTO refund_log (order_id, refund_amount, refund_time, remark) " + - "VALUES (#{orderId}, #{refundAmount}, NOW(), #{remark})") - int insertRefundLog(@Param("orderId") Long orderId, - @Param("refundAmount") BigDecimal refundAmount, - @Param("remark") String remark); -} diff --git a/com/openhis/web/outpatient/mapper/RegistrationMapper.java b/com/openhis/web/outpatient/mapper/RegistrationMapper.java deleted file mode 100644 index 5382bdd3c..000000000 --- a/com/openhis/web/outpatient/mapper/RegistrationMapper.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Update; -import org.apache.ibatis.annotations.Select; - -import java.util.List; -import java.util.Map; - -/** - * 挂号(排班)数据访问层 - * - * 主要修复: - * - 新增方法 {@link #updateSlotStatusToPaid(Long)},在预约签到缴费成功后 - * 将对应的 {@code adm_schedule_slot.status} 状态更新为 “3”(已取号)。 - * - 该方法在 {@link com.openhis.web.outpatient.service.impl.RegistrationServiceImpl#handlePaymentSuccess(Long)} - * 中被调用,用以修复 Bug #574。 - * - * 其他已有方法保持不变,仅在此文件中补充新方法的声明与实现。 - */ -@Mapper -public interface RegistrationMapper { - - // ----------------------------------------------------------------- - // 现有的查询/更新方法(省略具体实现,仅保留占位以示完整结构) - // ----------------------------------------------------------------- - @Select("SELECT * FROM adm_schedule_slot WHERE id = #{slotId}") - Map selectSlotById(@Param("slotId") Long slotId); - - @Update("UPDATE adm_schedule_pool SET booked_num = booked_num + 1 WHERE id = #{poolId}") - int incrementBookedNumByOrderId(@Param("poolId") Long poolId); - - // ----------------------------------------------------------------- - // 新增:支付成功后更新排班槽状态为已取号(status = 3) - // ----------------------------------------------------------------- - /** - * 将指定的排班槽(adm_schedule_slot)状态更新为 “3”(已取号)。 - * - * @param slotId 排班槽主键 - * @return 受影响的行数,正常情况下应为 1 - */ - @Update("UPDATE adm_schedule_slot SET status = 3 WHERE id = #{slotId}") - int updateSlotStatusToPaid(@Param("slotId") Long slotId); - - // ----------------------------------------------------------------- - // 其他可能的已有方法(保持原样) - // ----------------------------------------------------------------- - // List> selectAvailableSlots(...); - // int cancelSlot(...); -} diff --git a/com/openhis/web/outpatient/mapper/TriageMapper.java b/com/openhis/web/outpatient/mapper/TriageMapper.java deleted file mode 100644 index da1abe71b..000000000 --- a/com/openhis/web/outpatient/mapper/TriageMapper.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.openhis.web.outpatient.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 #544: - * 1. 原查询仅排除 “已完诊”(FINISHED) 状态,导致列表中不显示已完诊患者,实际业务需要在“排队队列列表”中 - * 同时展示 “待诊”(WAITING) 与 “已完诊”(FINISHED) 两种状态的患者,以便医生快速回顾。 - * 2. 原系统缺失历史队列查询接口,导致前端“历史队列查询”功能不可用。 - * - * 为此做了以下改动: - * - 将 {@link #selectCurrentQueue(Long)} 查询条件由 `status != 'FINISHED'` 改为 `status IN ('WAITING','FINISHED')`, - * 这样既能展示待诊患者,也能展示已完诊患者。 - * - 新增 {@link #selectQueueHistory(Long, String, String)} 方法,支持按患者 ID 与时间范围查询历史排队记录, - * 前端可用于历史队列查询功能。 - * - * 注意: - * - 状态值均使用 PRD 中统一定义的常量,避免硬编码。 - * - 为兼容旧代码,仍保留原有的 `selectCurrentQueue` 方法签名,仅修改其实现逻辑。 - */ -@Mapper -public interface TriageMapper { - - /** PRD 中定义的排队状态:待诊 */ - String STATUS_WAITING = "WAITING"; - - /** PRD 中定义的排队状态:已完诊 */ - String STATUS_FINISHED = "FINISHED"; - - /** - * 查询当前排队列表(包括待诊和已完诊患者)。 - * - * @param patientId 患者主键(可为 null,表示查询全部患者的排队信息) - * @return 每条排队记录的 Map,关键字段包括 id、patient_id、status、queue_time 等 - */ - @Select({ - "" - }) - List> selectCurrentQueue(@Param("patientId") Long patientId); - - /** - * 查询患者的历史排队记录(已完诊记录)。 - * - * @param patientId 患者主键,必填 - * @param startTime 起始时间(包含),格式:yyyy-MM-dd HH:mm:ss,若为空则不限制下限 - * @param endTime 结束时间(包含),格式:yyyy-MM-dd HH:mm:ss,若为空则不限制上限 - * @return 符合条件的历史排队记录列表,按完成时间倒序排列 - */ - @Select({ - "" - }) - List> selectQueueHistory(@Param("patientId") Long patientId, - @Param("startTime") String startTime, - @Param("endTime") String endTime); -} diff --git a/com/openhis/web/outpatient/service/RegistrationService.java b/com/openhis/web/outpatient/service/RegistrationService.java deleted file mode 100644 index 207da0ca5..000000000 --- a/com/openhis/web/outpatient/service/RegistrationService.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.openhis.web.outpatient.service; - -/** - * 门诊挂号业务接口 - */ -public interface RegistrationService { - - /** - * 处理预约挂号缴费成功后的后置业务。 - * - * @param orderId 医嘱(订单)ID - * @param slotId 对应的排班号ID(adm_schedule_slot.id),用于状态流转 - */ - void handlePaymentSuccess(Long orderId, Long slotId); -} diff --git a/com/openhis/web/outpatient/service/impl/LabApplyServiceImpl.java b/com/openhis/web/outpatient/service/impl/LabApplyServiceImpl.java deleted file mode 100644 index bba97782b..000000000 --- a/com/openhis/web/outpatient/service/impl/LabApplyServiceImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.LabApplyMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * 检验申请业务实现 - * - * 修复 Bug #571: - * 原来的撤回实现直接调用 {@code updateStatus(applyId, "RETURNED")},状态码与 PRD 不匹配, - * 并且缺少对当前状态的校验,导致在已执行、已报告等状态下仍能撤回,引发系统异常。 - * - * 现在通过调用 {@link LabApplyMapper#withdrawLabApply(Long)} 完成撤回,确保: - *
    - *
  • 仅在可撤回的状态(APPLIED、PENDING)下执行。
  • - *
  • 撤回后统一使用 PRD 定义的 CANCELLED 状态。
  • - *
  • 异常信息更加友好,前端可直接展示。
  • - *
- */ -@Service -public class LabApplyServiceImpl { - - private final LabApplyMapper labApplyMapper; - - public LabApplyServiceImpl(LabApplyMapper labApplyMapper) { - this.labApplyMapper = labApplyMapper; - } - - /** - * 撤回检验申请。 - * - * @param applyId 检验申请主键 - */ - @Transactional(rollbackFor = Exception.class) - public void withdrawApply(Long applyId) { - // LabApplyMapper 已经在内部完成状态校验并抛出异常 - labApplyMapper.withdrawLabApply(applyId); - } - - // 其余业务方法保持不变 -} diff --git a/com/openhis/web/outpatient/service/impl/RegistrationCancelServiceImpl.java b/com/openhis/web/outpatient/service/impl/RegistrationCancelServiceImpl.java deleted file mode 100644 index ff4d491f8..000000000 --- a/com/openhis/web/outpatient/service/impl/RegistrationCancelServiceImpl.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.RegistrationCancelMapper; -import com.openhis.web.outpatient.service.RegistrationCancelService; -import com.openhis.web.inpatient.mapper.OrderMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.Map; - -/** - * 门诊挂号退号业务实现 - * 修复 Bug #506:确保退号后 order_main、adm_schedule_slot、adm_schedule_pool、refund_log 状态与 PRD 严格一致 - * 以及在退号后统一调用 {@link OrderMapper#updateOrderStatusToCancelled} 将医嘱状态置为 PRD 定义的 “CANCELLED”。 - */ -@Service -public class RegistrationCancelServiceImpl implements RegistrationCancelService { - - private final RegistrationCancelMapper cancelMapper; - private final OrderMapper orderMapper; - - public RegistrationCancelServiceImpl(RegistrationCancelMapper cancelMapper, - OrderMapper orderMapper) { - this.cancelMapper = cancelMapper; - this.orderMapper = orderMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void cancelRegistration(Long orderId, BigDecimal refundAmount) { - if (orderId == null) { - throw new IllegalArgumentException("订单ID不能为空"); - } - - // 1. 更新 order_main 状态:status=0(已取消), pay_status=3(已退费), cancel_time=当前时间, cancel_reason='诊前退号' - int orderUpdated = cancelMapper.updateOrderStatus(orderId); - if (orderUpdated == 0) { - throw new RuntimeException("订单状态更新失败,请检查订单是否存在或已退号"); - } - - // 2. 将关联的医嘱状态更新为 PRD 定义的 “CANCELLED” - int orderStatusUpdated = orderMapper.updateOrderStatusToCancelled(orderId, OrderMapper.ORDER_STATUS_CANCELLED); - if (orderStatusUpdated == 0) { - throw new RuntimeException("医嘱状态更新为 CANCELLED 失败,请检查医嘱是否存在或已被处理"); - } - - // 3. 回滚 adm_schedule_slot 状态:status=0(待约), order_id=NULL - int slotUpdated = cancelMapper.rollbackSlotStatus(orderId); - if (slotUpdated == 0) { - throw new RuntimeException("号源回滚失败,请检查号源是否已被其他订单占用"); - } - - // 4. 更新对应的排班池(adm_schedule_pool)版本号和已约数 - Map slotInfo = cancelMapper.selectSlotByOrderId(orderId); - if (slotInfo != null && slotInfo.get("pool_id") != null) { - Long poolId = ((Number) slotInfo.get("pool_id")).longValue(); - int poolUpdated = cancelMapper.updatePoolAfterCancel(poolId); - if (poolUpdated == 0) { - throw new RuntimeException("排班池信息更新失败,请检查 pool_id 是否正确"); - } - } - - // 5. 记录退费日志 - int logInserted = cancelMapper.insertRefundLog(orderId, refundAmount, "诊前退号退款"); - if (logInserted == 0) { - throw new RuntimeException("退费日志插入失败"); - } - - // 6. 如有需要,可在此处加入对支付成功后号源状态流转为“已取”(status=3)的处理(已在 Mapper 中预留方法)。 - } -} diff --git a/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java b/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java deleted file mode 100644 index d41c8adc6..000000000 --- a/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.OrderMapper; -import com.openhis.web.outpatient.service.RegistrationService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.HashMap; -import java.util.Map; - -/** - * 门诊挂号业务实现 - * - * 修复 Bug #506: - * 门诊诊前退号后,医嘱状态应更新为 PRD 中统一定义的 “CANCELLED”, - * 之前的实现错误地使用了硬编码的 'RETURNED',导致数据库状态与 PRD 定义不符。 - * - * 解决方案: - * 1. 引入 {@link OrderMapper#ORDER_STATUS_CANCELLED} 常量; - * 2. 调用 {@link OrderMapper#updateOrderStatusToCancelled(Long,String,String)}, - * 将医嘱状态统一更新为 “CANCELLED”,并同步更新关联的排班号状态为 “已取消”(4)。 - * - * 该实现保持在同一事务内完成,确保状态一致性。 - * - * 同时修复 Bug #574: - * 预约缴费成功后,需要将对应的排班号状态更新为 “已取号”(3)。 - * 在 {@link #payRegistration(Long, Long, String)}(支付成功后)中调用 - * {@link OrderMapper#updateScheduleSlotStatusToFinished(Long)} 完成状态流转。 - */ -@Service -public class RegistrationServiceImpl implements RegistrationService { - - private final OrderMapper orderMapper; - - public RegistrationServiceImpl(OrderMapper orderMapper) { - this.orderMapper = orderMapper; - } - - /** - * 诊前退号(取消挂号)。 - * - * @param orderId 医嘱(订单)主键 - * @param patientId 患者主键 - * @param operator 操作人姓名 - * @return 业务结果映射,key 为 code(0 成功,1 失败),msg 为提示信息 - */ - @Transactional(rollbackFor = Exception.class) - @Override - public Map cancelRegistration(Long orderId, Long patientId, String operator) { - Map result = new HashMap<>(); - try { - // 1. 将医嘱状态更新为 PRD 定义的 CANCELLED - orderMapper.updateOrderStatusToCancelled(orderId, - OrderMapper.ORDER_STATUS_CANCELLED, operator); - - // 2. 将关联的排班号状态更新为已取消(状态码 4) - // 假设 order 表中有 schedule_id 字段记录对应排班号 - Map order = orderMapper.selectOrderById(orderId); - if (order != null && order.get("schedule_id") != null) { - Long scheduleId = ((Number) order.get("schedule_id")).longValue(); - orderMapper.updateScheduleSlotStatusToCancelled(scheduleId, 4); - } - - result.put("code", 0); - result.put("msg", "退号成功"); - } catch (Exception e) { - // 事务会回滚,返回错误信息 - result.put("code", 1); - result.put("msg", "退号失败: " + e.getMessage()); - throw e; // 让事务回滚 - } - return result; - } - - // 其它业务方法(如 payRegistration)保持不变,已在 mapper 中实现对应状态更新 -} diff --git a/openhis-application/src/main/java/com/openhis/application/controller/OrderController.java b/openhis-application/src/main/java/com/openhis/application/controller/OrderController.java deleted file mode 100644 index 2723128c7..000000000 --- a/openhis-application/src/main/java/com/openhis/application/controller/OrderController.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.openhis.application.controller; - -import com.openhis.application.domain.entity.OrderMain; -import com.openhis.application.service.OrderService; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -/** - * 医嘱相关接口 - * - * 修复 Bug #562:为“待写病历”列表接口加入分页参数,前端可自行控制加载量,避免一次性返回全部数据导致加载慢。 - * - * 新增:排队队列列表接口,支持“完诊”状态显示及历史查询(Bug #544)。 - */ -@RestController -@RequestMapping("/api/orders") -public class OrderController { - - private final OrderService orderService; - - public OrderController(OrderService orderService) { - this.orderService = orderService; - } - - /** - * 获取患者待写病历的医嘱列表(分页)。 - * - * @param patientId 患者 ID - * @param pageNum 页码,默认 1 - * @param pageSize 每页记录数,默认 20 - * @return 医嘱列表 - */ - @GetMapping("/pending") - public List getPendingOrders(@RequestParam Long patientId, - @RequestParam(required = false) Integer pageNum, - @RequestParam(required = false) Integer pageSize) { - return orderService.getPendingOrders(patientId, pageNum, pageSize); - } - - /** - * 获取患者排队队列(包括已完诊)的医嘱列表(分页)。 - * - * @param patientId 患者 ID - * @param pageNum 页码,默认 1 - * @param pageSize 每页记录数,默认 20 - * @return 医嘱列表 - */ - @GetMapping("/queue") - public List getQueueOrders(@RequestParam Long patientId, - @RequestParam(required = false) Integer pageNum, - @RequestParam(required = false) Integer pageSize) { - return orderService.getQueueOrders(patientId, pageNum, pageSize); - } - - // 其它接口保持不变... -} diff --git a/openhis-application/src/main/java/com/openhis/application/controller/VitalSignController.java b/openhis-application/src/main/java/com/openhis/application/controller/VitalSignController.java deleted file mode 100644 index a4a30ab43..000000000 --- a/openhis-application/src/main/java/com/openhis/application/controller/VitalSignController.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.openhis.application.controller; - -import com.openhis.application.domain.entity.VitalSign; -import com.openhis.application.service.VitalSignService; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -/** - * 体征数据 REST 控制器 - * - * 新增 /temperatureChart/{patientId} 接口供前端体温图表使用。 - */ -@RestController -@RequestMapping("/api/vitalSign") -public class VitalSignController { - - private final VitalSignService vitalSignService; - - public VitalSignController(VitalSignService vitalSignService) { - this.vitalSignService = vitalSignService; - } - - @PostMapping("/save") - public void save(@RequestBody VitalSign vitalSign) { - vitalSignService.saveVitalSign(vitalSign); - } - - /** - * 获取体温图表数据(时间序列) - */ - @GetMapping("/temperatureChart/{patientId}") - public List getTemperatureChart(@PathVariable Long patientId) { - return vitalSignService.getTemperatureChartData(patientId); - } -} diff --git a/openhis-application/src/main/java/com/openhis/application/domain/dto/QueuePatientDto.java b/openhis-application/src/main/java/com/openhis/application/domain/dto/QueuePatientDto.java deleted file mode 100644 index 572344cfe..000000000 --- a/openhis-application/src/main/java/com/openhis/application/domain/dto/QueuePatientDto.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.openhis.application.domain.dto; - -import java.util.Date; - -/** - * 用于智能分诊页面的患者排队信息 DTO。 - * - * 包含实时排队和历史查询两种场景,字段保持一致,仅通过 {@code history} - * 标记区分。 - */ -public class QueuePatientDto { - - /** 患者唯一标识 */ - private Long patientId; - - /** 患者姓名 */ - private String patientName; - - /** 当前排队状态,取值参考 {@link com.openhis.application.constants.OrderStatus} */ - private String status; - - /** 排队号或叫号顺序 */ - private String queueNumber; - - /** 预约或挂号时间 */ - private Date registerTime; - - /** 是否为历史记录(true 表示历史查询结果) */ - private boolean history = false; - - // ---------- getters & setters ---------- - public Long getPatientId() { - return patientId; - } - - public void setPatientId(Long patientId) { - this.patientId = patientId; - } - - public String getPatientName() { - return patientName; - } - - public void setPatientName(String patientName) { - this.patientName = patientName; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getQueueNumber() { - return queueNumber; - } - - public void setQueueNumber(String queueNumber) { - this.queueNumber = queueNumber; - } - - public Date getRegisterTime() { - return registerTime; - } - - public void setRegisterTime(Date registerTime) { - this.registerTime = registerTime; - } - - public boolean isHistory() { - return history; - } - - public void setHistory(boolean history) { - this.history = history; - } -} diff --git a/openhis-application/src/main/java/com/openhis/application/domain/entity/CatalogItem.java b/openhis-application/src/main/java/com/openhis/application/domain/entity/CatalogItem.java deleted file mode 100644 index c99c5afc0..000000000 --- a/openhis-application/src/main/java/com/openhis/application/domain/entity/CatalogItem.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.openhis.application.domain.entity; - -import com.baomidou.mybatisplus.annotation.TableName; - -/** - * 诊疗目录项实体 - * - * 仅保留与本次修复相关的字段。 - */ -@TableName("his_catalog_item") -public class CatalogItem { - - private Long id; - private String itemCode; - private String itemName; - private String unit; // 计量单位 - - // ---------- getters & setters ---------- - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getItemCode() { - return itemCode; - } - - public void setItemCode(String itemCode) { - this.itemCode = itemCode; - } - - public String getItemName() { - return itemName; - } - - public void setItemName(String itemName) { - this.itemName = itemName; - } - - public String getUnit() { - return unit; - } - - public void setUnit(String unit) { - this.unit = unit; - } -} diff --git a/openhis-application/src/main/java/com/openhis/application/domain/entity/OrderDetail.java b/openhis-application/src/main/java/com/openhis/application/domain/entity/OrderDetail.java deleted file mode 100644 index 92a3679f8..000000000 --- a/openhis-application/src/main/java/com/openhis/application/domain/entity/OrderDetail.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.openhis.application.domain.entity; - -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableName; - -/** - * 医嘱明细实体 - * - * 新增 unit 字段的 getter/setter(若原有则保持不变),确保在保存时能够写入计量单位。 - */ -@TableName("his_order_detail") -public class OrderDetail { - - private Long id; - private Long orderId; - private String itemCode; - private Long itemId; - private Integer quantity; - private Double price; - - /** - * 计量单位(如 “片”, “瓶”, “次”等),来源于诊疗目录配置。 - */ - private String unit; - - // 其它字段省略 - - // ---------- getters & setters ---------- - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Long getOrderId() { - return orderId; - } - - public void setOrderId(Long orderId) { - this.orderId = orderId; - } - - public String getItemCode() { - return itemCode; - } - - public void setItemCode(String itemCode) { - this.itemCode = itemCode; - } - - public Long getItemId() { - return itemId; - } - - public void setItemId(Long itemId) { - this.itemId = itemId; - } - - public Integer getQuantity() { - return quantity; - } - - public void setQuantity(Integer quantity) { - this.quantity = quantity; - } - - public Double getPrice() { - return price; - } - - public void setPrice(Double price) { - this.price = price; - } - - public String getUnit() { - return unit; - } - - public void setUnit(String unit) { - this.unit = unit; - } -} diff --git a/openhis-application/src/main/java/com/openhis/application/mapper/CatalogItemMapper.java b/openhis-application/src/main/java/com/openhis/application/mapper/CatalogItemMapper.java deleted file mode 100644 index 9f2e9e518..000000000 --- a/openhis-application/src/main/java/com/openhis/application/mapper/CatalogItemMapper.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.CatalogItem; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -/** - * 诊疗目录项 Mapper - * - * 新增用于根据 itemCode 或主键查询目录项,以便在 OrderServiceImpl 中获取计量单位。 - */ -public interface CatalogItemMapper { - - @Select("SELECT * FROM his_catalog_item WHERE id = #{id} AND del_flag = 0") - CatalogItem selectById(@Param("id") Long id); - - @Select("SELECT * FROM his_catalog_item WHERE item_code = #{itemCode} AND del_flag = 0") - CatalogItem selectByItemCode(@Param("itemCode") String itemCode); -} diff --git a/openhis-application/src/main/java/com/openhis/application/mapper/OrderMainMapper.java b/openhis-application/src/main/java/com/openhis/application/mapper/OrderMainMapper.java deleted file mode 100644 index 90964f1b9..000000000 --- a/openhis-application/src/main/java/com/openhis/application/mapper/OrderMainMapper.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.OrderMain; -import org.apache.ibatis.annotations.*; - -import java.util.List; - -/** - * 医嘱主表 Mapper - * - * 修复 Bug #562:在门诊医生工作站“待写病历”页面,查询待写医嘱列表时未限制返回条数, - * 导致一次性查询全部历史医嘱,数据量大时响应时间超过 2 秒。 - * - * 解决方案: - * 1. 为查询方法增加分页参数(offset、limit),由业务层调用时传入合理的分页值。 - * 2. 在 SQL 中使用索引字段(patient_id、status、create_time)过滤并排序,避免全表扫描。 - * 3. 为常用查询字段在数据库建复合索引(patient_id, status, create_time), - * 这里在代码层面已明确使用这些字段,以配合数据库索引。 - * - * 新增:查询任意状态(包括“完诊”)的排队队列列表以及历史查询功能。 - */ -@Mapper -public interface OrderMainMapper { - - @Insert("INSERT INTO hisdev.order_main " + - "(patient_id, doctor_id, status, create_time, update_time) " + - "VALUES (#{patientId}, #{doctorId}, #{status}, #{createTime}, #{updateTime})") - @Options(useGeneratedKeys = true, keyProperty = "id") - int insert(OrderMain orderMain); - - /** - * 查询待写病历的医嘱列表(分页)。 - * - * @param patientId 患者 ID - * @param status 医嘱状态,'0' 表示待写 - * @param offset 分页起始位置 - * @param limit 每页记录数 - * @return 医嘱列表 - */ - @Select("") - List selectPendingByPatient(@Param("patientId") Long patientId, - @Param("status") String status, - @Param("offset") int offset, - @Param("limit") int limit); - - /** - * 新增:查询指定患者的排队队列(包括所有状态),支持分页。 - * - * @param patientId 患者 ID - * @param offset 分页起始位置 - * @param limit 每页记录数 - * @return 医嘱列表(按创建时间升序) - */ - @Select("") - List selectQueueByPatient(@Param("patientId") Long patientId, - @Param("offset") int offset, - @Param("limit") int limit); -} diff --git a/openhis-application/src/main/java/com/openhis/application/mapper/SchedulePoolMapper.java b/openhis-application/src/main/java/com/openhis/application/mapper/SchedulePoolMapper.java deleted file mode 100644 index 2e465551f..000000000 --- a/openhis-application/src/main/java/com/openhis/application/mapper/SchedulePoolMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.SchedulePool; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; -import org.apache.ibatis.annotations.Update; - -public interface SchedulePoolMapper { - - SchedulePool selectByPrimaryKey(Long id); - - int insert(SchedulePool record); - - int updateByPrimaryKey(SchedulePool record); - - /** - * 乐观锁递增 booked_num - * - * @param id 号源池主键 - * @param oldBookedNum 更新前的 booked_num 值 - * @return 受影响的行数,0 表示并发冲突 - */ - @Update("UPDATE adm_schedule_pool " + - "SET booked_num = booked_num + 1 " + - "WHERE id = #{id} AND booked_num = #{oldBookedNum}") - int updateBookedNumOptimistic(@Param("id") Long id, - @Param("oldBookedNum") Integer oldBookedNum); -} diff --git a/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignMapper.java b/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignMapper.java deleted file mode 100644 index 334211de0..000000000 --- a/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignMapper.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.VitalSign; -import org.apache.ibatis.annotations.*; - -import java.util.List; - -/** - * 体征数据 Mapper - * - * 新增 selectTemperatureChartData 用于获取体温图表所需的时间序列数据。 - */ -@Mapper -public interface VitalSignMapper { - - @Insert("INSERT INTO vital_sign (patient_id, temperature, pulse, respiration, blood_pressure, record_time, del_flag) " + - "VALUES (#{patientId}, #{temperature}, #{pulse}, #{respiration}, #{bloodPressure}, #{recordTime}, 0)") - void insert(VitalSign vitalSign); - - /** - * 查询患者的体温图表数据,按记录时间升序返回。 - * - * 只返回未被逻辑删除的记录(del_flag = 0),确保前端图表渲染时数据完整。 - */ - @Select({ - "" - }) - List selectTemperatureChartData(@Param("patientId") Long patientId); -} diff --git a/openhis-application/src/main/java/com/openhis/application/service/OrderService.java b/openhis-application/src/main/java/com/openhis/application/service/OrderService.java deleted file mode 100644 index 42fca0c4e..000000000 --- a/openhis-application/src/main/java/com/openhis/application/service/OrderService.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.entity.OrderMain; - -import java.util.List; - -/** - * 医嘱业务接口 - * - * 新增:查询排队队列(包括已完诊)以及历史查询功能。 - */ -public interface OrderService { - - /** - * 查询患者待写病历的医嘱(分页)。 - */ - List getPendingOrders(Long patientId, Integer pageNum, Integer pageSize); - - /** - * 查询患者排队队列(包括所有状态,如“完诊”),分页返回。 - * - * @param patientId 患者 ID - * @param pageNum 页码,默认 1 - * @param pageSize 每页记录数,默认 20 - * @return 医嘱列表 - */ - List getQueueOrders(Long patientId, Integer pageNum, Integer pageSize); -} diff --git a/openhis-application/src/main/java/com/openhis/application/service/VitalSignService.java b/openhis-application/src/main/java/com/openhis/application/service/VitalSignService.java deleted file mode 100644 index 92824b325..000000000 --- a/openhis-application/src/main/java/com/openhis/application/service/VitalSignService.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.entity.VitalSign; - -import java.util.List; - -/** - * 体征数据业务接口 - */ -public interface VitalSignService { - - /** - * 保存体征记录 - */ - void saveVitalSign(VitalSign vitalSign); - - /** - * 获取体温图表数据(时间序列) - * - * @param patientId 患者主键 - * @return 按时间升序的体温记录列表 - */ - List getTemperatureChartData(Long patientId); -} diff --git a/openhis-application/src/main/java/com/openhis/application/service/impl/DiagnosisServiceImpl.java b/openhis-application/src/main/java/com/openhis/application/service/impl/DiagnosisServiceImpl.java deleted file mode 100644 index a50c9dc5c..000000000 --- a/openhis-application/src/main/java/com/openhis/application/service/impl/DiagnosisServiceImpl.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.dto.DiagnosisDto; -import com.openhis.application.domain.entity.Diagnosis; -import com.openhis.application.exception.BusinessException; -import com.openhis.application.mapper.DiagnosisMapper; -import com.openhis.application.mapper.DiseaseReportTypeMapper; -import com.openhis.application.service.DiagnosisService; -import com.openhis.application.service.InfectionReportService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; - -import java.util.List; - -/** - * 诊断业务实现 - * - * 修复 Bug #573:确诊配置了“报卡类型”的疾病后,保存诊断未自动触发传染病报卡弹窗。 - * 解决方案: - * 1. 保存诊断后查询该疾病是否在 disease_report_type 表中配置了报卡类型; - * 2. 若配置了报卡类型,调用 InfectionReportService.triggerReportPopup 触发前端弹窗。 - */ -@Service -public class DiagnosisServiceImpl implements DiagnosisService { - - private static final Logger logger = LoggerFactory.getLogger(DiagnosisServiceImpl.class); - - @Autowired - private DiagnosisMapper diagnosisMapper; - - @Autowired - private DiseaseReportTypeMapper diseaseReportTypeMapper; - - @Autowired - private InfectionReportService infectionReportService; - - /** - * 保存诊断(包括主诊断和其他诊断)。 - * - * @param diagnosisDto 诊断信息 - * @throws BusinessException 业务异常 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void saveDiagnosis(DiagnosisDto diagnosisDto) throws BusinessException { - // 1. 参数校验 - if (diagnosisDto == null || diagnosisDto.getPatientId() == null) { - throw new BusinessException("诊断信息不完整"); - } - - // 2. 删除原有诊断(如果是编辑场景) - diagnosisMapper.deleteByVisitId(diagnosisDto.getVisitId()); - - // 3. 批量插入新的诊断记录 - List entities = diagnosisDto.toEntityList(); - if (!CollectionUtils.isEmpty(entities)) { - diagnosisMapper.batchInsert(entities); - } - - // -------------------------------------------------------------- - // 4. 新增:检查是否需要弹出传染病报卡弹窗 - // -------------------------------------------------------------- - try { - // 只要有一条诊断对应的疾病配置了报卡类型,即触发弹窗 - boolean needReport = entities.stream().anyMatch(d -> { - // disease_report_type 表结构假设为 (disease_id, report_type) - // report_type 为非空即表示需要报卡 - return diseaseReportTypeMapper.selectReportTypeByDiseaseId(d.getDiseaseId()) != null; - }); - - if (needReport) { - // 触发报卡弹窗,传递必要的上下文(患者ID、就诊ID、诊断列表等) - infectionReportService.triggerReportPopup(diagnosisDto.getPatientId(), - diagnosisDto.getVisitId(), - entities); - logger.info("诊断保存后触发传染病报卡弹窗,patientId={}, visitId={}", diagnosisDto.getPatientId(), - diagnosisDto.getVisitId()); - } - } catch (Exception ex) { - // 业务不应因弹窗触发失败而回滚诊断保存,记录日志即可 - logger.error("诊断保存后检查报卡类型或触发弹窗异常,patientId={}, visitId={}", - diagnosisDto.getPatientId(), diagnosisDto.getVisitId(), ex); - } - } - - // 其它诊断相关业务方法保持不变... -} diff --git a/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java b/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java deleted file mode 100644 index 84cc0ff35..000000000 --- a/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java +++ /dev/null @@ -1,128 +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.RefundStatus; -import com.openhis.application.constants.SchedulePoolStatus; -import com.openhis.application.constants.ScheduleSlotStatus; -import com.openhis.application.domain.dto.OrderVerifyDto; -import com.openhis.application.domain.dto.QueuePatientDto; -import com.openhis.application.domain.dto.OrderDetailDto; -import com.openhis.application.domain.entity.CatalogItem; -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.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 com.openhis.application.util.OrderStatusMapper; -import com.openhis.application.util.DispenseStatusMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; - -/** - * 医嘱业务实现 - * - * 注意:发药明细/汇总功能已迁移至 web/inpatient 模块的 OrderServiceImpl。 - * 此文件仅保留订单/挂号相关的基础业务逻辑。 - * - * 修复 Bug #574:预约签到缴费成功后,数据库 adm_schedule_slot.status 状态未及时流转为“已就诊”(VISITED)。 - * 原因:在订单支付成功的业务路径中,仅更新了订单主表状态,却遗漏了对对应号源(ScheduleSlot)的状态更新。 - * 解决方案:在支付成功后,统一将关联的号源状态更新为 ScheduleSlotStatus.VISITED(code=2), - * 并记录更新时间,确保前端能够正确展示“已就诊”状态。 - * - * 其他已修复的 bug 说明请参考相应提交记录。 - */ -@Service -public class OrderServiceImpl implements OrderService { - - private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class); - - @Autowired - private OrderMainMapper orderMainMapper; - @Autowired - private OrderDetailMapper orderDetailMapper; - @Autowired - private ScheduleSlotMapper scheduleSlotMapper; - @Autowired - private SchedulePoolMapper schedulePoolMapper; - // 其它 mapper 省略 ... - - // ------------------------------------------------------------------------- - // 业务方法 - // ------------------------------------------------------------------------- - - /** - * 订单支付成功后统一处理(包括订单状态、号源状态等)。 - * - * @param orderId 订单主键 ID - */ - @Transactional(rollbackFor = Exception.class) - public void handlePaySuccess(Long orderId) { - // 1. 更新订单主表状态为已支付 - OrderMain order = orderMainMapper.selectByPrimaryKey(orderId); - if (order == null) { - throw new BusinessException("订单不存在"); - } - order.setStatus(OrderStatus.PAID); - order.setPayTime(new Date()); - orderMainMapper.updateByPrimaryKeySelective(order); - logger.info("订单[{}]状态更新为已支付", orderId); - - // 2. 更新对应的号源状态为已就诊(VISITED) - if (order.getScheduleSlotId() != null) { - updateScheduleSlotToVisited(order.getScheduleSlotId()); - } else { - logger.warn("订单[{}]未关联号源,无法更新号源状态", orderId); - } - - // 3. 其它业务(如生成就诊记录、发送通知等)保持原有实现 - // ... 这里保留原有的业务逻辑代码(如果有) ... - } - - /** - * 将指定的号源(ScheduleSlot)状态更新为已就诊(VISITED)。 - * - * @param slotId 号源主键 ID - */ - private void updateScheduleSlotToVisited(Long slotId) { - ScheduleSlot slot = scheduleSlotMapper.selectByPrimaryKey(slotId); - if (slot == null) { - logger.warn("号源[{}]不存在,无法更新为已就诊", slotId); - return; - } - // 只在状态不是已就诊时才更新,防止重复写库 - if (slot.getStatus() != null && slot.getStatus().intValue() == ScheduleSlotStatus.VISITED) { - logger.debug("号源[{}]已经是已就诊状态,无需重复更新", slotId); - return; - } - slot.setStatus(ScheduleSlotStatus.VISITED); - slot.setUpdateTime(new Date()); - scheduleSlotMapper.updateByPrimaryKeySelective(slot); - logger.info("号源[{}]状态更新为已就诊(VISITED)", slotId); - } - - // ------------------------------------------------------------------------- - // 其余业务方法保持不变(原有代码省略) - // ------------------------------------------------------------------------- - - // 下面是原有的业务实现(未改动),仅保留占位以防编译错误 - // 请根据实际项目将原有方法粘贴回此处 -} diff --git a/openhis-application/src/main/java/com/openhis/application/service/impl/OrderVerificationServiceImpl.java b/openhis-application/src/main/java/com/openhis/application/service/impl/OrderVerificationServiceImpl.java deleted file mode 100644 index a2262d1e2..000000000 --- a/openhis-application/src/main/java/com/openhis/application/service/impl/OrderVerificationServiceImpl.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.mapper.OrderMainMapper; -import com.openhis.application.domain.entity.OrderMain; -import com.openhis.application.exception.BusinessException; -import com.openhis.application.dto.OrderVerificationDTO; -import com.openhis.application.mapper.OrderVerificationMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * 医嘱校对业务实现 - * - * 修复 Bug #505:药品医嘱已由药房发药,护士仍能在“医嘱校对”模块执行“退回”操作。 - * - * 业务规则: - * 1. 医嘱状态为“已发药”(status = 2) 时,禁止退回。 - * 2. 只有在“待校对”(status = 0) 或 “已校对”(status = 1) 状态下才允许退回。 - * - * 该实现通过在退回前校验医嘱状态并抛出业务异常阻止后续处理,确保业务流程符合药房发药后的不可逆性要求。 - * - * 另外,新增查询医嘱校对列表的实现,确保返回的字段与医生站医嘱要素保持一致,消除核对安全隐患。 - * - * 修复 Bug #506:门诊诊前退号后,确保相关表的状态值与生产环境定义保持一致。 - * 具体表现为:退号后,order_main、order_detail 等表的 status 必须统一更新为 “已退号”(status = 3)。 - * 之前的实现仅更新了 order_main 表,导致业务查询时状态不一致。 - * - * 现在在退号(returnOrder)流程中,统一更新主表和明细表的状态,确保所有相关表的状态同步。 - */ -@Service -public class OrderVerificationServiceImpl implements OrderVerificationService { - - private final OrderMainMapper orderMainMapper; - private final OrderVerificationMapper orderVerificationMapper; - - public OrderVerificationServiceImpl(OrderMainMapper orderMainMapper, - OrderVerificationMapper orderVerificationMapper) { - this.orderMainMapper = orderMainMapper; - this.orderVerificationMapper = orderVerificationMapper; - } - - /** - * 医嘱退回(撤销)操作 - * - * @param orderId 医嘱主表ID - * @param reason 退回原因 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void returnOrder(Long orderId, String reason) { - // 1. 查询医嘱 - OrderMain order = orderMainMapper.selectById(orderId); - if (order == null) { - throw new BusinessException("医嘱不存在"); - } - - // 2. 检查医嘱状态,仅在待校对(0)或已校对(1)时允许退回 - // 已发药(2)及其它状态均不允许退回 - Integer status = order.getStatus(); - if (status == null || (status != 0 && status != 1)) { - // 已发药或已退药等不可退回状态 - throw new BusinessException("药品已由药房发药,不能退回"); - } - - // 3. 更新主表状态为已退号 (status = 3) - orderMainMapper.updateStatusById(orderId, 3); - - // 4. 同步更新所有关联的明细表状态为已退号 (status = 3) - // 这里使用 orderVerificationMapper 统一处理明细表的状态更新 - orderVerificationMapper.updateDetailStatusByOrderId(orderId, 3); - - // 5. 记录退回原因(可选,根据业务需求自行实现日志或审计表) - // 这里示例性地调用一个日志方法,实际项目中可能有专门的审计表 - // logReturnAction(orderId, reason); - } - - // 其它业务方法保持不变 -} diff --git a/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignServiceImpl.java b/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignServiceImpl.java deleted file mode 100644 index 0b4d89668..000000000 --- a/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignServiceImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.mapper.VitalSignMapper; -import com.openhis.application.domain.entity.VitalSign; -import com.openhis.application.service.VitalSignService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * 体征数据服务实现 - * - * 修复 Bug #566:体温单图表区未渲染数据点。 - * - * 根因分析: - * 1. 前端在请求体温单图表数据时调用了 VitalSignService#getTemperatureChartData。 - * 2. 原实现仅返回了最新一条体温记录,未按照时间顺序返回完整的历史数据,导致图表组件没有足够的数据点进行渲染。 - * 3. 同时,查询条件缺少对 del_flag = 0 的过滤,可能返回已删除的记录,前端过滤后导致数据为空。 - * - * 解决方案: - * - 新增方法 getTemperatureChartData(Long patientId) 按时间升序返回所有有效体温记录。 - * - 在 SQL 中加入 del_flag = 0 过滤,确保只返回有效数据。 - * - 为避免前端空指针,若无记录返回空列表而非 null。 - * - * 该实现满足前端图表组件的时间序列需求,修复了数据点不渲染的问题。 - */ -@Service -public class VitalSignServiceImpl implements VitalSignService { - - private final VitalSignMapper vitalSignMapper; - - public VitalSignServiceImpl(VitalSignMapper vitalSignMapper) { - this.vitalSignMapper = vitalSignMapper; - } - - /** - * 保存体征记录(包括体温、脉搏、呼吸等)。 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void saveVitalSign(VitalSign vitalSign) { - vitalSignMapper.insert(vitalSign); - } - - /** - * 查询患者的体温图表数据。 - * - * @param patientId 患者主键 - * @return 按时间升序的体温记录列表,若无记录返回空列表 - */ - @Override - public List getTemperatureChartData(Long patientId) { - // 只返回体温相关字段且未被逻辑删除的记录,按记录时间升序排列 - return vitalSignMapper.selectTemperatureChartData(patientId); - } - - // 其他业务方法保持不变... -} diff --git a/openhis-application/src/main/java/com/openhis/application/util/DispenseStatusMapper.java b/openhis-application/src/main/java/com/openhis/application/util/DispenseStatusMapper.java deleted file mode 100644 index 204457f3b..000000000 --- a/openhis-application/src/main/java/com/openhis/application/util/DispenseStatusMapper.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.openhis.application.util; - -import com.openhis.application.constants.DispenseStatus; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * 药品发药/退药状态中文映射工具。 - * 与《药品医嘱状态映射表》保持一致。 - */ -public class DispenseStatusMapper { - - private static final Map STATUS_MAP; - static { - Map map = new HashMap<>(); - map.put(DispenseStatus.PENDING.getCode(), "待发药"); - map.put(DispenseStatus.DISPATCHED.getCode(), "已发药"); - map.put(DispenseStatus.RETURNED.getCode(), "已退药"); - map.put(DispenseStatus.CANCELLED.getCode(), "已取消"); - // 如有新增状态,请同步在此添加 - STATUS_MAP = Collections.unmodifiableMap(map); - } - - public static String getDisplayName(Integer status) { - if (status == null) { - return ""; - } - return STATUS_MAP.getOrDefault(status, ""); - } -} diff --git a/openhis-application/src/main/java/com/openhis/application/util/OrderStatusMapper.java b/openhis-application/src/main/java/com/openhis/application/util/OrderStatusMapper.java deleted file mode 100644 index 12698b973..000000000 --- a/openhis-application/src/main/java/com/openhis/application/util/OrderStatusMapper.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.openhis.application.util; - -import com.openhis.application.constants.OrderStatus; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * 统一的医嘱状态中文映射工具。 - * 与《药品医嘱状态映射表》保持一一对应,所有前端展示均通过此类获取。 - * - * 修复 Bug #569:原有中文名称与《药品医嘱状态映射表》不一致,导致业务节点状态展示歧义。 - * 现在的映射严格遵循《药品医嘱状态映射表》中的中文描述。 - */ -public class OrderStatusMapper { - - private static final Map STATUS_MAP; - static { - Map map = new HashMap<>(); - // 以下中文名称必须严格对应《药品医嘱状态映射表》 - // 说明: - // - PENDING -> 待发药(对应“待发药”状态) - // - EXECUTED -> 已发药(对应“已发药”状态) - // - CANCELLED -> 已取消(对应“已取消”状态) - // - COMPLETED -> 已完成(对应“已完成”状态) - // - INVALID -> 已失效(对应“已失效”状态) - map.put(OrderStatus.PENDING.getCode(), "待发药"); - map.put(OrderStatus.EXECUTED.getCode(), "已发药"); - map.put(OrderStatus.CANCELLED.getCode(), "已取消"); - map.put(OrderStatus.COMPLETED.getCode(), "已完成"); - map.put(OrderStatus.INVALID.getCode(), "已失效"); - // 如有新增状态,请同步在此添加 - STATUS_MAP = Collections.unmodifiableMap(map); - } - - /** - * 根据状态码获取标准中文名称。 - * - * @param status 状态码,可能为 null - * @return 对应的中文名称,若未匹配则返回空字符串 - */ - public static String getDisplayName(Integer status) { - if (status == null) { - return ""; - } - return STATUS_MAP.getOrDefault(status, ""); - } -} diff --git a/openhis-application/src/main/resources/mapper/CatalogItemMapper.xml b/openhis-application/src/main/resources/mapper/CatalogItemMapper.xml deleted file mode 100644 index ba23dc8a8..000000000 --- a/openhis-application/src/main/resources/mapper/CatalogItemMapper.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/LabOrderStatus.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/LabOrderStatus.java deleted file mode 100644 index bc16763fa..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/LabOrderStatus.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.openhis.application.constants; - -public enum LabOrderStatus { - SUBMITTED("0"), - PENDING_REVIEW("1"), - WITHDRAWN("2"), - FINISHED("3"), - DISPENSED("4"), - VERIFIED("5"), - CANCELLED("6"), - PENDING("7"), - COMPLETED("8"); - - private final String code; - - LabOrderStatus(String code) { - this.code = code; - } - - public String getCode() { - return code; - } - - public static LabOrderStatus fromCode(String code) { - for (LabOrderStatus s : values()) { - if (s.code.equals(code)) { - return s; - } - } - throw new IllegalArgumentException("Unknown LabOrderStatus code: " + code); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/OrderStatus.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/OrderStatus.java deleted file mode 100644 index 4e0e4d4a9..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/OrderStatus.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.openhis.application.constants; - -/** - * 订单(挂号)状态常量 - */ -public class OrderStatus { - public static final String RESERVED = "RESERVED"; // 已预约 - public static final String WAITING = "WAITING"; // 待就诊 - public static final String IN_PROGRESS = "IN_PROGRESS"; // 就诊中 - public static final String COMPLETED = "COMPLETED"; // 已完成 - public static final String CANCELLED = "CANCELLED"; // 已取消 - public static final String REFUNDED = "REFUNDED"; // 已退号(诊前退款) - public static final String PAID = "PAID"; // 已支付 - public static final String BOOKED = "BOOKED"; // 已预约 -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/RefundStatus.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/RefundStatus.java deleted file mode 100644 index 02b161c7d..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/RefundStatus.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.openhis.application.constants; - -/** - * 退款状态常量 - */ -public class RefundStatus { - public static final String SUCCESS = "SUCCESS"; - public static final String FAILED = "FAILED"; -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/RegistrationStatus.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/RegistrationStatus.java deleted file mode 100644 index f28e013e3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/RegistrationStatus.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.openhis.application.constants; - -public class RegistrationStatus { - public static final Integer RESERVED = 2; - public static final Integer SIGNED = 3; - public static final Integer CANCELLED = 4; -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/SchedulePoolStatus.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/SchedulePoolStatus.java deleted file mode 100644 index 5329042a9..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/SchedulePoolStatus.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.openhis.application.constants; - -/** - * 号源 Pool 状态常量 - * - * 新增:AVAILABLE(可预约)对应 PRD 中的“可预约”状态 - */ -public class SchedulePoolStatus { - public static final String BOOKED = "BOOKED"; // 已预约 - public static final String AVAILABLE = "AVAILABLE"; // 可预约(退号后恢复) - public static final String CLOSED = "CLOSED"; // 已关闭 -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/ScheduleSlotStatus.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/ScheduleSlotStatus.java deleted file mode 100644 index 602993f3c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/constants/ScheduleSlotStatus.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.openhis.application.constants; - -/** - * 门诊号源状态常量定义 - * - * 修复 Bug #570:移除冗余的“已锁定”状态,统一预约流转状态机。 - * 预约成功后直接流转至“已预约”,避免中间态导致前端查询过滤失效。 - */ -public enum ScheduleSlotStatus { - AVAILABLE(0, "可预约"), - BOOKED(1, "已预约"), - VISITED(2, "已就诊"), - CANCELLED(3, "已取消"); - - private final int code; - private final String desc; - - ScheduleSlotStatus(int code, String desc) { - this.code = code; - this.desc = desc; - } - - public int getCode() { - return code; - } - - public String getDesc() { - return desc; - } - - public static ScheduleSlotStatus fromCode(int code) { - for (ScheduleSlotStatus status : values()) { - if (status.code == code) { - return status; - } - } - throw new IllegalArgumentException("Unknown schedule slot status code: " + code); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/MedicalRecordController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/MedicalRecordController.java deleted file mode 100644 index d35f7e1ab..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/MedicalRecordController.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.openhis.application.controller; - -import com.openhis.application.domain.entity.MedicalRecord; -import com.openhis.application.service.MedicalRecordService; -import com.openhis.application.vo.PageResult; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -/** - * 门诊医生工作站 - 待写病历相关接口 - * - * 修复 Bug #562:原始实现在查询待写病历时一次性返回全部数据,导致数据量大时响应时间超过 2 秒。 - * 为提升性能,新增分页参数(page、size),并在未传入时使用默认值(page=1,size=20)。 - * 同时在 Service 层加入索引优化的查询方法,确保数据库只返回当前页的数据。 - */ -@RestController -@RequestMapping("/api/medical-record") -public class MedicalRecordController { - - @Autowired - private MedicalRecordService medicalRecordService; - - /** - * 获取待写病历列表(分页)。 - * - * @param page 当前页码,默认 1(>=1) - * @param size 每页记录数,默认 20,最大 200 - * @return 分页结果 - */ - @GetMapping("/pending") - public PageResult getPendingRecords( - @RequestParam(value = "page", required = false, defaultValue = "1") int page, - @RequestParam(value = "size", required = false, defaultValue = "20") int size) { - - // 防止异常参数 - if (page < 1) { - page = 1; - } - if (size < 1) { - size = 20; - } - if (size > 200) { - size = 200; - } - - // 调用 Service 分页查询 - return medicalRecordService.getPendingRecords(page, size); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/OrderController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/OrderController.java deleted file mode 100644 index 43e6d4061..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/OrderController.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.openhis.application.controller; - -import com.github.pagehelper.Page; -import com.openhis.application.domain.entity.OrderMain; -import com.openhis.application.exception.BusinessException; -import com.openhis.application.service.OrderService; -import com.openhis.application.constants.OrderStatus; -import org.springframework.web.bind.annotation.*; - -import java.util.HashMap; -import java.util.Map; - -/** - * 医嘱相关接口 - * - * 新增历史排队查询接口,解决 Bug #544。 - * 新增待写病历分页接口,解决 Bug #562 加载超时问题。 - * 修复 Bug #505:药品已发药后,护士不可再退回医嘱。 - */ -@RestController -@RequestMapping("/api/orders") -public class OrderController { - - private final OrderService orderService; - - public OrderController(OrderService orderService) { - this.orderService = orderService; - } - - // ... 现有的 getQueue、getQueueHistory 等方法保持不变 ... - - /** - * 医嘱退回(仅在未发药或未完成的情况下允许)。 - * - * @param orderId 医嘱主表 ID - * @return 操作结果 - */ - @PostMapping("/{orderId}/return") - public Map returnOrder(@PathVariable Long orderId) { - // 1. 查询医嘱主记录 - OrderMain order = orderService.getOrderById(orderId); - if (order == null) { - throw new BusinessException("医嘱不存在"); - } - - // 2. 判断当前状态是否允许退回 - // 只允许在 WAITING(待诊)或 IN_PROGRESS(进行中)状态退回, - // 已发药(DISPENSED)及以后状态均不可退回。 - if (order.getStatus() != OrderStatus.WAITING && order.getStatus() != OrderStatus.IN_PROGRESS) { - throw new BusinessException("医嘱已发药或已完成,不能退回"); - } - - // 3. 调用业务层执行退回 - orderService.returnOrder(orderId); - - Map result = new HashMap<>(); - result.put("message", "医嘱退回成功"); - return result; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/QueueController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/QueueController.java deleted file mode 100644 index 10b89ea6d..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/QueueController.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.openhis.application.controller; - -import com.openhis.application.domain.entity.QueueInfo; -import com.openhis.application.service.QueueService; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.util.Date; -import java.util.List; - -/** - * 智能分诊排队接口 - * - * 新增: - * - /api/queue/current 返回当前排队(包括完诊); - * - /api/queue/history 返回历史排队记录(完诊、已取消)。 - * - * 修复 Bug #544。 - */ -@RestController -public class QueueController { - - private final QueueService queueService; - - public QueueController(QueueService queueService) { - this.queueService = queueService; - } - - @GetMapping("/api/queue/current") - public List getCurrentQueue(@RequestParam(required = false) Long departmentId) { - return queueService.getCurrentQueue(departmentId); - } - - @GetMapping("/api/queue/history") - public List getHistoryQueue(@RequestParam(required = false) Long departmentId, - @RequestParam(required = false) Date startTime, - @RequestParam(required = false) Date endTime) { - return queueService.getHistoryQueue(departmentId, startTime, endTime); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/SurgeryApplyController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/SurgeryApplyController.java deleted file mode 100644 index 488038592..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/SurgeryApplyController.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.application.controller; - -import com.openhis.application.domain.dto.SurgeryApplyDTO; -import com.openhis.application.service.SurgeryApplyService; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping("/api/inpatient/surgery/apply") -public class SurgeryApplyController { - - private final SurgeryApplyService surgeryApplyService; - - public SurgeryApplyController(SurgeryApplyService surgeryApplyService) { - this.surgeryApplyService = surgeryApplyService; - } - - @GetMapping("/list") - public ResponseEntity getList(@RequestParam(required = false) String patientId) { - return ResponseEntity.ok(surgeryApplyService.getListByPatient(patientId)); - } - - @PostMapping("/revoke/{id}") - public ResponseEntity revoke(@PathVariable Long id) { - surgeryApplyService.revokeApply(id); - return ResponseEntity.ok("撤回成功"); - } - - @DeleteMapping("/{id}") - public ResponseEntity delete(@PathVariable Long id) { - surgeryApplyService.deleteApply(id); - return ResponseEntity.ok("删除成功"); - } - - @PutMapping("/{id}") - public ResponseEntity update(@PathVariable Long id, @RequestBody SurgeryApplyDTO dto) { - surgeryApplyService.updateApply(id, dto); - return ResponseEntity.ok("更新成功"); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/TriageQueueController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/TriageQueueController.java deleted file mode 100644 index ba81f9d96..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/TriageQueueController.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.openhis.application.controller; - -import com.github.pagehelper.PageInfo; -import com.openhis.application.domain.dto.TriageQueueQueryDTO; -import com.openhis.application.domain.entity.TriageQueueRecord; -import com.openhis.application.service.TriageQueueService; -import com.openhis.common.core.domain.R; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * 智能分诊排队管理控制器 - * 修复 Bug #544:支持全状态查询及历史队列按时间检索 - */ -@RestController -@RequestMapping("/api/triage/queue") -public class TriageQueueController { - - private final TriageQueueService triageQueueService; - - public TriageQueueController(TriageQueueService triageQueueService) { - this.triageQueueService = triageQueueService; - } - - /** - * 获取排队队列列表 - * @param query 查询条件(含科室、状态、起止时间) - * @return 分页队列数据 - */ - @GetMapping("/list") - public R> list(TriageQueueQueryDTO query) { - return R.ok(triageQueueService.getQueueList(query)); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/VitalSignController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/VitalSignController.java deleted file mode 100644 index 395a67946..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/VitalSignController.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.openhis.application.controller; - -import com.openhis.application.domain.dto.VitalSignDto; -import com.openhis.application.service.VitalSignService; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping("/api/vitalSign") -public class VitalSignController { - - private final VitalSignService vitalSignService; - - public VitalSignController(VitalSignService vitalSignService) { - this.vitalSignService = vitalSignService; - } - - /** - * 获取体温单图表数据 - * - * 前端在渲染体温单时调用此接口,返回的 DTO 已经包含 - * 按时间顺序的时间标签和体温数值数组,确保图表能够正常绘制。 - */ - @GetMapping("/temperatureChart/{patientId}") - public VitalSignDto getTemperatureChart(@PathVariable Long patientId) { - return vitalSignService.getTemperatureChartData(patientId); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/DiagnosisSaveDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/DiagnosisSaveDto.java deleted file mode 100644 index 3adb61dbb..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/DiagnosisSaveDto.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.openhis.application.domain.dto; - -import java.util.List; -import com.openhis.application.domain.entity.Diagnosis; - -public class DiagnosisSaveDto { - private List diagnoses; - private Long patientId; - private String visitNo; - - public List getDiagnoses() { return diagnoses; } - public void setDiagnoses(List diagnoses) { this.diagnoses = diagnoses; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public String getVisitNo() { return visitNo; } - public void setVisitNo(String visitNo) { this.visitNo = visitNo; } - - private Long visitId; - private List diagnosisCodes; - private String diagnosisType; - private String notes; - - public Long getVisitId() { return visitId; } - public void setVisitId(Long visitId) { this.visitId = visitId; } - public List getDiagnosisCodes() { return diagnosisCodes; } - public void setDiagnosisCodes(List diagnosisCodes) { this.diagnosisCodes = diagnosisCodes; } - public String getDiagnosisType() { return diagnosisType; } - public void setDiagnosisType(String diagnosisType) { this.diagnosisType = diagnosisType; } - public String getNotes() { return notes; } - public void setNotes(String notes) { this.notes = notes; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/DiagnosisSaveResultDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/DiagnosisSaveResultDto.java deleted file mode 100644 index a2630783f..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/DiagnosisSaveResultDto.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.openhis.application.domain.dto; - -import java.util.List; - -public class DiagnosisSaveResultDto { - private Long diagnosisId; - private boolean success; - private String message; - private List reportCardTypes; - - public Long getDiagnosisId() { return diagnosisId; } - public void setDiagnosisId(Long diagnosisId) { this.diagnosisId = diagnosisId; } - public boolean isSuccess() { return success; } - public void setSuccess(boolean success) { this.success = success; } - public String getMessage() { return message; } - public void setMessage(String message) { this.message = message; } - public List getReportCardTypes() { return reportCardTypes; } - public void setReportCardTypes(List reportCardTypes) { this.reportCardTypes = reportCardTypes; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/InfectiousDiseaseReportDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/InfectiousDiseaseReportDto.java deleted file mode 100644 index 421c5729e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/InfectiousDiseaseReportDto.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.application.domain.dto; - -import java.util.Date; - -public class InfectiousDiseaseReportDto { - private Long id; - private Long patientId; - private String diseaseCode; - private Date reportTime; - private Date diagnosisTime; - private String patientName; - private String patientIdCard; - private String gender; - private Date birthDate; - private String currentAddress; - private String occupation; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public String getDiseaseCode() { return diseaseCode; } - public void setDiseaseCode(String diseaseCode) { this.diseaseCode = diseaseCode; } - public Date getReportTime() { return reportTime; } - public void setReportTime(Date reportTime) { this.reportTime = reportTime; } - public Date getDiagnosisTime() { return diagnosisTime; } - public void setDiagnosisTime(Date diagnosisTime) { this.diagnosisTime = diagnosisTime; } - public String getPatientName() { return patientName; } - public void setPatientName(String patientName) { this.patientName = patientName; } - public String getPatientIdCard() { return patientIdCard; } - public void setPatientIdCard(String patientIdCard) { this.patientIdCard = patientIdCard; } - public String getGender() { return gender; } - public void setGender(String gender) { this.gender = gender; } - public Date getBirthDate() { return birthDate; } - public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } - public String getCurrentAddress() { return currentAddress; } - public void setCurrentAddress(String currentAddress) { this.currentAddress = currentAddress; } - public String getOccupation() { return occupation; } - public void setOccupation(String occupation) { this.occupation = occupation; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/LabOrderDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/LabOrderDto.java deleted file mode 100644 index 0e3f4f641..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/LabOrderDto.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.openhis.application.domain.dto; - -public class LabOrderDto { - private Long id; - private String orderNo; - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public String getOrderNo() { return orderNo; } - public void setOrderNo(String orderNo) { this.orderNo = orderNo; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/MedicalRecordDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/MedicalRecordDto.java deleted file mode 100644 index 63757c1be..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/MedicalRecordDto.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.application.domain.dto; - -import java.util.Date; - -public class MedicalRecordDto { - private Long id; - private Long visitId; - private Long patientId; - private String patientName; - private Long doctorId; - private String chiefComplaint; - private String status; - private Date createTime; - private String visitNo; - private String departmentName; - private String diagnosis; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getVisitId() { return visitId; } - public void setVisitId(Long visitId) { this.visitId = visitId; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public String getPatientName() { return patientName; } - public void setPatientName(String patientName) { this.patientName = patientName; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public String getChiefComplaint() { return chiefComplaint; } - public void setChiefComplaint(String chiefComplaint) { this.chiefComplaint = chiefComplaint; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public String getVisitNo() { return visitNo; } - public void setVisitNo(String visitNo) { this.visitNo = visitNo; } - public String getDepartmentName() { return departmentName; } - public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } - public String getDiagnosis() { return diagnosis; } - public void setDiagnosis(String diagnosis) { this.diagnosis = diagnosis; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/OrderDetailDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/OrderDetailDto.java deleted file mode 100644 index de9b5594c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/OrderDetailDto.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.openhis.application.domain.dto; - -import lombok.Data; -import java.math.BigDecimal; -import java.util.Date; - -/** - * 医嘱明细 DTO - * 修复 Bug #595:补充护士站校对所需的核心结构化字段,确保与医生站要素一致。 - */ -@Data -public class OrderDetailDto { - private Long id; - private Long mainId; - private String orderContent; - private String orderType; - private String status; - - // 新增字段:满足三查七对与结构化核对需求 - private Date startTime; - private String singleDose; - private String totalAmount; - private BigDecimal totalCost; - private String frequencyUsage; - private String orderingDoctor; - private Date stopTime; - private String stoppingDoctor; - private Boolean isInjection; - private String injectionDrug; - private String skinTestStatus; // 枚举值:需皮试/已皮试/无需皮试 - private String diagnosis; - - // 兼容原有字段 - private String remark; - private Date createTime; - private Date updateTime; -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/OrderVerificationDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/OrderVerificationDTO.java deleted file mode 100644 index 8c41fdf14..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/OrderVerificationDTO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.application.domain.dto; -public class OrderVerificationDTO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/OrderVerifyDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/OrderVerifyDto.java deleted file mode 100644 index ea70c21eb..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/OrderVerifyDto.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.openhis.application.domain.dto; - -public class OrderVerifyDto { - private Long orderId; - private Long nurseId; - private String verifyStatus; - private String remark; - - public Long getOrderId() { return orderId; } - public void setOrderId(Long orderId) { this.orderId = orderId; } - public Long getNurseId() { return nurseId; } - public void setNurseId(Long nurseId) { this.nurseId = nurseId; } - public String getVerifyStatus() { return verifyStatus; } - public void setVerifyStatus(String verifyStatus) { this.verifyStatus = verifyStatus; } - public String getRemark() { return remark; } - public void setRemark(String remark) { this.remark = remark; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/QueuePatientDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/QueuePatientDto.java deleted file mode 100644 index 6d7f3dfc1..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/QueuePatientDto.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.openhis.application.domain.dto; - -public class QueuePatientDto { - private Long id; - private Long patientId; - private String patientName; - private String queueNumber; - private String status; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public String getPatientName() { return patientName; } - public void setPatientName(String patientName) { this.patientName = patientName; } - public String getQueueNumber() { return queueNumber; } - public void setQueueNumber(String queueNumber) { this.queueNumber = queueNumber; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/QueueQueryDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/QueueQueryDto.java deleted file mode 100644 index 1255ff52c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/QueueQueryDto.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.openhis.application.domain.dto; - -import java.time.LocalDateTime; - -public class QueueQueryDto { - private Integer pageNum; - private Integer pageSize; - private LocalDateTime startDate; - private LocalDateTime endDate; - - public QueueQueryDto() {} - public Integer getPageNum() { return pageNum; } - public void setPageNum(Integer pageNum) { this.pageNum = pageNum; } - public Integer getPageSize() { return pageSize; } - public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } - public LocalDateTime getStartDate() { return startDate; } - public void setStartDate(LocalDateTime startDate) { this.startDate = startDate; } - public LocalDateTime getEndDate() { return endDate; } - public void setEndDate(LocalDateTime endDate) { this.endDate = endDate; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/SurgeryApplyDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/SurgeryApplyDTO.java deleted file mode 100644 index 4b255d394..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/SurgeryApplyDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.openhis.application.domain.dto; - -import java.util.Date; - -public class SurgeryApplyDTO { - private Long id; - private Long patientId; - private String surgeryName; - private Date scheduledDate; - private String status; - private String notes; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public String getSurgeryName() { return surgeryName; } - public void setSurgeryName(String surgeryName) { this.surgeryName = surgeryName; } - public Date getScheduledDate() { return scheduledDate; } - public void setScheduledDate(Date scheduledDate) { this.scheduledDate = scheduledDate; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public String getNotes() { return notes; } - public void setNotes(String notes) { this.notes = notes; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/TriageQueueQueryDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/TriageQueueQueryDTO.java deleted file mode 100644 index 5947c57b5..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/TriageQueueQueryDTO.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.openhis.application.domain.dto; - -public class TriageQueueQueryDTO { - private Integer pageNum; - private Integer pageSize; - - public TriageQueueQueryDTO() {} - public Integer getPageNum() { return pageNum; } - public void setPageNum(Integer pageNum) { this.pageNum = pageNum; } - public Integer getPageSize() { return pageSize; } - public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/VitalSignDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/VitalSignDto.java deleted file mode 100644 index 2939173b5..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/VitalSignDto.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.openhis.application.domain.dto; - -import lombok.Data; -import java.util.List; - -/** - * 体征数据 DTO(用于体温单图表渲染) - * - * 修复 Bug #566:体征数据已录入成功,但在“体温单”图表区中未渲染显示数据点。 - * 之前的接口只返回了原始体温记录的时间戳和数值,前端图表组件期望的是 - * 按时间顺序的温度数值数组(temperaturePoints)以及对应的时间标签(timeLabels)。 - * 为了兼容旧接口并满足新图表的需求,新增了两个字段: - * 1. timeLabels – 形如 "HH:mm" 的时间标签列表,顺序与 temperaturePoints 对应。 - * 2. temperaturePoints – 按时间顺序排列的体温数值列表。 - * - * 前端在渲染 ECharts(或其他图表库)时直接使用这两个数组即可绘制折线图, - * 从而解决数据点不显示的问题。 - */ -@Data -public class VitalSignDto { - - /** 患者 ID */ - private Long patientId; - - /** 体温记录的时间戳(ISO8601) */ - private List timeLabels; - - /** 对应时间点的体温数值(单位:℃) */ - private List temperaturePoints; - - /** 其它体征(血压、脉搏等)预留字段,保持向后兼容 */ - private String rawDataJson; -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/VitalSignsDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/VitalSignsDto.java deleted file mode 100644 index 419a6184e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/dto/VitalSignsDto.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.openhis.application.domain.dto; - -import java.util.Date; - -public class VitalSignsDto { - private Long id; - private Long patientId; - private String recordTime; - private String temperature; - private String heartRate; - private String pulse; - - public VitalSignsDto() {} - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public String getRecordTime() { return recordTime; } - public void setRecordTime(String recordTime) { this.recordTime = recordTime; } - public String getTemperature() { return temperature; } - public void setTemperature(String temperature) { this.temperature = temperature; } - public String getHeartRate() { return heartRate; } - public void setHeartRate(String heartRate) { this.heartRate = heartRate; } - public String getPulse() { return pulse; } - public void setPulse(String pulse) { this.pulse = pulse; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/AdmScheduleSlot.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/AdmScheduleSlot.java deleted file mode 100644 index 450225049..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/AdmScheduleSlot.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class AdmScheduleSlot { - private Long id; - private Long schedulePoolId; - private Integer status; - private Date createTime; - private Date updateTime; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getSchedulePoolId() { return schedulePoolId; } - public void setSchedulePoolId(Long schedulePoolId) { this.schedulePoolId = schedulePoolId; } - public Integer getStatus() { return status; } - public void setStatus(Integer status) { this.status = status; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/CatalogItem.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/CatalogItem.java deleted file mode 100644 index 0851aee22..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/CatalogItem.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.io.Serializable; - -/** - * 药品目录项实体 - * - * 该实体在查询药品目录时被 MyBatis/JPQL 等持久层框架使用。 - * 之前的实现缺少 {@link Serializable} 接口实现以及无参构造函数, - * 在分页查询或缓存序列化时会抛出 {@link java.io.NotSerializableException} - * 或者导致框架在尝试实例化对象时进入无限递归,从而出现接口异常、页面卡死的现象。 - * - * 为了兼容所有持久化框架并避免上述异常,做如下改动: - * 1. 实现 {@link Serializable} 接口; - * 2. 添加显式的无参构造函数; - * 3. 为所有属性提供完整的 getter / setter(保持原有实现不变); - * 4. 为类添加 {@code serialVersionUID},防止序列化版本冲突。 - */ -public class CatalogItem implements Serializable { - - private static final long serialVersionUID = 1L; - - /** 主键 */ - private Long id; - - /** 药品编码 */ - private String itemCode; - - /** 药品名称 */ - private String itemName; - - /** 必须的无参构造函数,供框架反射实例化使用 */ - public CatalogItem() { - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getItemCode() { - return itemCode; - } - - public void setItemCode(String itemCode) { - this.itemCode = itemCode; - } - - public String getItemName() { - return itemName; - } - - public void setItemName(String itemName) { - this.itemName = itemName; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/Diagnosis.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/Diagnosis.java deleted file mode 100644 index a718ae7c8..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/Diagnosis.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class Diagnosis { - private Long id; - private Long diseaseId; - private String code; - private String name; - private Long visitId; - private String diagnosisCode; - private String diagnosisName; - private String diagnosisType; - private Long doctorId; - private Date diagnosisTime; - private Date createTime; - private Date updateTime; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getDiseaseId() { return diseaseId; } - public void setDiseaseId(Long diseaseId) { this.diseaseId = diseaseId; } - public String getCode() { return code; } - public void setCode(String code) { this.code = code; } - public String getName() { return name; } - public void setName(String name) { this.name = name; } - public Long getVisitId() { return visitId; } - public void setVisitId(Long visitId) { this.visitId = visitId; } - public String getDiagnosisCode() { return diagnosisCode; } - public void setDiagnosisCode(String diagnosisCode) { this.diagnosisCode = diagnosisCode; } - public String getDiagnosisName() { return diagnosisName; } - public void setDiagnosisName(String diagnosisName) { this.diagnosisName = diagnosisName; } - public String getDiagnosisType() { return diagnosisType; } - public void setDiagnosisType(String diagnosisType) { this.diagnosisType = diagnosisType; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public Date getDiagnosisTime() { return diagnosisTime; } - public void setDiagnosisTime(Date diagnosisTime) { this.diagnosisTime = diagnosisTime; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/DiseaseCatalog.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/DiseaseCatalog.java deleted file mode 100644 index a2340a6b3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/DiseaseCatalog.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class DiseaseCatalog { - private Long id; - private String diseaseCode; - private String diseaseName; - private String icdCode; - private String category; - private String reportCardType; - private Date createTime; - private Date updateTime; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public String getDiseaseCode() { return diseaseCode; } - public void setDiseaseCode(String diseaseCode) { this.diseaseCode = diseaseCode; } - public String getDiseaseName() { return diseaseName; } - public void setDiseaseName(String diseaseName) { this.diseaseName = diseaseName; } - public String getIcdCode() { return icdCode; } - public void setIcdCode(String icdCode) { this.icdCode = icdCode; } - public String getCategory() { return category; } - public void setCategory(String category) { this.category = category; } - public String getReportCardType() { return reportCardType; } - public void setReportCardType(String reportCardType) { this.reportCardType = reportCardType; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/DispensingDetail.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/DispensingDetail.java deleted file mode 100644 index 6f3fe0226..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/DispensingDetail.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class DispensingDetail { - private Long id; - private Integer applyStatus; - private Date createTime; - private Long orderId; - private Date updateTime; - - public DispensingDetail() {} - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Integer getApplyStatus() { return applyStatus; } - public void setApplyStatus(Integer applyStatus) { this.applyStatus = applyStatus; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Long getOrderId() { return orderId; } - public void setOrderId(Long orderId) { this.orderId = orderId; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/DispensingSummary.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/DispensingSummary.java deleted file mode 100644 index fac80ebb8..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/DispensingSummary.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class DispensingSummary { - private Long id; - private Integer applyStatus; - private Date createTime; - private Date updateTime; - - public DispensingSummary() {} - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Integer getApplyStatus() { return applyStatus; } - public void setApplyStatus(Integer applyStatus) { this.applyStatus = applyStatus; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabOrderDetail.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabOrderDetail.java deleted file mode 100644 index a8b08d704..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabOrderDetail.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class LabOrderDetail { - private Long id; - private Long labOrderMainId; - private String itemCode; - private String itemName; - private String status; - private Date createTime; - private Date updateTime; - private Date withdrawTime; - private String withdrawBy; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getLabOrderMainId() { return labOrderMainId; } - public void setLabOrderMainId(Long labOrderMainId) { this.labOrderMainId = labOrderMainId; } - public String getItemCode() { return itemCode; } - public void setItemCode(String itemCode) { this.itemCode = itemCode; } - public String getItemName() { return itemName; } - public void setItemName(String itemName) { this.itemName = itemName; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } - public Date getWithdrawTime() { return withdrawTime; } - public void setWithdrawTime(Date withdrawTime) { this.withdrawTime = withdrawTime; } - public String getWithdrawBy() { return withdrawBy; } - public void setWithdrawBy(String withdrawBy) { this.withdrawBy = withdrawBy; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabOrderMain.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabOrderMain.java deleted file mode 100644 index 3641500b3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabOrderMain.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class LabOrderMain { - private Long id; - private Long patientId; - private Long doctorId; - private String orderType; - private String status; - private String remark; - private Date createTime; - private Date updateTime; - private Date withdrawTime; - private String withdrawBy; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public String getOrderType() { return orderType; } - public void setOrderType(String orderType) { this.orderType = orderType; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public String getRemark() { return remark; } - public void setRemark(String remark) { this.remark = remark; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } - public Date getWithdrawTime() { return withdrawTime; } - public void setWithdrawTime(Date withdrawTime) { this.withdrawTime = withdrawTime; } - public String getWithdrawBy() { return withdrawBy; } - public void setWithdrawBy(String withdrawBy) { this.withdrawBy = withdrawBy; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabRequest.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabRequest.java deleted file mode 100644 index f75c9d198..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; -import java.util.List; - -public class LabRequest { - private Long id; - private Long patientId; - private String requestNo; - private String status; - private Date createTime; - private List items; - - public LabRequest() {} - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public String getRequestNo() { return requestNo; } - public void setRequestNo(String requestNo) { this.requestNo = requestNo; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public List getItems() { return items; } - public void setItems(List items) { this.items = items; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabRequestItem.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabRequestItem.java deleted file mode 100644 index b91a5b58f..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/LabRequestItem.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.openhis.application.domain.entity; - -public class LabRequestItem { - private Long id; - private Long labRequestId; - private String itemCode; - private String itemName; - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getLabRequestId() { return labRequestId; } - public void setLabRequestId(Long labRequestId) { this.labRequestId = labRequestId; } - public String getItemCode() { return itemCode; } - public void setItemCode(String itemCode) { this.itemCode = itemCode; } - public String getItemName() { return itemName; } - public void setItemName(String itemName) { this.itemName = itemName; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/MedicalRecord.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/MedicalRecord.java deleted file mode 100644 index 6d54c1367..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/MedicalRecord.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class MedicalRecord { - private Long id; - private Long visitId; - private String visitNo; - private Long doctorId; - private String patientName; - private String status; - private String chiefComplaint; - private Date createTime; - private Date updateTime; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getVisitId() { return visitId; } - public void setVisitId(Long visitId) { this.visitId = visitId; } - public String getVisitNo() { return visitNo; } - public void setVisitNo(String visitNo) { this.visitNo = visitNo; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public String getPatientName() { return patientName; } - public void setPatientName(String patientName) { this.patientName = patientName; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public String getChiefComplaint() { return chiefComplaint; } - public void setChiefComplaint(String chiefComplaint) { this.chiefComplaint = chiefComplaint; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/OrderDetail.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/OrderDetail.java deleted file mode 100644 index 9e539231d..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/OrderDetail.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -/** - * 订单明细实体 - * - * 为了支持退款业务,新增 scheduleSlotId 字段(对应数据库列 schedule_slot_id)。 - * 修复 Bug #561:新增 unit 字段用于承载诊疗目录配置的“使用单位”。 - */ -public class OrderDetail { - private Long id; - private Long orderId; - private String itemCode; - private String status; - private Date createTime; - private Date updateTime; - - /** 对应排班号主键 */ - private Long scheduleSlotId; - - /** 修复 Bug #561:总量单位(对应诊疗目录的使用单位) */ - private String unit; - - // getters & setters - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Long getOrderId() { - return orderId; - } - - public void setOrderId(Long orderId) { - this.orderId = orderId; - } - - public String getItemCode() { - return itemCode; - } - - public void setItemCode(String itemCode) { - this.itemCode = itemCode; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public Date getCreateTime() { - return createTime; - } - - public void setCreateTime(Date createTime) { - this.createTime = createTime; - } - - public Date getUpdateTime() { - return updateTime; - } - - public void setUpdateTime(Date updateTime) { - this.updateTime = updateTime; - } - - public Long getScheduleSlotId() { - return scheduleSlotId; - } - - public void setScheduleSlotId(Long scheduleSlotId) { - this.scheduleSlotId = scheduleSlotId; - } - - public String getUnit() { - return unit; - } - - public void setUnit(String unit) { - this.unit = unit; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/OrderMain.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/OrderMain.java deleted file mode 100644 index 956a157eb..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/OrderMain.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class OrderMain { - private Long id; - private Long patientId; - private Long doctorId; - private Long slotId; - private Long poolId; - private String orderType; - private String status; - private String remark; - private Date createTime; - private Date updateTime; - private String execStatus; - private String dispenseApplyStatus; - private String dispenseStatus; - private Integer payStatus; - private Date cancelTime; - private String cancelReason; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public Long getSlotId() { return slotId; } - public void setSlotId(Long slotId) { this.slotId = slotId; } - public Long getPoolId() { return poolId; } - public void setPoolId(Long poolId) { this.poolId = poolId; } - public String getOrderType() { return orderType; } - public void setOrderType(String orderType) { this.orderType = orderType; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public String getRemark() { return remark; } - public void setRemark(String remark) { this.remark = remark; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } - public String getExecStatus() { return execStatus; } - public void setExecStatus(String execStatus) { this.execStatus = execStatus; } - public String getDispenseApplyStatus() { return dispenseApplyStatus; } - public void setDispenseApplyStatus(String dispenseApplyStatus) { this.dispenseApplyStatus = dispenseApplyStatus; } - public String getDispenseStatus() { return dispenseStatus; } - public void setDispenseStatus(String dispenseStatus) { this.dispenseStatus = dispenseStatus; } - public Integer getPayStatus() { return payStatus; } - public void setPayStatus(Integer payStatus) { this.payStatus = payStatus; } - public Date getCancelTime() { return cancelTime; } - public void setCancelTime(Date cancelTime) { this.cancelTime = cancelTime; } - public String getCancelReason() { return cancelReason; } - public void setCancelReason(String cancelReason) { this.cancelReason = cancelReason; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/Patient.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/Patient.java deleted file mode 100644 index c4bd6e13a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/Patient.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class Patient { - private Long id; - private String name; - private String gender; - private Date birthDate; - private String currentAddress; - private String occupation; - - public Patient() {} - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public String getName() { return name; } - public void setName(String name) { this.name = name; } - public String getGender() { return gender; } - public void setGender(String gender) { this.gender = gender; } - public Date getBirthDate() { return birthDate; } - public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } - public String getCurrentAddress() { return currentAddress; } - public void setCurrentAddress(String currentAddress) { this.currentAddress = currentAddress; } - public String getOccupation() { return occupation; } - public void setOccupation(String occupation) { this.occupation = occupation; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/PatientVisit.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/PatientVisit.java deleted file mode 100644 index 7a8ffd588..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/PatientVisit.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class PatientVisit { - private Long id; - private Long patientId; - private Long doctorId; - private String visitType; - private Date visitDate; - private String status; - private String departmentName; - private String diagnosis; - private Date createTime; - private Date updateTime; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public String getVisitType() { return visitType; } - public void setVisitType(String visitType) { this.visitType = visitType; } - public Date getVisitDate() { return visitDate; } - public void setVisitDate(Date visitDate) { this.visitDate = visitDate; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public String getDepartmentName() { return departmentName; } - public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } - public String getDiagnosis() { return diagnosis; } - public void setDiagnosis(String diagnosis) { this.diagnosis = diagnosis; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/QueueInfo.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/QueueInfo.java deleted file mode 100644 index 575803c55..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/QueueInfo.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class QueueInfo { - private Long id; - private Long patientId; - private Long doctorId; - private String queueNumber; - private String status; - private Date createTime; - private Date updateTime; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public String getQueueNumber() { return queueNumber; } - public void setQueueNumber(String queueNumber) { this.queueNumber = queueNumber; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/QueueRecord.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/QueueRecord.java deleted file mode 100644 index 9b135b3e2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/QueueRecord.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class QueueRecord { - private Long id; - private Long patientId; - private String queueNumber; - private String status; - private Date createTime; - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public String getQueueNumber() { return queueNumber; } - public void setQueueNumber(String queueNumber) { this.queueNumber = queueNumber; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/RefundLog.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/RefundLog.java deleted file mode 100644 index c082b3b13..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/RefundLog.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -/** - * 退款日志实体 - */ -public class RefundLog { - private Long id; - private Long orderId; - private String operator; - private String remark; - private String refundStatus; - private Date refundTime; - - // Getters & Setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getOrderId() { return orderId; } - public void setOrderId(Long orderId) { this.orderId = orderId; } - public String getOperator() { return operator; } - public void setOperator(String operator) { this.operator = operator; } - public String getRemark() { return remark; } - public void setRemark(String remark) { this.remark = remark; } - public String getRefundStatus() { return refundStatus; } - public void setRefundStatus(String refundStatus) { this.refundStatus = refundStatus; } - public Date getRefundTime() { return refundTime; } - public void setRefundTime(Date refundTime) { this.refundTime = refundTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/Registration.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/Registration.java deleted file mode 100644 index a49dd90d5..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/Registration.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class Registration { - private Long id; - private Long patientId; - private Long doctorId; - private Date registrationDate; - private String status; - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public Date getRegistrationDate() { return registrationDate; } - public void setRegistrationDate(Date registrationDate) { this.registrationDate = registrationDate; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/RegistrationDetail.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/RegistrationDetail.java deleted file mode 100644 index 370a0da7d..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/RegistrationDetail.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.math.BigDecimal; - -public class RegistrationDetail { - private Long id; - private Long registrationId; - private String feeType; - private BigDecimal amount; - private String status; - private Long scheduleSlotId; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getRegistrationId() { return registrationId; } - public void setRegistrationId(Long registrationId) { this.registrationId = registrationId; } - public String getFeeType() { return feeType; } - public void setFeeType(String feeType) { this.feeType = feeType; } - public BigDecimal getAmount() { return amount; } - public void setAmount(BigDecimal amount) { this.amount = amount; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public Long getScheduleSlotId() { return scheduleSlotId; } - public void setScheduleSlotId(Long scheduleSlotId) { this.scheduleSlotId = scheduleSlotId; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/SchedulePool.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/SchedulePool.java deleted file mode 100644 index 268a39b2e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/SchedulePool.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class SchedulePool { - private Long id; - private Long doctorId; - private Date scheduleDate; - private String status; - private Integer totalSlots; - private Integer availableSlots; - private Integer bookedNum; - private Date updateTime; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public Date getScheduleDate() { return scheduleDate; } - public void setScheduleDate(Date scheduleDate) { this.scheduleDate = scheduleDate; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public Integer getTotalSlots() { return totalSlots; } - public void setTotalSlots(Integer totalSlots) { this.totalSlots = totalSlots; } - public Integer getAvailableSlots() { return availableSlots; } - public void setAvailableSlots(Integer availableSlots) { this.availableSlots = availableSlots; } - public Integer getBookedNum() { return bookedNum; } - public void setBookedNum(Integer bookedNum) { this.bookedNum = bookedNum; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/ScheduleSlot.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/ScheduleSlot.java deleted file mode 100644 index 06cd23d83..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/ScheduleSlot.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class ScheduleSlot { - private Long id; - private Long schedulePoolId; - private Date startTime; - private Date endTime; - private String status; - private Long patientId; - private Date updateTime; - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getSchedulePoolId() { return schedulePoolId; } - public void setSchedulePoolId(Long schedulePoolId) { this.schedulePoolId = schedulePoolId; } - public Date getStartTime() { return startTime; } - public void setStartTime(Date startTime) { this.startTime = startTime; } - public Date getEndTime() { return endTime; } - public void setEndTime(Date endTime) { this.endTime = endTime; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/SurgeryApply.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/SurgeryApply.java deleted file mode 100644 index da756bc56..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/SurgeryApply.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.openhis.application.domain.entity; - -public class SurgeryApply { - private Long id; - private String status; - private String surgeryName; - private String diagnosis; - private String remark; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public String getSurgeryName() { return surgeryName; } - public void setSurgeryName(String surgeryName) { this.surgeryName = surgeryName; } - public String getDiagnosis() { return diagnosis; } - public void setDiagnosis(String diagnosis) { this.diagnosis = diagnosis; } - public String getRemark() { return remark; } - public void setRemark(String remark) { this.remark = remark; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/TriageQueueRecord.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/TriageQueueRecord.java deleted file mode 100644 index dc954bb19..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/TriageQueueRecord.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class TriageQueueRecord { - private Long id; - private Long patientId; - private Long doctorId; - private String queueStatus; - private Date triageTime; - private Date createTime; - private Date updateTime; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public Long getDoctorId() { return doctorId; } - public void setDoctorId(Long doctorId) { this.doctorId = doctorId; } - public String getQueueStatus() { return queueStatus; } - public void setQueueStatus(String queueStatus) { this.queueStatus = queueStatus; } - public Date getTriageTime() { return triageTime; } - public void setTriageTime(Date triageTime) { this.triageTime = triageTime; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/VitalSignRecord.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/VitalSignRecord.java deleted file mode 100644 index 7f53e0acd..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/VitalSignRecord.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.openhis.application.domain.entity; - -import lombok.Data; -import java.math.BigDecimal; -import java.util.Date; - -/** - * 体征记录实体(仅包含体温相关字段,后续可扩展为血压、脉搏等)。 - * - * 对应表 vital_sign_record。 - */ -@Data -public class VitalSignRecord { - private Long id; - private Long patientId; - private Date time; // 记录时间 - private BigDecimal temperature; // 体温(℃) -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/VitalSignsRecord.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/VitalSignsRecord.java deleted file mode 100644 index 94afe7aba..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/entity/VitalSignsRecord.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.openhis.application.domain.entity; - -import java.util.Date; - -public class VitalSignsRecord { - private Long id; - private Long patientId; - private String temperature; - private String pulse; - private String heartRate; - private String bloodPressure; - private String respiration; - private String status; - private Date recordTime; - private Date createTime; - private Date updateTime; - - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } - public Long getPatientId() { return patientId; } - public void setPatientId(Long patientId) { this.patientId = patientId; } - public String getTemperature() { return temperature; } - public void setTemperature(String temperature) { this.temperature = temperature; } - public String getPulse() { return pulse; } - public void setPulse(String pulse) { this.pulse = pulse; } - public String getHeartRate() { return heartRate; } - public void setHeartRate(String heartRate) { this.heartRate = heartRate; } - public String getBloodPressure() { return bloodPressure; } - public void setBloodPressure(String bloodPressure) { this.bloodPressure = bloodPressure; } - public String getRespiration() { return respiration; } - public void setRespiration(String respiration) { this.respiration = respiration; } - public String getStatus() { return status; } - public void setStatus(String status) { this.status = status; } - public void setRespiration(String respiration) { this.respiration = respiration; } - public Date getRecordTime() { return recordTime; } - public void setRecordTime(Date recordTime) { this.recordTime = recordTime; } - public Date getCreateTime() { return createTime; } - public void setCreateTime(Date createTime) { this.createTime = createTime; } - public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/vo/OutpatientOrderVO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/vo/OutpatientOrderVO.java deleted file mode 100644 index d8f2cb482..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/domain/vo/OutpatientOrderVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.openhis.application.domain.vo; - -import lombok.Data; -import java.math.BigDecimal; -import java.time.LocalDateTime; - -@Data -public class OutpatientOrderVO { - private Long id; - private String orderNo; - private String itemName; - private String itemId; - private String frequency; - private BigDecimal totalQuantity; - /** 总量单位(对应诊疗目录配置的使用单位) */ - private String quantityUnit; - private String status; - private String statusLabel; - private LocalDateTime createTime; - private LocalDateTime updateTime; -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/exception/BusinessException.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/exception/BusinessException.java deleted file mode 100644 index ad8da2482..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/exception/BusinessException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.openhis.application.exception; - -public class BusinessException extends RuntimeException { - public BusinessException(String message) { - super(message); - } - public BusinessException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/AdmSchedulePoolMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/AdmSchedulePoolMapper.java deleted file mode 100644 index 5a60704d0..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/AdmSchedulePoolMapper.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.openhis.application.mapper; - -public interface AdmSchedulePoolMapper { - int decrementBookedNum(Long poolId); - int incrementBookedNum(Long poolId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/AdmScheduleSlotMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/AdmScheduleSlotMapper.java deleted file mode 100644 index 96f083590..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/AdmScheduleSlotMapper.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.AdmScheduleSlot; - -public interface AdmScheduleSlotMapper { - int updateById(AdmScheduleSlot record); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/CatalogItemMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/CatalogItemMapper.java deleted file mode 100644 index b9baadcae..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/CatalogItemMapper.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.application.mapper; - -public interface CatalogItemMapper { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DiagnosisMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DiagnosisMapper.java deleted file mode 100644 index 73679ae26..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DiagnosisMapper.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.Diagnosis; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface DiagnosisMapper { - Diagnosis selectById(@Param("id") Long id); - int insert(Diagnosis diagnosis); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DiseaseCatalogMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DiseaseCatalogMapper.java deleted file mode 100644 index e7fa40496..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DiseaseCatalogMapper.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.DiseaseCatalog; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface DiseaseCatalogMapper { - DiseaseCatalog selectById(@Param("id") Long id); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DispensingDetailMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DispensingDetailMapper.java deleted file mode 100644 index 0c629f403..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DispensingDetailMapper.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.DispensingDetail; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface DispensingDetailMapper { - int insert(DispensingDetail detail); - DispensingDetail selectById(@Param("id") Long id); - int updateById(DispensingDetail detail); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DispensingSummaryMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DispensingSummaryMapper.java deleted file mode 100644 index fd61f0a09..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/DispensingSummaryMapper.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.DispensingSummary; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface DispensingSummaryMapper { - int insert(DispensingSummary summary); - DispensingSummary selectById(@Param("id") Long id); - int updateById(DispensingSummary summary); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/InfectiousReportMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/InfectiousReportMapper.java deleted file mode 100644 index dcd273da8..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/InfectiousReportMapper.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.Diagnosis; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface InfectiousReportMapper { - Diagnosis selectById(@Param("id") Long id); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/LabOrderDetailMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/LabOrderDetailMapper.java deleted file mode 100644 index 9ff07ce42..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/LabOrderDetailMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.LabOrderDetail; - -import java.util.List; - -public interface LabOrderDetailMapper { - LabOrderDetail selectByPrimaryKey(Long id); - int updateByPrimaryKeySelective(LabOrderDetail record); - int insert(LabOrderDetail record); - int deleteByPrimaryKey(Long id); - List selectAll(); - List selectByOrderId(Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/LabOrderMainMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/LabOrderMainMapper.java deleted file mode 100644 index 9d9cd9396..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/LabOrderMainMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.LabOrderMain; - -import java.util.List; - -public interface LabOrderMainMapper { - LabOrderMain selectByPrimaryKey(Long id); - int updateByPrimaryKeySelective(LabOrderMain record); - int insert(LabOrderMain record); - int deleteByPrimaryKey(Long id); - List selectAll(); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/LabRequestMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/LabRequestMapper.java deleted file mode 100644 index 968ce9705..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/LabRequestMapper.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.LabRequest; -import com.openhis.application.domain.entity.LabRequestItem; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import java.util.List; - -@Mapper -public interface LabRequestMapper { - LabRequest selectById(@Param("id") Long id); - List selectItemsByRequestId(@Param("requestId") Long requestId); - int insert(LabRequest request); - int updateById(LabRequest request); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/MedicalRecordMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/MedicalRecordMapper.java deleted file mode 100644 index 4cef99ae6..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/MedicalRecordMapper.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.MedicalRecord; - -import java.util.List; - -public interface MedicalRecordMapper { - List selectPendingByDoctorId(Long doctorId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/OrderDetailMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/OrderDetailMapper.java deleted file mode 100644 index b2bd2e9a2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/OrderDetailMapper.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.OrderDetail; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface OrderDetailMapper { - OrderDetail selectById(@Param("id") Long id); - int insert(OrderDetail detail); - int updateById(OrderDetail detail); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/OrderMainMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/OrderMainMapper.java deleted file mode 100644 index 9d9cff15f..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/OrderMainMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.OrderMain; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface OrderMainMapper { - OrderMain selectById(@Param("id") Long id); - OrderMain selectBySurgeryApplyId(@Param("applyId") Long applyId); - int insert(OrderMain orderMain); - int updateById(OrderMain orderMain); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/OrderVerificationMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/OrderVerificationMapper.java deleted file mode 100644 index d846a9cbb..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/OrderVerificationMapper.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.openhis.application.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface OrderVerificationMapper { - void insertDispensingDetail(@Param("orderId") Long orderId); - void insertDispensingSummary(@Param("orderId") Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/PatientMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/PatientMapper.java deleted file mode 100644 index 0e3fc2583..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/PatientMapper.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.Patient; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface PatientMapper { - Patient selectById(@Param("id") Long id); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/PatientVisitMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/PatientVisitMapper.java deleted file mode 100644 index 735e17c5f..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/PatientVisitMapper.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.PatientVisit; - -import java.util.List; - -public interface PatientVisitMapper { - List selectBatchIds(List ids); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/QueueMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/QueueMapper.java deleted file mode 100644 index f71bf79f3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/QueueMapper.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.dto.QueueQueryDto; -import com.openhis.application.domain.entity.QueueInfo; -import com.openhis.application.domain.entity.QueueRecord; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import java.util.List; - -@Mapper -public interface QueueMapper { - List selectCurrentQueue(@Param("departmentId") Long departmentId); - List selectHistoryQueue(@Param("departmentId") Long departmentId, @Param("startTime") java.util.Date startTime, @Param("endTime") java.util.Date endTime); - List selectQueueList(QueueQueryDto queryDto); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/RefundLogMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/RefundLogMapper.java deleted file mode 100644 index 17957dc83..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/RefundLogMapper.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.RefundLog; -import org.apache.ibatis.annotations.*; - -import java.util.List; - -/** - * 退款日志 Mapper - */ -@Mapper -public interface RefundLogMapper { - - @Insert("INSERT INTO hisdev.refund_log " + - "(order_id, operator, remark, refund_status, refund_time) " + - "VALUES (#{orderId}, #{operator}, #{remark}, #{refundStatus}, #{refundTime})") - @Options(useGeneratedKeys = true, keyProperty = "id") - int insert(RefundLog log); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/RegistrationDetailMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/RegistrationDetailMapper.java deleted file mode 100644 index 6c3b1d380..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/RegistrationDetailMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.RegistrationDetail; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import java.util.List; - -@Mapper -public interface RegistrationDetailMapper { - List selectByRegistrationId(@Param("registrationId") Long registrationId); - int insert(RegistrationDetail detail); - int updateByPrimaryKeySelective(RegistrationDetail detail); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/RegistrationMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/RegistrationMapper.java deleted file mode 100644 index 0f35df4c9..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/RegistrationMapper.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.Registration; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface RegistrationMapper { - Registration selectByPrimaryKey(@Param("id") Long id); - int updateByPrimaryKeySelective(Registration registration); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/ReportCardMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/ReportCardMapper.java deleted file mode 100644 index 777d19416..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/ReportCardMapper.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.application.mapper; - -public interface ReportCardMapper { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/SchedulePoolMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/SchedulePoolMapper.java deleted file mode 100644 index 4642bceae..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/SchedulePoolMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.SchedulePool; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -@Mapper -public interface SchedulePoolMapper { - SchedulePool selectById(@Param("id") Long id); - int incrementBookedNum(@Param("id") Long id); - int decrementBookedNum(@Param("id") Long id); - int updateById(SchedulePool pool); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/ScheduleSlotMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/ScheduleSlotMapper.java deleted file mode 100644 index e8b084539..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/ScheduleSlotMapper.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.ScheduleSlot; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import java.util.List; - -@Mapper -public interface ScheduleSlotMapper { - ScheduleSlot selectById(@Param("id") Long id); - ScheduleSlot selectByOrderId(@Param("orderId") Long orderId); - int incrementBookedNum(@Param("id") Long id, @Param("delta") int delta); - int updateStatus(@Param("id") Long id, @Param("status") int status); - int updateById(ScheduleSlot slot); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/SurgeryApplyMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/SurgeryApplyMapper.java deleted file mode 100644 index 0d473b6be..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/SurgeryApplyMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.SurgeryApply; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import java.util.List; - -@Mapper -public interface SurgeryApplyMapper { - List selectByPatientId(@Param("patientId") String patientId); - SurgeryApply selectById(@Param("id") Long id); - int updateById(SurgeryApply apply); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/TriageQueueMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/TriageQueueMapper.java deleted file mode 100644 index cf28f851a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/TriageQueueMapper.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.dto.QueuePatientDto; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -import java.util.Date; -import java.util.List; - -/** - * 分诊队列 Mapper - * - * 修复 Bug #544: - * 1. 移除原 SQL 中硬编码的 status != 'COMPLETED' 过滤条件 - * 2. 增加 startDate/endDate 动态查询支持,用于历史队列检索 - */ -@Mapper -public interface TriageQueueMapper { - - @Select("") - List selectQueueList(@Param("deptId") Long deptId, - @Param("status") String status, - @Param("startDate") Date startDate, - @Param("endDate") Date endDate); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignMapper.java deleted file mode 100644 index 3ab8f6a78..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignMapper.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.VitalSignRecord; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -import java.util.List; - -/** - * 体征(体温)数据持久层 - * - * 新增接口用于获取患者的体温记录,配合 VitalSignServiceImpl - * 解决前端图表无数据点的问题。 - */ -@Mapper -public interface VitalSignMapper { - - List selectByPatientId(@Param("patientId") Long patientId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignMapper.xml b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignMapper.xml deleted file mode 100644 index e5eca8ecc..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignMapper.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignsMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignsMapper.java deleted file mode 100644 index a08ee23c2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/VitalSignsMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.openhis.application.mapper; - -import com.openhis.application.domain.entity.VitalSignsRecord; -import org.apache.ibatis.annotations.*; - -import java.util.List; - -/** - * 体征记录 Mapper - * 修复 Bug #566 数据查询层:确保按时间正序返回,且仅查询有效状态数据。 - */ -@Mapper -public interface VitalSignsMapper { - - @Insert("INSERT INTO hisdev.vital_signs_record " + - "(patient_id, record_time, temperature, heart_rate, pulse, status, create_time) " + - "VALUES (#{patientId}, #{recordTime}, #{temperature}, #{heartRate}, #{pulse}, #{status}, #{createTime})") - @Options(useGeneratedKeys = true, keyProperty = "id") - int insert(VitalSignsRecord record); - - @Select("SELECT id, patient_id, record_time, temperature, heart_rate, pulse, status " + - "FROM hisdev.vital_signs_record " + - "WHERE patient_id = #{patientId} AND status = '1' " + - "ORDER BY record_time ASC") - List selectByPatientId(@Param("patientId") Long patientId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/DiagnosisService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/DiagnosisService.java deleted file mode 100644 index d1692b3e6..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/DiagnosisService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.dto.DiagnosisSaveDto; -import com.openhis.application.domain.dto.DiagnosisSaveResultDto; - -public interface DiagnosisService { - DiagnosisSaveResultDto saveDiagnosis(DiagnosisSaveDto dto); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/DispensingService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/DispensingService.java deleted file mode 100644 index 84b34d034..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/DispensingService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.openhis.application.service; - -import java.util.List; - -public interface DispensingService { - void batchDispense(List orderDetailIds); - void batchReturn(List detailIds); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/InfectiousDiseaseReportService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/InfectiousDiseaseReportService.java deleted file mode 100644 index 95be3eb06..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/InfectiousDiseaseReportService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.dto.InfectiousDiseaseReportDto; -import com.openhis.application.domain.entity.Diagnosis; - -public interface InfectiousDiseaseReportService { - InfectiousDiseaseReportDto createReport(Long diagnosisId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/LabOrderService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/LabOrderService.java deleted file mode 100644 index 1a28abc8a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/LabOrderService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.openhis.application.service; - -public interface LabOrderService { - void withdraw(Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/LabRequestService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/LabRequestService.java deleted file mode 100644 index 3ae310077..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/LabRequestService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.entity.LabRequest; - -public interface LabRequestService { - LabRequest getRequestWithItems(Long requestId); - void saveRequest(LabRequest request); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/MedicalRecordService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/MedicalRecordService.java deleted file mode 100644 index 7f5858062..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/MedicalRecordService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.entity.MedicalRecord; -import com.openhis.application.vo.PageResult; - -public interface MedicalRecordService { - PageResult getPendingRecords(int page, int size); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OrderMainService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OrderMainService.java deleted file mode 100644 index 4b57b6f44..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OrderMainService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.application.service; - -public interface OrderMainService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OrderService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OrderService.java deleted file mode 100644 index b2a2bee31..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OrderService.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.entity.OrderMain; - -public interface OrderService { - void confirmAppointment(Long orderId, Long schedulePoolId); - void refundOrder(Long orderId); - void payOrder(Long orderId); - OrderMain getOrderById(Long orderId); - void returnOrder(Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OrderVerificationService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OrderVerificationService.java deleted file mode 100644 index cb8c20abd..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OrderVerificationService.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.dto.OrderVerificationDTO; -import java.util.List; - -public interface OrderVerificationService { - List getOrderVerifyList(Long doctorId, String status); - void verifyOrder(Long orderId); - void rollbackOrder(Long orderId); - void executeOrder(Long orderId); - void applySummaryDispensing(Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OutpatientRegistrationService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OutpatientRegistrationService.java deleted file mode 100644 index e807a5ab2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/OutpatientRegistrationService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.entity.OrderMain; - -public interface OutpatientRegistrationService { - void cancelRegistration(Long orderId); - void registerOutpatient(OrderMain order, Long poolId, Long slotId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/QueueService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/QueueService.java deleted file mode 100644 index 09a66c280..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/QueueService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.dto.QueueQueryDto; -import com.openhis.application.domain.entity.QueueInfo; -import com.openhis.application.domain.entity.QueueRecord; -import com.github.pagehelper.PageInfo; -import java.util.Date; -import java.util.List; - -public interface QueueService { - PageInfo getQueueList(QueueQueryDto queryDto); - List getCurrentQueue(Long departmentId); - List getHistoryQueue(Long departmentId, Date startTime, Date endTime); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/RegistrationService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/RegistrationService.java deleted file mode 100644 index 64e844d77..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/RegistrationService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.openhis.application.service; - -public interface RegistrationService { - void cancelRegistration(Long registrationId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/ScheduleSlotService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/ScheduleSlotService.java deleted file mode 100644 index d844be672..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/ScheduleSlotService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.openhis.application.service; - -public interface ScheduleSlotService { - void bookSlot(Long slotId, Long patientId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/SurgeryApplyService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/SurgeryApplyService.java deleted file mode 100644 index 6d837712a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/SurgeryApplyService.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.dto.SurgeryApplyDTO; -import com.openhis.application.domain.entity.SurgeryApply; -import java.util.List; - -public interface SurgeryApplyService { - List getListByPatient(String patientId); - void revokeApply(Long id); - void deleteApply(Long id); - void updateApply(Long id, SurgeryApplyDTO dto); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/SysConfigService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/SysConfigService.java deleted file mode 100644 index b193a1a45..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/SysConfigService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.openhis.application.service; - -public interface SysConfigService { - String getConfigValue(String key, String defaultValue); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/TriageQueueService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/TriageQueueService.java deleted file mode 100644 index 4ef847659..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/TriageQueueService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.dto.TriageQueueQueryDTO; -import com.openhis.application.domain.entity.TriageQueueRecord; -import com.github.pagehelper.PageInfo; - -public interface TriageQueueService { - PageInfo getQueueList(TriageQueueQueryDTO query); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/VitalSignService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/VitalSignService.java deleted file mode 100644 index 66c8d9e1c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/VitalSignService.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.dto.VitalSignDto; - -/** - * 体征业务接口 - * - * 新增方法 getTemperatureChartData 用于前端体温单图表渲染。 - */ -public interface VitalSignService { - - /** - * 获取指定患者的体温折线图数据。 - * - * @param patientId 患者主键 - * @return 包含时间标签和体温数值的 DTO - */ - VitalSignDto getTemperatureChartData(Long patientId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/VitalSignsService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/VitalSignsService.java deleted file mode 100644 index 2a5b1fc4a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/VitalSignsService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.openhis.application.service; - -import com.openhis.application.domain.dto.VitalSignsDto; -import java.util.List; - -public interface VitalSignsService { - boolean saveRecord(VitalSignsDto dto); - List listByPatient(Long patientId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DiagnosisServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DiagnosisServiceImpl.java deleted file mode 100644 index 22df8152e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DiagnosisServiceImpl.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.dto.DiagnosisSaveDto; -import com.openhis.application.domain.dto.DiagnosisSaveResultDto; -import com.openhis.application.domain.entity.Diagnosis; -import com.openhis.application.domain.entity.DiseaseCatalog; -import com.openhis.application.mapper.DiagnosisMapper; -import com.openhis.application.mapper.DiseaseCatalogMapper; -import com.openhis.application.mapper.ReportCardMapper; -import com.openhis.application.service.DiagnosisService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -/** - * 诊断业务实现 - * - * 修复 Bug #573:确诊配置了“报卡类型”的疾病后,保存诊断未自动触发传染病报卡弹窗。 - * 原因:原 saveDiagnosis 方法仅执行了诊断数据的持久化,未对疾病目录的报卡类型进行校验, - * 也未检查是否已存在对应的报卡记录,导致前端无法获取触发弹窗的标识。 - * - * 解决方案:在保存诊断成功后,遍历诊断项,查询疾病目录的报卡类型配置。 - * 若配置了报卡类型且当前患者/就诊次下无对应报卡记录,则将报卡类型加入返回结果。 - * 前端根据返回的报卡类型列表自动弹出填报界面。 - */ -@Service -public class DiagnosisServiceImpl implements DiagnosisService { - - private static final Logger logger = LoggerFactory.getLogger(DiagnosisServiceImpl.class); - - @Autowired - private DiagnosisMapper diagnosisMapper; - @Autowired - private DiseaseCatalogMapper diseaseCatalogMapper; - @Autowired - private ReportCardMapper reportCardMapper; - - @Override - @Transactional(rollbackFor = Exception.class) - public DiagnosisSaveResultDto saveDiagnosis(DiagnosisSaveDto dto) { - // 1. 持久化诊断数据 - if (!CollectionUtils.isEmpty(dto.getDiagnoses())) { - for (Diagnosis diagnosis : dto.getDiagnoses()) { - diagnosisMapper.insert(diagnosis); - } - } - - // 2. 校验报卡类型并收集需触发的报卡 - List reportCardTypes = new ArrayList<>(); - if (!CollectionUtils.isEmpty(dto.getDiagnoses())) { - for (Diagnosis diagnosis : dto.getDiagnoses()) { - DiseaseCatalog catalog = diseaseCatalogMapper.selectById(diagnosis.getDiseaseId()); - if (catalog != null && catalog.getReportCardType() != null) { - // 保留现系统校验规则:若已存在报卡记录则不重复弹出 - boolean hasExistingCard = reportCardMapper.existsByPatientAndDisease( - dto.getPatientId(), dto.getVisitId(), diagnosis.getDiseaseId() - ); - if (!hasExistingCard) { - reportCardTypes.add(catalog.getReportCardType()); - } - } - } - } - - // 去重并返回 - List uniqueTypes = reportCardTypes.stream().distinct().collect(Collectors.toList()); - - DiagnosisSaveResultDto result = new DiagnosisSaveResultDto(); - result.setMessage("诊断已保存并按排序号排序"); - result.setReportCardTypes(uniqueTypes); - return result; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DispensingServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DispensingServiceImpl.java deleted file mode 100644 index 3dc74a315..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/DispensingServiceImpl.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.entity.DispensingDetail; -import com.openhis.application.domain.entity.DispensingSummary; -import com.openhis.application.mapper.DispensingDetailMapper; -import com.openhis.application.mapper.DispensingSummaryMapper; -import com.openhis.application.service.DispensingService; -import com.openhis.application.service.SysConfigService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Date; -import java.util.List; - -/** - * 住院发退药业务实现 - */ -@Service -public class DispensingServiceImpl implements DispensingService { - - private static final Logger log = LoggerFactory.getLogger(DispensingServiceImpl.class); - - private final DispensingDetailMapper dispensingDetailMapper; - private final DispensingSummaryMapper dispensingSummaryMapper; - private final SysConfigService sysConfigService; - - public DispensingServiceImpl(DispensingDetailMapper dispensingDetailMapper, - DispensingSummaryMapper dispensingSummaryMapper, - SysConfigService sysConfigService) { - this.dispensingDetailMapper = dispensingDetailMapper; - this.dispensingSummaryMapper = dispensingSummaryMapper; - this.sysConfigService = sysConfigService; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void batchDispense(List orderDetailIds) { - // 获取配置: 病区护士执行提交药品模式 - String mode = sysConfigService.getConfigValue("pharmacy", "dispenseMode"); - - // 生成发药明细 - for (Long detailId : orderDetailIds) { - DispensingDetail detail = dispensingDetailMapper.selectById(detailId); - if (detail != null) { - detail.setApplyStatus(1); - detail.setOrderId(detailId); - detail.setCreateTime(new Date()); - dispensingDetailMapper.insert(detail); - } - } - - // 生成发药汇总 - DispensingSummary summary = new DispensingSummary(); - summary.setApplyStatus(1); - summary.setCreateTime(new Date()); - dispensingSummaryMapper.insert(summary); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void batchReturn(List detailIds) { - for (Long detailId : detailIds) { - DispensingDetail detail = dispensingDetailMapper.selectById(detailId); - if (detail != null) { - detail.setApplyStatus(2); - dispensingDetailMapper.updateById(detail); - } - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/InfectiousDiseaseReportServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/InfectiousDiseaseReportServiceImpl.java deleted file mode 100644 index 54e249ffc..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/InfectiousDiseaseReportServiceImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.dto.InfectiousDiseaseReportDto; -import com.openhis.application.domain.entity.Diagnosis; -import com.openhis.application.domain.entity.Patient; -import com.openhis.application.mapper.DiagnosisMapper; -import com.openhis.application.mapper.PatientMapper; -import com.openhis.application.service.InfectiousDiseaseReportService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * 传染病报告卡业务实现 - * - * 修复 Bug #572:原逻辑在初始化报卡 DTO 时仅填充了诊断基础信息, - * 遗漏了患者档案中的“现住址”与“职业”字段同步,导致前端弹窗显示为空。 - * 现增加患者档案查询与字段映射逻辑。 - */ -@Service -public class InfectiousDiseaseReportServiceImpl implements InfectiousDiseaseReportService { - - private static final Logger logger = LoggerFactory.getLogger(InfectiousDiseaseReportServiceImpl.class); - - @Autowired - private PatientMapper patientMapper; - - @Autowired - private DiagnosisMapper diagnosisMapper; - - @Override - public InfectiousDiseaseReportDto generateReportCard(Long patientId, Long diagnosisId) { - InfectiousDiseaseReportDto reportDto = new InfectiousDiseaseReportDto(); - - // 1. 填充诊断相关信息 - Diagnosis diagnosis = diagnosisMapper.selectById(diagnosisId); - if (diagnosis != null) { - reportDto.setDiagnosisName(diagnosis.getName()); - reportDto.setDiagnosisTime(diagnosis.getCreateTime()); - reportDto.setDiagnosisCode(diagnosis.getCode()); - } - - // 2. 修复 Bug #572:自动同步并填充患者档案中的“现住址”与“职业”信息 - Patient patient = patientMapper.selectById(patientId); - if (patient != null) { - reportDto.setPatientName(patient.getName()); - reportDto.setPatientIdCard(patient.getIdCard()); - reportDto.setGender(patient.getGender()); - reportDto.setBirthDate(patient.getBirthDate()); - - // 核心修复:映射现住址与职业 - reportDto.setCurrentAddress(patient.getCurrentAddress()); - reportDto.setOccupation(patient.getOccupation()); - - logger.info("已自动同步患者[{}]档案信息至传染病报告卡,现住址:[{}],职业:[{}]", - patientId, patient.getCurrentAddress(), patient.getOccupation()); - } else { - logger.warn("未找到患者[{}]档案信息,报告卡患者基础字段将为空", patientId); - } - - return reportDto; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/LabOrderServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/LabOrderServiceImpl.java deleted file mode 100644 index c3dc57d65..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/LabOrderServiceImpl.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.constants.LabOrderStatus; -import com.openhis.application.domain.dto.LabOrderDto; -import com.openhis.application.domain.entity.LabOrderDetail; -import com.openhis.application.domain.entity.LabOrderMain; -import com.openhis.application.exception.BusinessException; -import com.openhis.application.mapper.LabOrderDetailMapper; -import com.openhis.application.mapper.LabOrderMainMapper; -import com.openhis.application.service.LabOrderService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Date; -import java.util.List; - -/** - * 检验申请业务实现 - * - * 修复 Bug #571:撤回已发药/已检验的检验申请时出现错误提示。 - * - * 关键修复点: - * 1. 在撤回前统一校验不可撤回的状态集合(FINISHED、DISPENSED、VERIFIED、CANCELLED)。 - * 2. 防御性检查检验明细是否存在,避免 NullPointerException。 - * 3. 将撤回操作放入同一 @Transactional 方法,确保数据一致性。 - * 4. 添加详细日志,便于运维定位问题。 - */ -@Service -public class LabOrderServiceImpl implements LabOrderService { - - private static final Logger logger = LoggerFactory.getLogger(LabOrderServiceImpl.class); - - private final LabOrderMainMapper labOrderMainMapper; - private final LabOrderDetailMapper labOrderDetailMapper; - - public LabOrderServiceImpl(LabOrderMainMapper labOrderMainMapper, - LabOrderDetailMapper labOrderDetailMapper) { - this.labOrderMainMapper = labOrderMainMapper; - this.labOrderDetailMapper = labOrderDetailMapper; - } - - // ----------------------------------------------------------------------- - // 其它业务方法(省略)... - // ----------------------------------------------------------------------- - - /** - * 撤回检验申请 - * - * @param orderId 检验申请主单ID - * @throws BusinessException 若订单状态不允许撤回或内部异常 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void withdraw(Long orderId) { - logger.info("Attempting to withdraw lab order, orderId={}", orderId); - - // 1. 查询主单,若不存在直接抛异常 - LabOrderMain main = labOrderMainMapper.selectByPrimaryKey(orderId); - if (main == null) { - logger.warn("Lab order not found, orderId={}", orderId); - throw new BusinessException("检验申请不存在,无法撤回"); - } - - // 2. 校验当前状态是否允许撤回 - // 允许撤回的状态仅为:已提交(SUBMITTED)和待审核(PENDING_REVIEW) - // 其它任何状态均视为不可撤回 - LabOrderStatus currentStatus = LabOrderStatus.fromCode(main.getStatus()); - if (!LabOrderStatus.SUBMITTED.equals(currentStatus) && - !LabOrderStatus.PENDING_REVIEW.equals(currentStatus)) { - logger.warn("Lab order cannot be withdrawn, orderId={}, status={}", orderId, currentStatus); - throw new BusinessException("当前检验申请状态不允许撤回"); - } - - // 3. 更新主单状态为已撤回,并记录撤回时间、操作人(此处简化为系统) - main.setStatus(LabOrderStatus.WITHDRAWN.getCode()); - main.setWithdrawTime(new Date()); - main.setWithdrawBy("system"); // 实际应取当前登录用户 - int updatedMain = labOrderMainMapper.updateByPrimaryKeySelective(main); - if (updatedMain != 1) { - logger.error("Failed to update lab order main status to withdrawn, orderId={}", orderId); - throw new BusinessException("撤回检验申请失败,请稍后重试"); - } - - // 4. 处理明细:若明细已被删除(如已发药后被清理),则不做更新,防止 NPE - List details = labOrderDetailMapper.selectByOrderId(orderId); - if (details != null && !details.isEmpty()) { - for (LabOrderDetail detail : details) { - // 只对未完成的明细标记为撤回 - LabOrderStatus detailStatus = LabOrderStatus.fromCode(detail.getStatus()); - if (LabOrderStatus.SUBMITTED.equals(detailStatus) || - LabOrderStatus.PENDING_REVIEW.equals(detailStatus)) { - detail.setStatus(LabOrderStatus.WITHDRAWN.getCode()); - detail.setWithdrawTime(new Date()); - detail.setWithdrawBy("system"); - labOrderDetailMapper.updateByPrimaryKeySelective(detail); - } - } - } else { - logger.info("No lab order details found for orderId={}, may have been cleaned up already.", orderId); - } - - logger.info("Lab order withdrawn successfully, orderId={}", orderId); - } - - // ----------------------------------------------------------------------- - // 其它实现细节(省略)... - // ----------------------------------------------------------------------- -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/LabRequestServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/LabRequestServiceImpl.java deleted file mode 100644 index b3b932f59..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/LabRequestServiceImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.entity.LabRequest; -import com.openhis.application.mapper.LabRequestMapper; -import com.openhis.application.service.LabRequestService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -public class LabRequestServiceImpl implements LabRequestService { - - private static final Logger log = LoggerFactory.getLogger(LabRequestServiceImpl.class); - - private final LabRequestMapper labRequestMapper; - - public LabRequestServiceImpl(LabRequestMapper labRequestMapper) { - this.labRequestMapper = labRequestMapper; - } - - @Override - public LabRequest getRequestWithItems(Long requestId) { - LabRequest request = labRequestMapper.selectById(requestId); - if (request != null) { - request.setItems(labRequestMapper.selectItemsByRequestId(requestId)); - } - return request; - } - - @Override - public void saveRequest(LabRequest request) { - if (request.getId() == null) { - labRequestMapper.insert(request); - } else { - labRequestMapper.updateById(request); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/MedicalRecordServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/MedicalRecordServiceImpl.java deleted file mode 100644 index 7776b58ca..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/MedicalRecordServiceImpl.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.openhis.application.service.impl; - -import com.github.pagehelper.Page; -import com.github.pagehelper.PageHelper; -import com.openhis.application.domain.dto.MedicalRecordDto; -import com.openhis.application.domain.entity.MedicalRecord; -import com.openhis.application.domain.entity.PatientVisit; -import com.openhis.application.mapper.MedicalRecordMapper; -import com.openhis.application.mapper.PatientVisitMapper; -import com.openhis.application.service.MedicalRecordService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * 病历业务实现 - * - * 修复 Bug #562:待写病历数据加载时间超过2秒一直加载 - * 根因:原实现未启用分页,且使用循环查询患者就诊信息导致 N+1 问题,全表扫描耗时过长。 - * 修复方案: - * 1. 引入 PageHelper 强制分页,限制单次查询数据量。 - * 2. 使用批量查询替代循环查询,消除 N+1 性能瓶颈。 - * 3. 仅查询必要字段,减少网络传输与序列化开销。 - */ -@Service -public class MedicalRecordServiceImpl implements MedicalRecordService { - - private static final Logger logger = LoggerFactory.getLogger(MedicalRecordServiceImpl.class); - - @Autowired - private MedicalRecordMapper medicalRecordMapper; - - @Autowired - private PatientVisitMapper patientVisitMapper; - - @Override - public Page getPendingMedicalRecords(Long doctorId, Integer pageNum, Integer pageSize) { - // 1. 强制分页,避免全表扫描导致 >2s 响应 - PageHelper.startPage(pageNum, pageSize); - - // 2. 仅查询待写状态(status='PENDING')且归属当前医生的病历,按需加载字段 - List records = medicalRecordMapper.selectPendingByDoctorId(doctorId); - Page page = (Page) records; - - if (CollectionUtils.isEmpty(records)) { - return new Page<>(pageNum, pageSize, 0); - } - - // 3. 批量获取就诊信息,消除 N+1 查询 - List visitIds = records.stream() - .map(MedicalRecord::getVisitId) - .distinct() - .collect(Collectors.toList()); - - Map visitMap = patientVisitMapper.selectBatchIds(visitIds).stream() - .collect(Collectors.toMap(PatientVisit::getId, v -> v)); - - // 4. 组装 DTO - List dtoList = records.stream().map(record -> { - MedicalRecordDto dto = new MedicalRecordDto(); - dto.setId(record.getId()); - dto.setPatientName(record.getPatientName()); - dto.setVisitNo(record.getVisitNo()); - dto.setStatus(record.getStatus()); - dto.setCreateTime(record.getCreateTime()); - - PatientVisit visit = visitMap.get(record.getVisitId()); - if (visit != null) { - dto.setDepartmentName(visit.getDepartmentName()); - dto.setDiagnosis(visit.getDiagnosis()); - } - return dto; - }).collect(Collectors.toList()); - - // 5. 返回分页结果 - Page resultPage = new Page<>(pageNum, pageSize); - resultPage.setTotal(page.getTotal()); - resultPage.addAll(dtoList); - return resultPage; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java deleted file mode 100644 index 7c030eb75..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.constants.OrderStatus; -import com.openhis.application.domain.entity.OrderMain; -import com.openhis.application.domain.entity.SchedulePool; -import com.openhis.application.exception.BusinessException; -import com.openhis.application.mapper.OrderMainMapper; -import com.openhis.application.mapper.SchedulePoolMapper; -import com.openhis.application.service.OrderService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Date; - -@Service -public class OrderServiceImpl implements OrderService { - - private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class); - - @Autowired - private OrderMainMapper orderMainMapper; - @Autowired - private SchedulePoolMapper schedulePoolMapper; - - @Override - @Transactional(rollbackFor = Exception.class) - public void confirmAppointment(Long orderId, Long schedulePoolId) { - OrderMain order = orderMainMapper.selectById(orderId); - if (order == null) { - throw new BusinessException("预约订单不存在"); - } - order.setStatus(OrderStatus.BOOKED); - order.setUpdateTime(new Date()); - orderMainMapper.updateById(order); - - if (schedulePoolId != null) { - SchedulePool pool = schedulePoolMapper.selectById(schedulePoolId); - if (pool != null) { - int currentBooked = pool.getBookedNum() == null ? 0 : pool.getBookedNum(); - pool.setBookedNum(currentBooked + 1); - schedulePoolMapper.updateById(pool); - logger.info("预约成功,号源池 booked_num 已实时累加: poolId={}, newBookedNum={}", schedulePoolId, pool.getBookedNum()); - } else { - logger.warn("预约成功但未找到对应号源池记录,跳过 booked_num 更新: poolId={}", schedulePoolId); - } - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void refundOrder(Long orderId) { - OrderMain order = orderMainMapper.selectById(orderId); - if (order == null) { - throw new BusinessException("订单不存在"); - } - order.setStatus(OrderStatus.REFUNDED); - order.setUpdateTime(new Date()); - orderMainMapper.updateById(order); - logger.info("订单已退款: orderId={}", orderId); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void payOrder(Long orderId) { - OrderMain order = orderMainMapper.selectById(orderId); - if (order == null) { - throw new BusinessException("订单不存在"); - } - order.setStatus(OrderStatus.PAID); - order.setUpdateTime(new Date()); - orderMainMapper.updateById(order); - logger.info("订单已支付: orderId={}", orderId); - } - - @Override - public OrderMain getOrderById(Long orderId) { - return orderMainMapper.selectById(orderId); - } - - @Override - public void returnOrder(Long orderId) { - OrderMain order = orderMainMapper.selectById(orderId); - if (order != null) { - order.setStatus(OrderStatus.REFUNDED); - order.setUpdateTime(new Date()); - orderMainMapper.updateById(order); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderVerificationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderVerificationServiceImpl.java deleted file mode 100644 index 60ef972e0..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderVerificationServiceImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.dto.OrderVerificationDTO; -import com.openhis.application.service.OrderVerificationService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import java.util.Collections; -import java.util.List; - -@Service -public class OrderVerificationServiceImpl implements OrderVerificationService { - - private static final Logger log = LoggerFactory.getLogger(OrderVerificationServiceImpl.class); - - @Override - public List getOrderVerifyList(Long doctorId, String status) { - log.info("getOrderVerifyList called: doctorId={}, status={}", doctorId, status); - return Collections.emptyList(); - } - - @Override - public void verifyOrder(Long orderId) { - log.info("verifyOrder called: orderId={}", orderId); - } - - @Override - public void rollbackOrder(Long orderId) { - log.info("rollbackOrder called: orderId={}", orderId); - } - - @Override - public void executeOrder(Long orderId) { - log.info("executeOrder called: orderId={}", orderId); - } - - @Override - public void applySummaryDispensing(Long orderId) { - log.info("applySummaryDispensing called for orderId={}", orderId); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OutpatientRegistrationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OutpatientRegistrationServiceImpl.java deleted file mode 100644 index c79faf1ab..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OutpatientRegistrationServiceImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.mapper.*; -import com.openhis.application.domain.entity.*; -import com.openhis.application.service.OutpatientRegistrationService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Date; - -@Service -public class OutpatientRegistrationServiceImpl implements OutpatientRegistrationService { - - private final OrderMainMapper orderMainMapper; - private final AdmScheduleSlotMapper admScheduleSlotMapper; - private final AdmSchedulePoolMapper admSchedulePoolMapper; - private final RefundLogMapper refundLogMapper; - - public OutpatientRegistrationServiceImpl(OrderMainMapper orderMainMapper, - AdmScheduleSlotMapper admScheduleSlotMapper, - AdmSchedulePoolMapper admSchedulePoolMapper, - RefundLogMapper refundLogMapper) { - this.orderMainMapper = orderMainMapper; - this.admScheduleSlotMapper = admScheduleSlotMapper; - this.admSchedulePoolMapper = admSchedulePoolMapper; - this.refundLogMapper = refundLogMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void cancelRegistration(Long orderId) { - // 1. 查询原订单 - OrderMain order = orderMainMapper.selectById(orderId); - if (order == null) { - throw new RuntimeException("挂号订单不存在"); - } - - // 2. 更新 order_main 表 - OrderMain updateOrder = new OrderMain(); - updateOrder.setId(orderId); - updateOrder.setStatus("0"); // 状态变更为 0(已取消) - updateOrder.setPayStatus(3); // 支付状态变更为 3(已退费) - updateOrder.setCancelTime(new Date()); // 写入当前取消时间 - updateOrder.setCancelReason("诊前退号"); // 修正退号原因 - orderMainMapper.updateById(updateOrder); - - // 3. 更新 adm_schedule_slot 表 (回滚号源) - if (order.getSlotId() != null) { - AdmScheduleSlot updateSlot = new AdmScheduleSlot(); - updateSlot.setId(order.getSlotId()); - // 将已预约的号源状态回滚为“可预约”(status = 1) - updateSlot.setStatus(1); - admScheduleSlotMapper.updateById(updateSlot); - } - - // 4. 更新 adm_schedule_pool 表 (已预约数回滚) - if (order.getPoolId() != null) { - // 已预约数 -1 - admSchedulePoolMapper.decrementBookedNum(order.getPoolId()); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void registerOutpatient(OrderMain order, Long poolId, Long slotId) { - // 保存挂号订单 - orderMainMapper.insert(order); - - // 5. 更新号源槽状态为“已预约”(status = 2) - if (slotId != null) { - AdmScheduleSlot slot = new AdmScheduleSlot(); - slot.setId(slotId); - slot.setStatus(2); // 已预约 - admScheduleSlotMapper.updateById(slot); - } - - // 6. 实时累加号源池的已预约数 (booked_num) - if (poolId != null) { - // 这里使用乐观锁/原子更新,确保并发安全 - admSchedulePoolMapper.incrementBookedNum(poolId); - } - } - - // 其它业务方法保持不变... -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/QueueServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/QueueServiceImpl.java deleted file mode 100644 index e8419a309..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/QueueServiceImpl.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.dto.QueueQueryDto; -import com.openhis.application.domain.entity.QueueInfo; -import com.openhis.application.domain.entity.QueueRecord; -import com.openhis.application.mapper.QueueMapper; -import com.openhis.application.service.QueueService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import com.github.pagehelper.PageHelper; -import com.github.pagehelper.PageInfo; - -import java.util.Date; -import java.util.List; - -@Service -public class QueueServiceImpl implements QueueService { - - private static final Logger log = LoggerFactory.getLogger(QueueServiceImpl.class); - - private final QueueMapper queueMapper; - - public QueueServiceImpl(QueueMapper queueMapper) { - this.queueMapper = queueMapper; - } - - @Override - public PageInfo getQueueList(QueueQueryDto queryDto) { - if (queryDto.getPageNum() != null && queryDto.getPageSize() != null) { - PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize()); - } - List list = queueMapper.selectQueueList(queryDto); - return new PageInfo<>(list); - } - - @Override - public List getCurrentQueue(Long departmentId) { - return queueMapper.selectCurrentQueue(departmentId); - } - - @Override - public List getHistoryQueue(Long departmentId, Date startTime, Date endTime) { - return queueMapper.selectHistoryQueue(departmentId, startTime, endTime); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java deleted file mode 100644 index 357f5482b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.entity.Registration; -import com.openhis.application.domain.entity.RegistrationDetail; -import com.openhis.application.domain.entity.ScheduleSlot; -import com.openhis.application.mapper.RegistrationMapper; -import com.openhis.application.mapper.RegistrationDetailMapper; -import com.openhis.application.mapper.ScheduleSlotMapper; -import com.openhis.application.exception.BusinessException; -import com.openhis.application.service.RegistrationService; -import com.openhis.application.constants.RegistrationStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * 门诊挂号业务实现 - * - * 修复 Bug #506、#575、#574。 - * - * 1. 退号时同步更新 registration_main 与 registration_detail 状态。 - * 2. 预约成功后实时累加 adm_schedule_pool.booked_num。 - * 3. 预约签到缴费成功后,将对应的 adm_schedule_slot.status 更新为 3(已取)。 - */ -@Service -public class RegistrationServiceImpl implements RegistrationService { - - private static final Logger log = LoggerFactory.getLogger(RegistrationServiceImpl.class); - - private final RegistrationMapper registrationMapper; - private final RegistrationDetailMapper registrationDetailMapper; - private final ScheduleSlotMapper scheduleSlotMapper; - - public RegistrationServiceImpl(RegistrationMapper registrationMapper, - RegistrationDetailMapper registrationDetailMapper, - ScheduleSlotMapper scheduleSlotMapper) { - this.registrationMapper = registrationMapper; - this.registrationDetailMapper = registrationDetailMapper; - this.scheduleSlotMapper = scheduleSlotMapper; - } - - /** - * 退号业务(已在 Bug #506 中实现)。 - * - * 退号需要满足以下 PRD 定义: - * - 主表 registration_main.status 必须更新为 {@link RegistrationStatus#CANCELLED}(值 4)。 - * - 所有关联的 registration_detail.status 也必须同步更新为同一状态。 - * - 已占用的号源(ScheduleSlot)如果在“已预约”状态(status=2),需要回滚已预约数量 - * (即 booked_num - 1),并将号源状态恢复为“可预约”(status=1)。 - * - * 该方法在事务内执行,确保多表状态保持一致。 - * - * @param registrationId 挂号主键 ID - */ - @Transactional - @Override - public void cancelRegistration(Long registrationId) { - // 1. 查询挂号主记录 - Registration registration = registrationMapper.selectByPrimaryKey(registrationId); - if (registration == null) { - throw new BusinessException("挂号记录不存在"); - } - - // 2. 判断当前状态是否允许退号 - // 仅在已预约(status=2)或已签到(status=3)时允许退号,已取消或已完成的不能再次退号 - if (!String.valueOf(RegistrationStatus.RESERVED).equals(registration.getStatus()) && - !String.valueOf(RegistrationStatus.SIGNED).equals(registration.getStatus())) { - throw new BusinessException("当前挂号状态不允许退号"); - } - - // 3. 更新主表状态为已取消 - registration.setStatus(String.valueOf(RegistrationStatus.CANCELLED)); - int mainUpdated = registrationMapper.updateByPrimaryKeySelective(registration); - if (mainUpdated != 1) { - throw new BusinessException("挂号主表状态更新失败"); - } - - // 4. 更新所有明细状态为已取消 - List details = registrationDetailMapper.selectByRegistrationId(registrationId); - for (RegistrationDetail detail : details) { - detail.setStatus(String.valueOf(RegistrationStatus.CANCELLED)); - int detailUpdated = registrationDetailMapper.updateByPrimaryKeySelective(detail); - if (detailUpdated != 1) { - throw new BusinessException("挂号明细状态更新失败,detailId=" + detail.getId()); - } - - // 5. 处理关联的号源(ScheduleSlot) - // 只对仍处于“已预约”状态的号源进行回滚 - ScheduleSlot slot = scheduleSlotMapper.selectById(detail.getScheduleSlotId()); - if (slot != null && slot.getStatus() != null && "2".equals(slot.getStatus())) { // 2 = 已预约 - // 已预约数量回滚 - scheduleSlotMapper.incrementBookedNum(slot.getId(), -1); - // 将号源状态恢复为“可预约”(1) - scheduleSlotMapper.updateStatus(slot.getId(), 1); - } - } - - log.info("挂号退号成功,registrationId={}, 影响明细数={}", registrationId, details.size()); - } - - // 其它业务方法保持不变... -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/ScheduleSlotServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/ScheduleSlotServiceImpl.java deleted file mode 100644 index 9f7f5d2d0..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/ScheduleSlotServiceImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.constants.ScheduleSlotStatus; -import com.openhis.application.domain.entity.ScheduleSlot; -import com.openhis.application.mapper.ScheduleSlotMapper; -import com.openhis.application.service.ScheduleSlotService; -import com.openhis.application.exception.BusinessException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Date; - -/** - * 门诊号源业务实现 - * - * 修复 Bug #570:修正预约成功后的状态赋值逻辑。 - * 原逻辑错误地将状态设置为 LOCKED,导致前端"已预约"筛选器无法匹配数据。 - * 现统一使用 BOOKED 状态,并移除 LOCKED 分支。 - */ -@Service -public class ScheduleSlotServiceImpl implements ScheduleSlotService { - - private static final Logger logger = LoggerFactory.getLogger(ScheduleSlotServiceImpl.class); - - @Autowired - private ScheduleSlotMapper scheduleSlotMapper; - - @Override - @Transactional(rollbackFor = Exception.class) - public void bookSlot(Long slotId, Long patientId) { - ScheduleSlot slot = scheduleSlotMapper.selectById(slotId); - if (slot == null) { - throw new BusinessException("号源不存在"); - } - - // 仅允许可预约状态的号源被锁定/预约 - // slot.getStatus() is String, ScheduleSlotStatus.AVAILABLE.getCode() is int - if (!String.valueOf(ScheduleSlotStatus.AVAILABLE.getCode()).equals(slot.getStatus())) { - throw new BusinessException("该号源当前不可预约"); - } - - // 修复 Bug #570:预约成功后直接更新为"已预约"(BOOKED) - slot.setStatus(String.valueOf(ScheduleSlotStatus.BOOKED.getCode())); - slot.setPatientId(patientId); - slot.setUpdateTime(new Date()); - - int updated = scheduleSlotMapper.updateById(slot); - if (updated <= 0) { - throw new BusinessException("预约状态更新失败,请重试"); - } - - logger.info("号源预约成功: slotId={}, patientId={}, status=BOOKED", slotId, patientId); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/SurgeryApplyServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/SurgeryApplyServiceImpl.java deleted file mode 100644 index b106bec8f..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/SurgeryApplyServiceImpl.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.dto.SurgeryApplyDTO; -import com.openhis.application.domain.entity.OrderMain; -import com.openhis.application.domain.entity.SurgeryApply; -import com.openhis.application.exception.BusinessException; -import com.openhis.application.mapper.OrderMainMapper; -import com.openhis.application.mapper.SurgeryApplyMapper; -import com.openhis.application.service.SurgeryApplyService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -@Service -public class SurgeryApplyServiceImpl implements SurgeryApplyService { - - private final SurgeryApplyMapper surgeryApplyMapper; - private final OrderMainMapper orderMainMapper; - - public SurgeryApplyServiceImpl(SurgeryApplyMapper surgeryApplyMapper, OrderMainMapper orderMainMapper) { - this.surgeryApplyMapper = surgeryApplyMapper; - this.orderMainMapper = orderMainMapper; - } - - @Override - public List getListByPatient(String patientId) { - return surgeryApplyMapper.selectByPatientId(patientId); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void revokeApply(Long applyId) { - SurgeryApply apply = surgeryApplyMapper.selectById(applyId); - if (apply == null) throw new BusinessException("手术申请单不存在"); - if (!"1".equals(apply.getStatus())) throw new BusinessException("仅已签发状态可撤回"); - - // 校验护士是否已校对 (假设 order_main.status >= 2 表示已校对/已执行) - OrderMain relatedOrder = orderMainMapper.selectBySurgeryApplyId(applyId); - if (relatedOrder != null && Integer.parseInt(relatedOrder.getStatus() != null ? relatedOrder.getStatus() : "0") >= 2) { - throw new BusinessException("撤回失败!该手术申请已由病区护士已校对,请致电病区护士处理。"); - } - - // 状态回滚至 0-待签发 - apply.setStatus("0"); - surgeryApplyMapper.updateById(apply); - - // 联级更新对应医嘱状态为待签发 - if (relatedOrder != null) { - relatedOrder.setStatus("0"); - orderMainMapper.updateById(relatedOrder); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void deleteApply(Long applyId) { - SurgeryApply apply = surgeryApplyMapper.selectById(applyId); - if (apply == null) throw new BusinessException("手术申请单不存在"); - if (!"0".equals(apply.getStatus())) throw new BusinessException("仅待签发状态可删除"); - - // 逻辑删除/作废:状态置为 7-已作废 - apply.setStatus("7"); - surgeryApplyMapper.updateById(apply); - - // 联级作废对应医嘱 - OrderMain relatedOrder = orderMainMapper.selectBySurgeryApplyId(applyId); - if (relatedOrder != null) { - relatedOrder.setStatus("7"); - orderMainMapper.updateById(relatedOrder); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateApply(Long applyId, SurgeryApplyDTO dto) { - SurgeryApply apply = surgeryApplyMapper.selectById(applyId); - if (apply == null || !"0".equals(apply.getStatus())) { - throw new BusinessException("仅待签发状态可编辑"); - } - // 映射 DTO 到 Entity 并更新 - apply.setSurgeryName(dto.getSurgeryName()); - apply.setDiagnosis(dto.getDiagnosis()); - apply.setRemark(dto.getRemark()); - surgeryApplyMapper.updateById(apply); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/TriageQueueServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/TriageQueueServiceImpl.java deleted file mode 100644 index c4bd69ca5..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/TriageQueueServiceImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.dto.TriageQueueQueryDTO; -import com.openhis.application.domain.entity.TriageQueueRecord; -import com.openhis.application.mapper.TriageQueueMapper; -import com.openhis.application.service.TriageQueueService; -import com.github.pagehelper.PageHelper; -import com.github.pagehelper.PageInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -public class TriageQueueServiceImpl implements TriageQueueService { - - private static final Logger log = LoggerFactory.getLogger(TriageQueueServiceImpl.class); - - private final TriageQueueMapper triageQueueMapper; - - public TriageQueueServiceImpl(TriageQueueMapper triageQueueMapper) { - this.triageQueueMapper = triageQueueMapper; - } - - @Override - public PageInfo getQueueList(TriageQueueQueryDTO queryDTO) { - if (queryDTO.getPageNum() != null && queryDTO.getPageSize() != null) { - PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize()); - } - List list = triageQueueMapper.selectQueueList(queryDTO); - return new PageInfo<>(list); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignServiceImpl.java deleted file mode 100644 index 29245b580..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignServiceImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.dto.VitalSignDto; -import com.openhis.application.mapper.VitalSignMapper; -import com.openhis.application.service.VitalSignService; -import org.springframework.stereotype.Service; - -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.stream.Collectors; - -/** - * 体征(尤其是体温)业务实现 - * - * 关键修复点(Bug #566): - * 1. 读取体温记录后,按时间升序排序。 - * 2. 将时间格式化为前端图表需要的 “HH:mm” 形式。 - * 3. 将体温数值抽取为 Double 列表。 - * 4. 将上述两列封装进 VitalSignDto 返回,避免前端再次自行转换导致空数据。 - */ -@Service -public class VitalSignServiceImpl implements VitalSignService { - - private final VitalSignMapper vitalSignMapper; - private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); - - public VitalSignServiceImpl(VitalSignMapper vitalSignMapper) { - this.vitalSignMapper = vitalSignMapper; - } - - @Override - public VitalSignDto getTemperatureChartData(Long patientId) { - // 从数据库查询原始体温记录(假设返回的实体包含 time(java.util.Date)和 temperature(BigDecimal)) - List records = vitalSignMapper.selectByPatientId(patientId); - - // 按时间升序排列,防止前端出现乱序 - records.sort((r1, r2) -> r1.getTime().compareTo(r2.getTime())); - - List timeLabels = records.stream() - .map(r -> TIME_FORMATTER.format(r.getTime().toInstant() - .atZone(java.time.ZoneId.systemDefault()).toLocalTime())) - .collect(Collectors.toList()); - - List temperaturePoints = records.stream() - .map(r -> r.getTemperature() != null ? r.getTemperature().doubleValue() : null) - .collect(Collectors.toList()); - - VitalSignDto dto = new VitalSignDto(); - dto.setPatientId(patientId); - dto.setTimeLabels(timeLabels); - dto.setTemperaturePoints(temperaturePoints); - // rawDataJson 仍保留原始 JSON(若有需要),这里暂时设为空字符串 - dto.setRawDataJson(""); - return dto; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignsServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignsServiceImpl.java deleted file mode 100644 index 720906cbf..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignsServiceImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.dto.VitalSignsDto; -import com.openhis.application.domain.entity.VitalSignsRecord; -import com.openhis.application.mapper.VitalSignsMapper; -import com.openhis.application.service.VitalSignsService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.text.SimpleDateFormat; -import java.util.List; -import java.util.stream.Collectors; - -@Service -public class VitalSignsServiceImpl implements VitalSignsService { - - private static final Logger logger = LoggerFactory.getLogger(VitalSignsServiceImpl.class); - private final VitalSignsMapper vitalSignsMapper; - - public VitalSignsServiceImpl(VitalSignsMapper vitalSignsMapper) { - this.vitalSignsMapper = vitalSignsMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public boolean saveRecord(VitalSignsDto dto) { - VitalSignsRecord record = new VitalSignsRecord(); - record.setPatientId(dto.getPatientId()); - try { - if (dto.getRecordTime() != null) { - record.setRecordTime(new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(dto.getRecordTime())); - } - } catch (Exception e) { - logger.warn("Failed to parse recordTime: {}", dto.getRecordTime()); - } - record.setTemperature(dto.getTemperature()); - record.setHeartRate(dto.getHeartRate()); - record.setPulse(dto.getPulse()); - record.setStatus("1"); - record.setCreateTime(new java.util.Date()); - int rows = vitalSignsMapper.insert(record); - logger.info("体征数据保存成功, patientId={}, rows={}", dto.getPatientId(), rows); - return rows > 0; - } - - @Override - public List listByPatient(Long patientId) { - List records = vitalSignsMapper.selectByPatientId(patientId); - return records.stream().map(this::toDto).collect(Collectors.toList()); - } - - private VitalSignsDto toDto(VitalSignsRecord record) { - VitalSignsDto dto = new VitalSignsDto(); - dto.setId(record.getId()); - dto.setPatientId(record.getPatientId()); - dto.setRecordTime(record.getRecordTime() != null ? - new SimpleDateFormat("MM-dd HH:mm").format(record.getRecordTime()) : null); - dto.setTemperature(record.getTemperature()); - dto.setHeartRate(record.getHeartRate()); - dto.setPulse(record.getPulse()); - return dto; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/util/DispenseStatusMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/util/DispenseStatusMapper.java deleted file mode 100644 index 8760f2d73..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/util/DispenseStatusMapper.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.openhis.application.util; - -public class DispenseStatusMapper { - public static String mapStatus(String status) { return status; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/util/OrderStatusMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/util/OrderStatusMapper.java deleted file mode 100644 index b7abe9ff1..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/util/OrderStatusMapper.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.openhis.application.util; - -public class OrderStatusMapper { - public static String mapStatus(String status) { return status; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/vo/PageResult.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/vo/PageResult.java deleted file mode 100644 index 3a47b2492..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/vo/PageResult.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.openhis.application.vo; - -import java.util.List; - -public class PageResult { - private int page; - private int size; - private long total; - private List records; - - public PageResult() {} - public int getPage() { return page; } - public void setPage(int page) { this.page = page; } - public int getSize() { return size; } - public void setSize(int size) { this.size = size; } - public long getTotal() { return total; } - public void setTotal(long total) { this.total = total; } - public List getRecords() { return records; } - public void setRecords(List records) { this.records = records; } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/common/core/domain/R.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/common/core/domain/R.java deleted file mode 100644 index d14a933a6..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/common/core/domain/R.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.openhis.common.core.domain; - -import java.util.HashMap; - -public class R extends HashMap { - private static final long serialVersionUID = 1L; - - public R() {} - - public static R success() { - R r = new R<>(); - r.put("code", 200); - r.put("msg", "success"); - return r; - } - - public static R error(String msg) { - R r = new R<>(); - r.put("code", 500); - r.put("msg", msg); - return r; - } - - public static R error(int code, String msg) { - R r = new R<>(); - r.put("code", code); - r.put("msg", msg); - return r; - } - - public static R ok(T data) { - R r = new R<>(); - r.put("code", 200); - r.put("msg", "success"); - r.put("data", data); - return r; - } - - public R put(String key, Object value) { - super.put(key, value); - return this; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/common/utils/DateUtils.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/common/utils/DateUtils.java deleted file mode 100644 index bc8333ed1..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/common/utils/DateUtils.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.common.utils; -public class DateUtils {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/domain/dto/DispensingDetailQueryDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/domain/dto/DispensingDetailQueryDTO.java deleted file mode 100644 index 47534f4c2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/domain/dto/DispensingDetailQueryDTO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.domain.dto; -public class DispensingDetailQueryDTO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/domain/entity/DispensingRecord.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/domain/entity/DispensingRecord.java deleted file mode 100644 index a0cc40056..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/domain/entity/DispensingRecord.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.domain.entity; -public class DispensingRecord {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/mapper/DispensingMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/mapper/DispensingMapper.java deleted file mode 100644 index 1d30a545e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/mapper/DispensingMapper.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.mapper; -public interface DispensingMapper {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/quartz/task/ExampleTask.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/quartz/task/ExampleTask.java index f024e07f6..a425cfb13 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/quartz/task/ExampleTask.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/quartz/task/ExampleTask.java @@ -1,19 +1,33 @@ package com.openhis.quartz.task; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.core.common.core.domain.R; +import com.core.common.utils.DateUtils; +import com.openhis.web.basedatamanage.appservice.IOrganizationAppService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +/** + * 定时任务例子 + * + * @author system + */ +@Slf4j @Component("exampleTask") public class ExampleTask { - private static final Logger log = LoggerFactory.getLogger(ExampleTask.class); + @Autowired + private IOrganizationAppService organizationAppService; - public void execute() { - log.info("ExampleTask executed at {}", new java.util.Date()); - } + /** + * 定时获取机构信息 + */ + public void getOrgInfo() { + log.info("定时获取机构信息START,时间:{}", DateUtils.getDate()); - public void run() { - execute(); + // 处理部分 + R r = organizationAppService.getOrgInfo(1907249098877554689L); + + log.info("定时获取机构信息END,机构信息:{},时间:{}", r.getData(), DateUtils.getDate()); } } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/service/DispensingService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/service/DispensingService.java deleted file mode 100644 index e766f2450..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/service/DispensingService.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.service; -public interface DispensingService {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/service/SysDictDataService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/service/SysDictDataService.java deleted file mode 100644 index ba77f7dc6..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/service/SysDictDataService.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.service; -public interface SysDictDataService {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/service/impl/DispensingServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/service/impl/DispensingServiceImpl.java deleted file mode 100644 index ae555c222..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/service/impl/DispensingServiceImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.service.impl; - -import com.openhis.domain.dto.DispensingDetailQueryDTO; -import com.openhis.domain.entity.DispensingRecord; -import com.openhis.mapper.DispensingMapper; -import com.openhis.service.DispensingService; -import com.openhis.service.SysDictDataService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -public class DispensingServiceImpl implements DispensingService { - - @Autowired - private DispensingMapper dispensingMapper; - - @Autowired - private SysDictDataService sysDictDataService; - - private static final String DICT_TYPE_NURSE_SUBMIT_MODE = "ward_nurse_submit_mode"; - private static final String MODE_REQUIRED_APPLY = "1"; // 需申请模式 - - @Override - public List queryDispensingDetails(DispensingDetailQueryDTO queryDTO) { - // 获取病区护士执行提交药品模式配置 - String submitMode = sysDictDataService.getDictValueByType(DICT_TYPE_NURSE_SUBMIT_MODE); - - // 修复 Bug #503:若为需申请模式,强制要求汇总申请状态为已申请(1) - // 确保明细单与汇总单的触发时机严格一致,避免业务脱节 - if (MODE_REQUIRED_APPLY.equals(submitMode)) { - queryDTO.setSummaryApplyStatus(1); - } - - return dispensingMapper.selectDispensingDetails(queryDTO); - } - - // 其他原有方法保持不变... -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/dto/AppointmentParam.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/dto/AppointmentParam.java deleted file mode 100644 index d49beedde..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/dto/AppointmentParam.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.appointment.dto; -public class AppointmentParam {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/entity/Appointment.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/entity/Appointment.java deleted file mode 100644 index 425829662..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/entity/Appointment.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.appointment.entity; -public class Appointment {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/AppointmentMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/AppointmentMapper.java deleted file mode 100644 index ed98ce69b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/AppointmentMapper.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.appointment.mapper; -public interface AppointmentMapper {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/OrderMainMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/OrderMainMapper.java deleted file mode 100644 index a8906b281..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/OrderMainMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.openhis.web.appointment.mapper; - -import org.apache.ibatis.annotations.*; -import java.math.BigDecimal; -import java.time.LocalDateTime; - -/** - * 订单主表数据库操作 Mapper - */ -@Mapper -public interface OrderMainMapper { - - @Insert("INSERT INTO order_main (appointment_id, amount, status, pay_status, create_time) " + - "VALUES (#{appointmentId}, #{amount}, 1, 1, #{createTime})") - @Options(useGeneratedKeys = true, keyProperty = "id") - Long insertOrder(@Param("appointmentId") Long appointmentId, - @Param("amount") BigDecimal amount, - @Param("createTime") LocalDateTime createTime); - - /** - * Bug #506 Fix: 更新订单状态为已取消且已退费 - * status=0, pay_status=3, cancel_time=当前时间, cancel_reason='诊前退号' - */ - @Update("UPDATE order_main SET status = 0, pay_status = 3, cancel_time = NOW(), cancel_reason = '诊前退号', update_time = NOW() WHERE id = #{orderId}") - int updateOrderForCancellation(@Param("orderId") Long orderId); - - /** - * 根据订单ID查询关联的排班ID,用于回滚号源池 - */ - @Select("SELECT schedule_id FROM order_main WHERE id = #{orderId}") - Long getScheduleIdByOrderId(@Param("orderId") Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/RefundLogMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/RefundLogMapper.java deleted file mode 100644 index 436279eef..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/RefundLogMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.openhis.web.appointment.mapper; - -import org.apache.ibatis.annotations.Insert; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -/** - * 退费日志数据库操作 Mapper - */ -@Mapper -public interface RefundLogMapper { - - /** - * Bug #506 Fix: 插入退费日志,严格关联 order_main.id - * 确保后台业务数据可追溯 - */ - @Insert("INSERT INTO refund_log (order_id, refund_amount, refund_time, create_time) " + - "VALUES (#{orderId}, #{refundAmount}, NOW(), NOW())") - int insertRefundLog(@Param("orderId") Long orderId, @Param("refundAmount") java.math.BigDecimal refundAmount); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/SchedulePoolMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/SchedulePoolMapper.java deleted file mode 100644 index 4249594be..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/SchedulePoolMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.openhis.web.appointment.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Update; - -/** - * 号源池数据库操作 Mapper - */ -@Mapper -public interface SchedulePoolMapper { - - /** - * 预约时累加已预约数 - */ - @Update("UPDATE adm_schedule_pool SET booked_num = booked_num + 1, version = version + 1, update_time = NOW() WHERE id = #{scheduleId}") - int incrementBookedNum(@Param("scheduleId") Long scheduleId); - - /** - * Bug #506 Fix: 退号时扣减已预约数并累加版本号 - * 严格遵循 PRD:booked_num - 1,version + 1 - * - * @param scheduleId 排班池主键ID - * @return 受影响的行数 - */ - @Update("UPDATE adm_schedule_pool SET booked_num = booked_num - 1, version = version + 1, update_time = NOW() WHERE id = #{scheduleId}") - int decrementBookedNumAndIncrementVersion(@Param("scheduleId") Long scheduleId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/ScheduleSlotMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/ScheduleSlotMapper.java deleted file mode 100644 index 99490d63a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/mapper/ScheduleSlotMapper.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.openhis.web.appointment.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Update; - -/** - * 号源时段数据库操作 Mapper - */ -@Mapper -public interface ScheduleSlotMapper { - - /** - * 将号源时段状态更新为“已取号”(status = 3) - * - * @param slotId 号源时段主键ID - * @return 受影响的行数 - */ - @Update("UPDATE adm_schedule_slot SET status = 3, update_time = NOW() WHERE id = #{slotId}") - int updateStatusToTaken(@Param("slotId") Long slotId); - - /** - * Bug #506 Fix: 退号时回滚号源时段状态 - * 将 status 重置为 0 (待约),并清空 order_id 关联,释放号源供再次预约 - * - * @param orderId 关联的订单ID - * @return 受影响的行数 - */ - @Update("UPDATE adm_schedule_slot SET status = 0, order_id = NULL, update_time = NOW() WHERE order_id = #{orderId}") - int rollbackSlotStatus(@Param("orderId") Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/service/AppointmentService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/service/AppointmentService.java deleted file mode 100644 index 7a9c0578a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/service/AppointmentService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.appointment.service; - -public interface AppointmentService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/service/AppointmentServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/service/AppointmentServiceImpl.java deleted file mode 100644 index a90f521d3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointment/service/AppointmentServiceImpl.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.openhis.web.appointment.service; - -import com.openhis.web.appointment.entity.Appointment; -import com.openhis.web.appointment.mapper.AppointmentMapper; -import com.openhis.web.appointment.mapper.ScheduleSlotMapper; -import com.openhis.web.appointment.mapper.OrderMainMapper; -import com.openhis.web.appointment.mapper.SchedulePoolMapper; -import com.openhis.web.appointment.mapper.RefundLogMapper; -import com.openhis.web.appointment.dto.AppointmentParam; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.time.LocalDateTime; - -/** - * 门诊预约挂号服务实现 - */ -@Service -public class AppointmentServiceImpl implements AppointmentService { - - private final AppointmentMapper appointmentMapper; - private final ScheduleSlotMapper scheduleSlotMapper; - private final OrderMainMapper orderMainMapper; - private final SchedulePoolMapper schedulePoolMapper; - private final RefundLogMapper refundLogMapper; - - public AppointmentServiceImpl(AppointmentMapper appointmentMapper, - ScheduleSlotMapper scheduleSlotMapper, - OrderMainMapper orderMainMapper, - SchedulePoolMapper schedulePoolMapper, - RefundLogMapper refundLogMapper) { - this.appointmentMapper = appointmentMapper; - this.scheduleSlotMapper = scheduleSlotMapper; - this.orderMainMapper = orderMainMapper; - this.schedulePoolMapper = schedulePoolMapper; - this.refundLogMapper = refundLogMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public boolean createAppointment(AppointmentParam param) { - Appointment appointment = new Appointment(); - appointment.setPatientId(param.getPatientId()); - appointment.setScheduleId(param.getScheduleId()); - appointment.setDoctorId(param.getDoctorId()); - appointment.setDeptId(param.getDeptId()); - appointment.setVisitDate(param.getVisitDate()); - appointment.setCreateTime(LocalDateTime.now()); - - // 1. 保存预约记录 - appointmentMapper.insert(appointment); - - // 2. 累加号源池已预约数(已实现的原子操作) - schedulePoolMapper.incrementBookedNum(param.getScheduleId()); - - // 3. 创建订单并完成支付(简化示例,实际业务已在后续代码中实现) - Long orderId = orderMainMapper.insertOrder(appointment.getId(), - param.getAmount(), LocalDateTime.now()); - return orderId != null; - } - - /** - * Bug #574 Fix: 预约签到缴费成功后,更新号源时段状态为“已取号”(status=3) - * 修复原流程中遗漏调用 scheduleSlotMapper.updateStatusToTaken 导致状态滞留为 1 的问题 - * - * @param orderId 订单ID - * @param slotId 号源时段ID - * @return 是否更新成功 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public boolean checkInAndPay(Long orderId, Long slotId) { - if (orderId == null || slotId == null) { - throw new IllegalArgumentException("订单ID或号源时段ID不能为空"); - } - - // 核心修复:显式调用 Mapper 将 adm_schedule_slot.status 更新为 3(已取号/签到) - int rows = scheduleSlotMapper.updateStatusToTaken(slotId); - if (rows <= 0) { - throw new RuntimeException("更新号源时段状态失败,未找到对应记录或状态已变更"); - } - - // 此处可补充订单状态流转逻辑(如 orderMainMapper.updateOrderStatus(orderId, 2)) - return true; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java index 6b5626889..f9f0b95ee 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java @@ -1,27 +1,152 @@ package com.openhis.web.doctorstation.appservice; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.core.common.core.domain.R; +import com.openhis.web.doctorstation.dto.AdviceBaseDto; import com.openhis.web.doctorstation.dto.AdviceSaveParam; +import com.openhis.web.doctorstation.dto.OrderBindInfoDto; +import com.openhis.web.doctorstation.dto.SurgeryItemDto; +import com.openhis.web.doctorstation.dto.UpdateGroupIdParam; + +import java.util.List; /** - * 医生站-医嘱/处方 AppService 接口 + * 医生站-医嘱/处方 应用Service */ public interface IDoctorStationAdviceAppService { /** - * 保存医嘱/检验申请 + * 查询医嘱信息 + * + * @param adviceBaseDto 查询条件 + * @param searchKey 模糊查询关键字 + * @param locationId 药房id + * @param adviceDefinitionIdParamList 医嘱定义id参数集合 + * @param organizationId 患者挂号对应的科室id + * @param pageNo 当前页 + * @param pageSize 每页多少条 + * @param pricingFlag 划价标记 + * @param adviceTypes 医嘱类型参数集合 + * @param orderPricing 医嘱定价来源 | 定时任务调用时传参 + * @return 医嘱信息 */ - R saveAdvice(AdviceSaveParam param); + IPage getAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId, + List adviceDefinitionIdParamList, Long organizationId, Integer pageNo, Integer pageSize, + Integer pricingFlag, List adviceTypes, String orderPricing, String categoryCode); /** - * 撤回已签发的医嘱(包括“停嘱”操作) - * @param adviceId 医嘱ID - * @return 操作结果 + * 查询医嘱绑定信息 + * + * @param typeCode 1:用法绑东西 2:诊疗绑东西 + * @param itemNo 用法的code 或者 诊疗定义id + * @return 医嘱绑定信息 */ - R withdrawAdvice(Long adviceId); + List getOrderBindInfo(String typeCode, String itemNo); /** - * 取消停嘱(恢复已停止的长期医嘱) + * 门诊保存医嘱 + * + * @param adviceSaveParam 医嘱表单信息 + * @param adviceOpType 医嘱操作类型 + * @return 结果 */ - R cancelStopAdvice(Long adviceId); + R saveAdvice(AdviceSaveParam adviceSaveParam, String adviceOpType); + + /** + * 查询医嘱请求数据 + * + * @param encounterId 就诊id + * @return 医嘱请求数据 + */ + R getRequestBaseInfo(Long encounterId); + + /** + * 查询医嘱请求数据(支持按生成来源和来源单据号过滤) + * + * @param encounterId 就诊id + * @param generateSourceEnum 生成来源(可选,如手术计费=6) + * @param sourceBillNo 来源业务单据号(可选) + * @return 医嘱请求数据 + */ + R getRequestBaseInfo(Long encounterId, Integer generateSourceEnum, String sourceBillNo); + + /** + * 门诊签退医嘱 + * + * @param requestIdList 请求id列表 + * @return 结果 + */ + R signOffAdvice(List requestIdList); + + /** + * 查询历史医嘱请求数据 + * + * @param patientId 病人id + * @param encounterId 就诊id + * @return 历史医嘱请求数据 + */ + R getRequestHistoryInfo(Long patientId, Long encounterId); + + /** + * 更新组号 + * + * @param updateGroupIdParam 更新组号参数 + * @return 结果 + */ + void updateGroupId(UpdateGroupIdParam updateGroupIdParam); + + /** + * 查询就诊费用性质 + * + * @param encounterId 就诊id + * @return 就诊费用性质 + */ + R getEncounterContract(Long encounterId); + + /** + * 查询检验检查开立历史(近30天) + * + * @param patientId 患者id + * @param adviceDefinitionId 医嘱定义id + * @return 检验检查开立历史 + */ + R getProofAndTestHistory(Long patientId, Long adviceDefinitionId); + + /** + * 查询检验url相关参数 + * + * @param encounterId 就诊id + * @return 检验url相关参数 + */ + R getProofResult(Long encounterId); + + /** + * 查询检查url相关参数 + * + * @param encounterId 就诊id + * @return 检查url相关参数 + */ + R getTestResult(Long encounterId); + + /** + * 获取当前科室已配置的药品类别列表 + * + * @param organizationId 科室id + * @return 已配置的药品类别编码列表 + */ + R getConfiguredCategories(Long organizationId); + + /** + * 手术项目专用分页查询(仅手术 + 定价,无库存/草稿库存/取药科室等无关逻辑) + * + * @param organizationId 科室ID(可选) + * @param pageNo 当前页 + * @param pageSize 每页条数 + * @param searchKey 模糊查询关键字(可选) + * @return 手术项目分页数据(含价格信息) + */ + IPage getSurgeryPage(Long organizationId, Integer pageNo, Integer pageSize, String searchKey); + + IPage getExaminationPage(Long organizationId, Integer pageNo, Integer pageSize, String searchKey, String categoryCode); + } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java index 3be6af983..ca722b74c 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java @@ -1,104 +1,2583 @@ package com.openhis.web.doctorstation.appservice.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.core.common.core.domain.R; +import com.core.common.core.redis.RedisCache; +import com.core.common.enums.DelFlag; +import com.core.common.enums.TenantOptionDict; import com.core.common.exception.ServiceException; +import com.core.common.utils.AssignSeqUtil; +import com.core.common.utils.MessageUtils; +import com.core.common.utils.SecurityUtils; +import com.core.common.utils.StringUtils; +import com.core.web.util.TenantOptionUtil; +import com.openhis.administration.domain.Account; +import com.openhis.administration.domain.ChargeItem; +import com.openhis.administration.domain.Encounter; +import com.openhis.administration.service.IAccountService; +import com.openhis.administration.service.IChargeItemService; +import com.openhis.administration.service.IEncounterService; +import com.openhis.administration.service.IEncounterDiagnosisService; +import com.openhis.administration.domain.EncounterDiagnosis; +import com.openhis.common.constant.CommonConstants; +import com.openhis.common.constant.PromptMsgConstant; +import com.openhis.common.enums.*; +import com.openhis.common.utils.EnumUtils; +import com.openhis.common.utils.HisQueryUtils; +import com.openhis.medication.domain.MedicationDispense; +import com.openhis.medication.domain.MedicationRequest; +import com.openhis.medication.service.IMedicationDispenseService; +import com.openhis.medication.service.IMedicationRequestService; +import com.openhis.web.chargemanage.mapper.OutpatientRegistrationAppMapper; import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService; -import com.openhis.web.doctorstation.dto.AdviceSaveParam; -import com.openhis.web.regdoctorstation.mapper.RequestFormManageAppMapper; -import lombok.RequiredArgsConstructor; +import com.openhis.document.service.IRequestFormService; +import com.openhis.clinical.service.ISurgeryService; +import com.openhis.clinical.domain.Surgery; +import com.openhis.web.doctorstation.appservice.IDoctorStationInspectionLabApplyService; +import com.openhis.web.doctorstation.dto.*; +import com.openhis.web.doctorstation.mapper.DoctorStationAdviceAppMapper; +import com.openhis.web.doctorstation.utils.AdviceUtils; +import com.openhis.web.doctorstation.utils.DoctorStationSendApplyUtil; +import com.openhis.web.doctorstation.utils.PrescriptionUtils; +import com.openhis.web.personalization.dto.ActivityDeviceDto; +import com.openhis.workflow.domain.ActivityDefinition; +import com.openhis.workflow.domain.DeviceRequest; +import com.openhis.workflow.domain.InventoryItem; +import com.openhis.workflow.domain.ServiceRequest; +import com.openhis.workflow.service.*; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; +import com.openhis.document.domain.RequestForm; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; /** - * 医生站-医嘱/处方 AppService 实现 + * 医生站-医嘱/处方 应用实现类 */ -@Service @Slf4j -@RequiredArgsConstructor +@Service public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAppService { - private final RequestFormManageAppMapper requestFormManageAppMapper; + private static final Pattern INSPECTION_APPLY_NO_JSON = + Pattern.compile("\"applyNo\"\\s*:\\s*\"([^\"]+)\""); + + @Resource + AssignSeqUtil assignSeqUtil; + + @Resource + DoctorStationAdviceAppMapper doctorStationAdviceAppMapper; + + @Resource + IMedicationRequestService iMedicationRequestService; + + @Resource + IDeviceRequestService iDeviceRequestService; + + @Resource + IServiceRequestService iServiceRequestService; + + @Resource + IChargeItemService iChargeItemService; + + @Resource + IAccountService iAccountService; + + // @Resource + // IOrganizationLocationService iOrganizationLocationService; + @Resource + IMedicationDispenseService iMedicationDispenseService; + + @Resource + IDeviceDispenseService iDeviceDispenseService; + + @Resource + PrescriptionUtils prescriptionUtils; + + @Resource + AdviceUtils adviceUtils; + + @Resource + IActivityDefinitionService iActivityDefinitionService; + + @Resource + OutpatientRegistrationAppMapper outpatientRegistrationAppMapper; + + @Resource + DoctorStationSendApplyUtil doctorStationSendApplyUtil; + + @Resource + RedisCache redisCache; + + @Resource + IEncounterService iEncounterService; + + @Resource + IEncounterDiagnosisService iEncounterDiagnosisService; + + @Resource + IInventoryItemService inventoryItemService; + + /** + * 与检验申请实现存在循环依赖,需延迟注入;删除诊疗医嘱时按 contentJson 级联作废检验申请单。 + */ + @Resource + @Lazy + private IDoctorStationInspectionLabApplyService iDoctorStationInspectionLabApplyService; + + /** + * 与RequestFormManageAppServiceImpl存在循环依赖,需延迟注入;删除手术医嘱时级联作废手术申请单。 + */ + @Resource + @Lazy + private IRequestFormService iRequestFormService; + + /** + * 删除手术医嘱时级联删除 cli_surgery 手术记录。 + */ + @Resource + @Lazy + private ISurgeryService iSurgeryService; + + // 缓存 key 前缀 + private static final String ADVICE_BASE_INFO_CACHE_PREFIX = "advice:base:info:"; + // 缓存过期时间(小时) + private static final long CACHE_EXPIRE_HOURS = 24; + + + /** + * 查询医嘱信息 + * + * @param adviceBaseDto 查询条件 + * @param searchKey 模糊查询关键字 + * @param locationId 药房id + * @param adviceDefinitionIdParamList 医嘱定义id参数集合 + * @param organizationId 患者挂号对应的科室id + * @param pageNo 当前页 + * @param pageSize 每页多少条 + * @param pricingFlag 划价标记 + * @param adviceTypes 医嘱类型参数集合 + * @param orderPricing 医嘱定价来源 | 定时任务调用时传参 + * @return 医嘱信息 + */ + @Override + public IPage getAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId, + List adviceDefinitionIdParamList, Long organizationId, Integer pageNo, Integer pageSize, + Integer pricingFlag, List adviceTypes, String orderPricing, String categoryCode) { + + // 生成缓存键,处理可能的null值 + String safeSearchKey = searchKey != null ? searchKey : ""; + String safeAdviceTypesStr = ""; + if (adviceTypes != null && !adviceTypes.isEmpty()) { + safeAdviceTypesStr = String.join(",", + adviceTypes.stream().map(String::valueOf).collect(Collectors.toList())); + } + String safeOrganizationId = organizationId != null ? organizationId.toString() : ""; + String safePricingFlag = pricingFlag != null ? pricingFlag.toString() : ""; + String safePageNo = pageNo != null ? pageNo.toString() : ""; + String safePageSize = pageSize != null ? pageSize.toString() : ""; + String safeCategoryCode = categoryCode != null ? categoryCode : ""; + + // 设置默认科室:仅当前端/调用方未传 organizationId 时才回退到登录人科室 + // 否则会导致门诊划价等场景(按患者挂号科室查询)返回空 + if (organizationId == null) { + organizationId = SecurityUtils.getLoginUser().getOrgId(); + } + + // 只有在没有搜索关键字时才尝试使用缓存 + boolean useCache = (searchKey == null || searchKey.trim().isEmpty()) + && (adviceDefinitionIdParamList == null || adviceDefinitionIdParamList.isEmpty()); + + String cacheKey = null; + if (useCache) { + // 生成缓存 key:无搜索关键字时按科室缓存 + cacheKey = ADVICE_BASE_INFO_CACHE_PREFIX + organizationId + ":" + safeAdviceTypesStr + ":" + safeCategoryCode + ":" + safePageNo + ":" + safePageSize; + + // 先清除可能存在的无效缓存(JSONObject类型) + if (redisCache.hasKey(cacheKey)) { + Object cachedObj = redisCache.getCacheObject(cacheKey); + if (cachedObj instanceof com.alibaba.fastjson2.JSONObject) { + redisCache.deleteObject(cacheKey); + log.info("清除无效缓存, key: {}", cacheKey); + } else if (cachedObj instanceof com.baomidou.mybatisplus.extension.plugins.pagination.Page) { + log.info("从缓存获取医嘱基础信息, key: {}, records: {}", cacheKey, ((IPage)cachedObj).getRecords().size()); + return (IPage) cachedObj; + } + } + + log.info("缓存未命中,准备查询数据库, key: {}", cacheKey); + } else { + log.info("不使用缓存条件: searchKey={}, adviceDefinitionIdParamList={}", searchKey, adviceDefinitionIdParamList); + } + + log.info("从数据库查询医嘱基础信息"); + + // 医嘱定价来源 + String orderPricingSource = TenantOptionUtil.getOptionContent(TenantOptionDict.ORDER_PRICING_SOURCE); + if (StringUtils.isEmpty(orderPricingSource) && StringUtils.isEmpty(orderPricing)) { + throw new ServiceException("租户配置项【医嘱定价来源】未配置"); + } else if (StringUtils.isNotEmpty(orderPricing)) { + orderPricingSource = orderPricing; + } + // 开药时药房允许多选开关 + String pharmacyMultipleChoiceSwitch = TenantOptionUtil + .getOptionContent(TenantOptionDict.PHARMACY_MULTIPLE_CHOICE_SWITCH); + // 药房允许多选 + boolean pharmacyMultipleChoice = Whether.YES.getCode().equals(pharmacyMultipleChoiceSwitch); + + // 构建查询条件 + QueryWrapper queryWrapper = HisQueryUtils.buildQueryWrapper(adviceBaseDto, searchKey, + new HashSet<>(Arrays.asList("advice_name", "py_str", "wb_str")), null); + // 🔧 BugFix#339: 药房筛选条件失效 - 添加 locationId 过滤条件 + if (locationId != null) { + queryWrapper.eq("location_id", locationId); + log.info("BugFix#339: 添加药房筛选条件 locationId={}", locationId); + } + IPage adviceBaseInfo = doctorStationAdviceAppMapper.getAdviceBaseInfo( + new Page<>(pageNo, pageSize), PublicationStatus.ACTIVE.getValue(), organizationId, + CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION, + CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, pricingFlag, adviceDefinitionIdParamList, + adviceTypes, searchKey, categoryCode, + queryWrapper); + List adviceBaseDtoList = adviceBaseInfo.getRecords(); + + // 如果searchKey不为null,对查询结果进行排序:adviceName以searchKey开头的排在前面 + if (searchKey != null && !searchKey.trim().isEmpty()) { + sortAdviceListBySearchKey(adviceBaseDtoList, searchKey.trim()); + } + + // 医嘱定义ID集合 + List adviceDefinitionIdList = adviceBaseDtoList.stream().map(AdviceBaseDto::getAdviceDefinitionId) + .collect(Collectors.toList()); + // 费用定价主表ID集合(过滤null值,手术项目无定价定义) + List chargeItemDefinitionIdList = adviceBaseDtoList.stream() + .map(AdviceBaseDto::getChargeItemDefinitionId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + // 判断是否包含药品或耗材类型(只有这些类型才需要库存相关查询) + boolean hasMedOrDevice = adviceTypes != null + && (adviceTypes.contains(1) || adviceTypes.contains(2)); + + // 医嘱库存集合 — 仅药品/耗材需要库存查询,手术/诊疗(3,6)无库存概念,跳过以减少数据库开销 + List adviceInventoryList; + List adviceDraftInventoryList; + List adviceInventory; + if (hasMedOrDevice) { + adviceInventoryList = doctorStationAdviceAppMapper.getAdviceInventory(locationId, + adviceDefinitionIdList, + CommonConstants.SqlCondition.ABOUT_INVENTORY_TABLE_STR, PublicationStatus.ACTIVE.getValue()); + // 待发放个数信息 + adviceDraftInventoryList = doctorStationAdviceAppMapper.getAdviceDraftInventory( + CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION, + DispenseStatus.DRAFT.getValue(), DispenseStatus.PREPARATION.getValue()); + // 预减库存 + adviceInventory = adviceUtils.subtractInventory(adviceInventoryList, adviceDraftInventoryList); + } else { + adviceInventoryList = Collections.emptyList(); + adviceDraftInventoryList = Collections.emptyList(); + adviceInventory = Collections.emptyList(); + } + // 查询取药科室配置 — 仅药品开单场景需要 + List medLocationConfig; + Map> allowedLocByCategory; + if (hasMedOrDevice) { + medLocationConfig = doctorStationAdviceAppMapper.getMedLocationConfig(organizationId); + // 将配置转为 {categoryCode -> 允许的locationId集合} + allowedLocByCategory = new HashMap<>(); + if (medLocationConfig != null && !medLocationConfig.isEmpty()) { + for (AdviceInventoryDto cfg : medLocationConfig) { + if (cfg.getCategoryCode() == null || cfg.getLocationId() == null) { + continue; + } + allowedLocByCategory.computeIfAbsent(String.valueOf(cfg.getCategoryCode()), k -> new HashSet<>()) + .add(cfg.getLocationId()); + } + } + } else { + medLocationConfig = Collections.emptyList(); + allowedLocByCategory = Collections.emptyMap(); + } + // 费用定价子表信息 - 仅药品/耗材需要批次定价查询,手术/诊疗无库存概念不需要 + List childCharge = new ArrayList<>(); + if (hasMedOrDevice && chargeItemDefinitionIdList != null && !chargeItemDefinitionIdList.isEmpty()) { + // 分批处理,每批最多1000个ID,增加批次大小以减少查询次数 + int batchSize = 1000; + for (int i = 0; i < chargeItemDefinitionIdList.size(); i += batchSize) { + int endIndex = Math.min(i + batchSize, chargeItemDefinitionIdList.size()); + List batch = chargeItemDefinitionIdList.subList(i, endIndex); + childCharge.addAll(doctorStationAdviceAppMapper + .getChildCharge(ConditionCode.LOT_NUMBER_PRICE.getCode(), batch)); + } + } + + // 费用定价主表信息 - 使用分批处理避免大量参数问题 + List mainCharge = new ArrayList<>(); + if (chargeItemDefinitionIdList != null && !chargeItemDefinitionIdList.isEmpty()) { + // 分批处理,每批最多500个ID + int batchSize = 500; + for (int i = 0; i < chargeItemDefinitionIdList.size(); i += batchSize) { + int endIndex = Math.min(i + batchSize, chargeItemDefinitionIdList.size()); + List batch = chargeItemDefinitionIdList.subList(i, endIndex); + mainCharge + .addAll(doctorStationAdviceAppMapper.getMainCharge(batch, PublicationStatus.ACTIVE.getValue())); + } + } + String unitCode = ""; // 包装单位 + Long chargeItemDefinitionId; // 费用定价主表ID + // 检查是否有取药科室配置(用于药品类型) + boolean hasPharmacyConfig = medLocationConfig != null && !medLocationConfig.isEmpty(); + for (AdviceBaseDto baseDto : adviceBaseDtoList) { + String tableName = baseDto.getAdviceTableName(); + if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(tableName)) { // 药品 + // 是否皮试 + baseDto + .setSkinTestFlag_enumText(EnumUtils.getInfoByValue(Whether.class, baseDto.getSkinTestFlag())); + // 是否为注射药物 + baseDto.setInjectFlag_enumText(EnumUtils.getInfoByValue(Whether.class, baseDto.getInjectFlag())); + + // 设置是否缺少取药科室配置标志 + baseDto.setPharmacyConfigMissing(!hasPharmacyConfig); + + // fallthrough to 耗材处理逻辑(保持原有逻辑) + // 每一条医嘱的库存集合信息 , 包装单位库存前端计算 + List inventoryList = adviceInventory + .stream().filter(e -> baseDto.getAdviceDefinitionId() != null && e.getItemId() != null + && baseDto.getAdviceDefinitionId().equals(e.getItemId()) + && baseDto.getAdviceTableName() != null && e.getItemTable() != null + && baseDto.getAdviceTableName().equals(e.getItemTable()) + && (pharmacyMultipleChoice + || (baseDto.getPositionId() == null || (e.getLocationId() != null + && baseDto.getPositionId().equals(e.getLocationId()))))) + .collect(Collectors.toList()); + // 库存信息 + baseDto.setInventoryList(inventoryList); + // 设置默认产品批号 + if (!inventoryList.isEmpty()) { + // 库存大于0 + List hasInventoryList = inventoryList.stream() + .filter(e -> e.getQuantity().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList()); + if (!hasInventoryList.isEmpty()) { + baseDto.setDefaultLotNumber(hasInventoryList.get(0).getLotNumber()); + } + } + if (!inventoryList.isEmpty() && !medLocationConfig.isEmpty()) { + // 第一步:在medLocationConfig中匹配categoryCode + AdviceInventoryDto result1 = medLocationConfig.stream() + .filter(dto -> baseDto.getCategoryCode() != null && dto.getCategoryCode() != null + && baseDto.getCategoryCode().equals(dto.getCategoryCode())) + .findFirst() + .orElse(null); + if (result1 != null) { + // 第二步:在inventoryList中匹配locationId + AdviceInventoryDto result2 = inventoryList.stream() + .filter(dto -> result1.getLocationId() != null && dto.getLocationId() != null + && result1.getLocationId().equals(dto.getLocationId())) + .findFirst() + .orElse(null); + if (result2 != null && result2.getLotNumber() != null) { + baseDto.setDefaultLotNumber(result2.getLotNumber()); + } + } + } + + unitCode = baseDto.getUnitCode(); + chargeItemDefinitionId = baseDto.getChargeItemDefinitionId(); + List priceDtoList = new ArrayList<>(); + // 库存信息里取 命中条件 去匹配价格 + for (AdviceInventoryDto adviceInventoryDto : inventoryList) { + Long finalChargeItemDefinitionId = chargeItemDefinitionId; + String finalUnitCode = unitCode; + // 从定价子表取价格(适用于批次售卖场景) + List childPrice = childCharge.stream() + .filter(e -> e.getDefinitionId() != null && finalChargeItemDefinitionId != null + && e.getDefinitionId().equals(finalChargeItemDefinitionId) + && e.getConditionValue() != null && adviceInventoryDto.getLotNumber() != null + && e.getConditionValue().equals(adviceInventoryDto.getLotNumber())) + .peek(e -> e.setUnitCode(finalUnitCode)) // 设置 unitCode + .collect(Collectors.toList()); + // 从定价主表取价格(适用于统一零售价场景) + List mainPrice = mainCharge.stream() + .filter(e -> baseDto.getChargeItemDefinitionId() != null && e.getDefinitionId() != null + && baseDto.getChargeItemDefinitionId().equals(e.getDefinitionId())) + .collect(Collectors.toList()); + // 按批次售价 + if (OrderPricingSource.BATCH_SELLING_PRICE.getCode().equals(orderPricingSource)) { + priceDtoList.addAll(childPrice); + } else { + priceDtoList.addAll(mainPrice); + } + } + // 价格信息 + baseDto.setPriceList(priceDtoList); + } else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(tableName)) { // 耗材 + // 每一条医嘱的库存集合信息 , 包装单位库存前端计算 + List inventoryList = adviceInventory + .stream().filter(e -> baseDto.getAdviceDefinitionId() != null && e.getItemId() != null + && baseDto.getAdviceDefinitionId().equals(e.getItemId()) + && baseDto.getAdviceTableName() != null && e.getItemTable() != null + && baseDto.getAdviceTableName().equals(e.getItemTable()) + && (pharmacyMultipleChoice + || (baseDto.getPositionId() == null || (e.getLocationId() != null + && baseDto.getPositionId().equals(e.getLocationId()))))) + .collect(Collectors.toList()); + // 库存信息 + baseDto.setInventoryList(inventoryList); + // 设置默认产品批号 + if (!inventoryList.isEmpty()) { + // 库存大于0 + List hasInventoryList = inventoryList.stream() + .filter(e -> e.getQuantity().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList()); + if (!hasInventoryList.isEmpty()) { + baseDto.setDefaultLotNumber(hasInventoryList.get(0).getLotNumber()); + } + } + if (!inventoryList.isEmpty() && !medLocationConfig.isEmpty()) { + // 第一步:在medLocationConfig中匹配categoryCode + AdviceInventoryDto result1 = medLocationConfig.stream() + .filter(dto -> baseDto.getCategoryCode() != null && dto.getCategoryCode() != null + && baseDto.getCategoryCode().equals(dto.getCategoryCode())) + .findFirst() + .orElse(null); + if (result1 != null) { + // 第二步:在inventoryList中匹配locationId + AdviceInventoryDto result2 = inventoryList.stream() + .filter(dto -> result1.getLocationId() != null && dto.getLocationId() != null + && result1.getLocationId().equals(dto.getLocationId())) + .findFirst() + .orElse(null); + if (result2 != null && result2.getLotNumber() != null) { + baseDto.setDefaultLotNumber(result2.getLotNumber()); + } + } + } + + unitCode = baseDto.getUnitCode(); + chargeItemDefinitionId = baseDto.getChargeItemDefinitionId(); + List priceDtoList = new ArrayList<>(); + + // 🔧 Bug #220 修复:耗材无库存时也需要设置价格 + if (inventoryList.isEmpty()) { + // 库存为空时,直接从定价主表获取统一零售价 + String finalUnitCode = unitCode; // 创建final变量用于lambda + List mainPrice = mainCharge.stream() + .filter(e -> baseDto.getChargeItemDefinitionId() != null && e.getDefinitionId() != null + && baseDto.getChargeItemDefinitionId().equals(e.getDefinitionId())) + .peek(e -> e.setUnitCode(finalUnitCode)) // 设置 unitCode + .collect(Collectors.toList()); + priceDtoList.addAll(mainPrice); + } else { + // 库存信息里取 命中条件 去匹配价格 + for (AdviceInventoryDto adviceInventoryDto : inventoryList) { + Long finalChargeItemDefinitionId = chargeItemDefinitionId; + String finalUnitCode = unitCode; + // 从定价子表取价格(适用于批次售卖场景) + List childPrice = childCharge.stream() + .filter(e -> e.getDefinitionId() != null && finalChargeItemDefinitionId != null + && e.getDefinitionId().equals(finalChargeItemDefinitionId) + && e.getConditionValue() != null && adviceInventoryDto.getLotNumber() != null + && e.getConditionValue().equals(adviceInventoryDto.getLotNumber())) + .peek(e -> e.setUnitCode(finalUnitCode)) // 设置 unitCode + .collect(Collectors.toList()); + // 从定价主表取价格(适用于统一零售价场景) + List mainPrice = mainCharge.stream() + .filter(e -> baseDto.getChargeItemDefinitionId() != null && e.getDefinitionId() != null + && baseDto.getChargeItemDefinitionId().equals(e.getDefinitionId())) + .collect(Collectors.toList()); + // 按批次售价 + if (OrderPricingSource.BATCH_SELLING_PRICE.getCode().equals(orderPricingSource)) { + priceDtoList.addAll(childPrice); + } else { + priceDtoList.addAll(mainPrice); + } + } + } + // 价格信息 + baseDto.setPriceList(priceDtoList); + } else if (CommonConstants.TableName.WOR_ACTIVITY_DEFINITION.equals(tableName)) { // 诊疗 + List priceList = mainCharge.stream() + .filter(e -> baseDto.getChargeItemDefinitionId() != null && e.getDefinitionId() != null + && baseDto.getChargeItemDefinitionId().equals(e.getDefinitionId())) + .collect(Collectors.toList()); + // 价格信息 + baseDto.setPriceList(priceList); + // 活动类型 + baseDto.setActivityType_enumText( + EnumUtils.getInfoByValue(ActivityType.class, baseDto.getActivityType())); + } + } + + // 缓存结果(只有无搜索关键字时才缓存) + if (useCache && cacheKey != null && adviceBaseInfo != null) { + // 确保是 IPage 类型再缓存,避免缓存无效数据 + if (adviceBaseInfo instanceof com.baomidou.mybatisplus.extension.plugins.pagination.Page) { + redisCache.setCacheObject(cacheKey, adviceBaseInfo, (int) CACHE_EXPIRE_HOURS, java.util.concurrent.TimeUnit.HOURS); + log.info("缓存医嘱基础信息, key: {}, 过期时间: {} 小时", cacheKey, CACHE_EXPIRE_HOURS); + } + } + + return adviceBaseInfo; + } + + /** + * 查询医嘱绑定信息 + * + * @param typeCode 1:用法绑东西 2:诊疗绑东西 + * @param itemNo 用法的code 或者 诊疗定义id + * @return 医嘱绑定信息 + */ + @Override + public List getOrderBindInfo(String typeCode, String itemNo) { + return doctorStationAdviceAppMapper.getOrderBindInfo(typeCode, PublicationStatus.ACTIVE.getValue(), itemNo); + } + + /** + * 门诊保存/签发医嘱 + * + * @param adviceSaveParam 医嘱表单信息 + * @param adviceOpType 医嘱操作类型 + * @return 结果 + */ @Override @Transactional(rollbackFor = Exception.class) - public R saveAdvice(AdviceSaveParam param) { - // Bug #587 修复:校验开始时间不可早于患者入院时间 - if (param.getStartTime() != null && param.getEncounterId() != null) { - LocalDateTime admissionTime = requestFormManageAppMapper.selectAdmissionTimeByEncounterId(param.getEncounterId()); - if (admissionTime != null && param.getStartTime().isBefore(admissionTime)) { - String formattedAdmission = admissionTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); - throw new ServiceException("医嘱开始时间不能早于患者入院时间(" + formattedAdmission + ")!"); + public R saveAdvice(AdviceSaveParam adviceSaveParam, String adviceOpType) { + try { + // 🔧 BugFix#333/335/336: 参数非空校验 + if (adviceSaveParam == null) { + log.error("BugFix#333: adviceSaveParam 为 null"); + return R.fail(null, "请求参数为空,请刷新页面后重试"); } - } - // Bug #466 修复:校验执行时间不可早于当前系统时间 - if (param.getExecutionTime() != null) { - LocalDateTime now = LocalDateTime.now(); - if (param.getExecutionTime().isBefore(now)) { - throw new ServiceException("执行时间不可早于当前时间"); + // 患者挂号对应的科室id + Long organizationId = adviceSaveParam.getOrganizationId(); + // 医嘱分类信息 + List adviceSaveList = adviceSaveParam.getAdviceSaveList(); + + // 🔧 BugFix#333: 医嘱列表非空校验 + if (adviceSaveList == null || adviceSaveList.isEmpty()) { + log.error("BugFix#333: adviceSaveList 为 null 或空,adviceOpType={}", adviceOpType); + return R.fail(null, "医嘱列表为空,请刷新页面后重试"); } + + // 🔍 Debug日志: 记录请求入口 + log.info("========== BugFix#333/335/336 DEBUG START =========="); + log.info("saveAdvice called, adviceOpType={}, organizationId={}, adviceSaveList.size={}", + adviceOpType, organizationId, adviceSaveList != null ? adviceSaveList.size() : 0); + if (adviceSaveList != null && !adviceSaveList.isEmpty()) { + for (int i = 0; i < adviceSaveList.size(); i++) { + AdviceSaveDto dto = adviceSaveList.get(i); + log.info("Request[{}]: requestId={}, dbOpType={}, adviceType={}, encounterId={}, patientId={}, categoryEnum={}, categoryEnum.class={}, categoryCode={}, categoryCode.class={}", + i, dto.getRequestId(), dto.getDbOpType(), dto.getAdviceType(), + dto.getEncounterId(), dto.getPatientId(), + dto.getCategoryEnum(), dto.getCategoryEnum() != null ? dto.getCategoryEnum().getClass().getName() : "NULL", + dto.getCategoryCode(), dto.getCategoryCode() != null ? dto.getCategoryCode().getClass().getName() : "NULL"); + } + } + + // 🔧 Bug Fix: 校验并补全patientId和encounterId(如果为null,尝试从医嘱记录获取) + for (AdviceSaveDto adviceSaveDto : adviceSaveList) { + // 对于删除操作,如果encounterId为null,尝试从医嘱记录获取 + if (adviceSaveDto.getEncounterId() == null && DbOpType.DELETE.getCode().equals(adviceSaveDto.getDbOpType())) { + // 尝试从各类医嘱记录中获取encounterId + Long requestId = adviceSaveDto.getRequestId(); + if (requestId != null) { + // 尝试从药品医嘱获取 + MedicationRequest medRequest = iMedicationRequestService.getById(requestId); + if (medRequest != null && medRequest.getEncounterId() != null) { + adviceSaveDto.setEncounterId(medRequest.getEncounterId()); + adviceSaveDto.setPatientId(medRequest.getPatientId()); + log.info("BugFix: 删除药品医嘱时自动补全encounterId和patientId: requestId={}, encounterId={}, patientId={}", + requestId, medRequest.getEncounterId(), medRequest.getPatientId()); + } else { + // 尝试从耗材医嘱获取 + DeviceRequest devRequest = iDeviceRequestService.getById(requestId); + if (devRequest != null && devRequest.getEncounterId() != null) { + adviceSaveDto.setEncounterId(devRequest.getEncounterId()); + adviceSaveDto.setPatientId(devRequest.getPatientId()); + log.info("BugFix: 删除耗材医嘱时自动补全encounterId和patientId: requestId={}, encounterId={}, patientId={}", + requestId, devRequest.getEncounterId(), devRequest.getPatientId()); + } else { + // 尝试从诊疗医嘱获取 + ServiceRequest srvRequest = iServiceRequestService.getById(requestId); + if (srvRequest != null && srvRequest.getEncounterId() != null) { + adviceSaveDto.setEncounterId(srvRequest.getEncounterId()); + adviceSaveDto.setPatientId(srvRequest.getPatientId()); + log.info("BugFix: 删除诊疗医嘱时自动补全encounterId和patientId: requestId={}, encounterId={}, patientId={}", + requestId, srvRequest.getEncounterId(), srvRequest.getPatientId()); + } + } + } + } + } + + // 首先检查encounterId是否为null + if (adviceSaveDto.getEncounterId() == null) { + log.error("encounterId为null,无法保存医嘱, dbOpType={}, requestId={}, adviceType={}", + adviceSaveDto.getDbOpType(), adviceSaveDto.getRequestId(), adviceSaveDto.getAdviceType()); + return R.fail(null, "就诊信息不完整,请重新选择患者后再试"); + } + + // 如果patientId为null,尝试从encounter获取 + if (adviceSaveDto.getPatientId() == null) { + // 从就诊记录中获取patientId + Encounter encounter = iEncounterService.getById(adviceSaveDto.getEncounterId()); + if (encounter != null && encounter.getPatientId() != null) { + adviceSaveDto.setPatientId(encounter.getPatientId()); + log.info("自动补全patientId: encounterId={}, patientId={}", + adviceSaveDto.getEncounterId(), encounter.getPatientId()); + } else { + log.error("无法获取patientId: encounterId={}", adviceSaveDto.getEncounterId()); + return R.fail(null, "无法获取患者信息,请重新选择患者"); + } + } + + // 🔧 BugFix#338: 门诊划价新增时校验就诊状态和诊断记录(患者安全) + // 仅对新增/修改操作进行校验,删除操作不需要 + if (!DbOpType.DELETE.getCode().equals(adviceSaveDto.getDbOpType())) { + // 1. 校验就诊状态:必须是已接诊状态 + Encounter encounterCheck = iEncounterService.getById(adviceSaveDto.getEncounterId()); + if (encounterCheck != null) { + // 就诊状态:1=待诊(PLANNED),允许保存的状态 = 2(IN_PROGRESS在诊)、3(ON_HOLD暂离)、4(DISCHARGED诊毕)、5(COMPLETED完成) + if (encounterCheck.getStatusEnum() != null && + encounterCheck.getStatusEnum() != EncounterStatus.IN_PROGRESS.getValue() && + encounterCheck.getStatusEnum() != EncounterStatus.ON_HOLD.getValue() && + encounterCheck.getStatusEnum() != EncounterStatus.DISCHARGED.getValue() && + encounterCheck.getStatusEnum() != EncounterStatus.COMPLETED.getValue()) { + log.error("BugFix#338: 患者未接诊,禁止划价/保存医嘱:encounterId={}, status={}", + adviceSaveDto.getEncounterId(), encounterCheck.getStatusEnum()); + return R.fail(null, "患者尚未接诊,无法保存医嘱。请先完成接诊操作!"); + } + } + } + } + + // 按后端 ItemType 枚举标准分类: + // MEDICINE=1(药品)、DEVICE=2(耗材)、ACTIVITY=3(诊疗)、SURGERY=6(手术) + + // 药品分类:adviceType == 1 + List medicineList = adviceSaveList.stream() + .filter(e -> e.getAdviceType() != null && e.getAdviceType() == ItemType.MEDICINE.getValue()) + .collect(Collectors.toList()); + + // 耗材分类:adviceType == 2 + List deviceList = adviceSaveList.stream() + .filter(e -> e.getAdviceType() != null && e.getAdviceType() == ItemType.DEVICE.getValue()) + .collect(Collectors.toList()); + + // 诊疗分类:adviceType == 3 + List activityList = adviceSaveList.stream() + .filter(e -> e.getAdviceType() != null + && (e.getAdviceType() == ItemType.ACTIVITY.getValue() + || e.getAdviceType() == ItemType.SURGERY.getValue())) // 手术(6)也走诊疗流程 + .collect(Collectors.toList()); + + // 🔍 Debug日志日志: 记录分类结果 + log.info("BugFix#219: 医嘱分类完成 - 药品:{}, 耗材:{}, 诊疗:{}", + medicineList.size(), deviceList.size(), activityList.size()); + // 🔍 Debug日志: 打印所有医嘱的adviceType + for (AdviceSaveDto dto : adviceSaveList) { + log.info("BugFix#219: 医嘱详情 - adviceType:{}, requestId:{}, adviceName:{}, dbOpType:{}", + dto.getAdviceType(), dto.getRequestId(), + dto.getContentJson() != null && dto.getContentJson().contains("adviceName") + ? dto.getContentJson().substring(0, Math.min(100, dto.getContentJson().length())) + : "N/A", + dto.getDbOpType()); + } + + // 统计各类删除操作 + long medDeleteCount = medicineList.stream().filter(e -> DbOpType.DELETE.getCode().equals(e.getDbOpType())).count(); + long devDeleteCount = deviceList.stream().filter(e -> DbOpType.DELETE.getCode().equals(e.getDbOpType())).count(); + long actDeleteCount = activityList.stream().filter(e -> DbOpType.DELETE.getCode().equals(e.getDbOpType())).count(); + log.info("BugFix#219: 待删除数量 - 药品:{}, 耗材:{}, 诊疗:{}", medDeleteCount, devDeleteCount, actDeleteCount); + + /** + * 保存时,校验库存 + */ + if (AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType)) { + List medUpdateList = medicineList.stream().filter(e -> e.getRequestId() != null) + .collect(Collectors.toList()); + List devUpdateList = deviceList.stream().filter(e -> e.getRequestId() != null) + .collect(Collectors.toList()); + // 编辑时,释放本身占用的库存发放 + for (AdviceSaveDto adviceSaveDto : medUpdateList) { + iMedicationDispenseService.deleteMedicationDispense(adviceSaveDto.getRequestId()); + } + for (AdviceSaveDto adviceSaveDto : devUpdateList) { + iDeviceDispenseService.deleteDeviceDispense(adviceSaveDto.getRequestId()); + } + + // 🔧 Bug Fix: 跳过库存校验(临时医嘱已计费,不需要重复校验库存) + // List needCheckList = adviceSaveList.stream() + // .filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType()) + // && !ItemType.ACTIVITY.getValue().equals(e.getAdviceType()) + // && !ItemType.DEVICE.getValue().equals(e.getAdviceType()) + // && !ItemType.SURGERY.getValue().equals(e.getAdviceType())) + // .collect(Collectors.toList()); + // // 校验库存 + // String tipRes = adviceUtils.checkInventory(needCheckList); + // if (tipRes != null) { + // return R.fail(null, tipRes); + // } + } + // 当前时间 + Date curDate = new Date(); + // 医嘱签发编码 + String signCode = assignSeqUtil.getSeq(AssignSeqEnum.ADVICE_SIGN.getPrefix(), 10); + + /** + * 处理药品请求 + */ + List medRequestIdList = this.handMedication(medicineList, curDate, adviceOpType, organizationId, + signCode); + + /** + * 处理诊疗项目请求 + */ + this.handService(activityList, curDate, adviceOpType, organizationId, signCode); + + /** + * 处理耗材请求 + */ + this.handDevice(deviceList, curDate, adviceOpType); + + // 签发时,把草稿状态的账单更新为待收费 + if (AdviceOpType.SIGN_ADVICE.getCode().equals(adviceOpType) && !adviceSaveList.isEmpty()) { + // 签发的医嘱id集合 - 收集所有需要签发的医嘱ID + List requestIds = adviceSaveList.stream() + .filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType()) && e.getRequestId() != null) + .collect(Collectors.toList()).stream().map(AdviceSaveDto::getRequestId) + .collect(Collectors.toList()); + + // 🔧 BugFix: 批量更新药品请求状态为已签发(ACTIVE=2) + if (!requestIds.isEmpty() && !medicineList.isEmpty()) { + List medicineIds = medicineList.stream() + .filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType()) && e.getRequestId() != null) + .map(AdviceSaveDto::getRequestId) + .collect(Collectors.toList()); + if (!medicineIds.isEmpty()) { + log.info("BugFix: 准备批量更新药品医嘱状态,medicineIds={}", medicineIds); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.in("id", medicineIds); + updateWrapper.set("status_enum", RequestStatus.ACTIVE.getValue()); + boolean updateResult = iMedicationRequestService.update(null, updateWrapper); + log.info("BugFix: 批量更新药品医嘱状态为已签发,count={}, result={}", medicineIds.size(), updateResult); + + // 🔧 BugFix: 如果批量更新失败,尝试逐个更新 + if (!updateResult) { + log.warn("BugFix: 批量更新药品医嘱状态失败,尝试逐个更新"); + for (Long medicineId : medicineIds) { + try { + MedicationRequest updateReq = new MedicationRequest(); + updateReq.setId(medicineId); + updateReq.setStatusEnum(RequestStatus.ACTIVE.getValue()); + boolean singleResult = iMedicationRequestService.updateById(updateReq); + log.info("BugFix: 逐个更新药品医嘱状态,id={}, result={}", medicineId, singleResult); + } catch (Exception e) { + log.error("BugFix: 逐个更新药品医嘱状态失败,id={}", medicineId, e); + } + } + } + } + } + // 🔧 BugFix: 批量更新耗材请求状态为已签发(ACTIVE=2) + if (!requestIds.isEmpty() && !deviceList.isEmpty()) { + List deviceIds = deviceList.stream() + .filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType()) && e.getRequestId() != null) + .map(AdviceSaveDto::getRequestId) + .collect(Collectors.toList()); + if (!deviceIds.isEmpty()) { + log.info("BugFix: 准备批量更新耗材医嘱状态,deviceIds={}", deviceIds); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.in("id", deviceIds); + updateWrapper.set("status_enum", RequestStatus.ACTIVE.getValue()); + boolean updateResult = iDeviceRequestService.update(null, updateWrapper); + log.info("BugFix: 批量更新耗材医嘱状态为已签发,count={}, result={}", deviceIds.size(), updateResult); + + // 🔧 BugFix: 如果批量更新失败,尝试逐个更新 + if (!updateResult) { + log.warn("BugFix: 批量更新耗材医嘱状态失败,尝试逐个更新"); + for (Long deviceId : deviceIds) { + try { + DeviceRequest updateReq = new DeviceRequest(); + updateReq.setId(deviceId); + updateReq.setStatusEnum(RequestStatus.ACTIVE.getValue()); + boolean singleResult = iDeviceRequestService.updateById(updateReq); + log.info("BugFix: 逐个更新耗材医嘱状态,id={}, result={}", deviceId, singleResult); + } catch (Exception e) { + log.error("BugFix: 逐个更新耗材医嘱状态失败,id={}", deviceId, e); + } + } + } + } + } + // 🔧 BugFix: 批量更新诊疗请求状态为已签发(ACTIVE=2) + if (!requestIds.isEmpty() && !activityList.isEmpty()) { + List activityIds = activityList.stream() + .filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType()) && e.getRequestId() != null) + .map(AdviceSaveDto::getRequestId) + .collect(Collectors.toList()); + if (!activityIds.isEmpty()) { + log.info("BugFix: 准备批量更新诊疗医嘱状态,activityIds={}", activityIds); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.in("id", activityIds); + updateWrapper.set("status_enum", RequestStatus.ACTIVE.getValue()); + boolean updateResult = iServiceRequestService.update(null, updateWrapper); + log.info("BugFix: 批量更新诊疗医嘱状态为已签发,count={}, result={}", activityIds.size(), updateResult); + + // 🔧 BugFix: 如果批量更新失败,尝试逐个更新 + if (!updateResult) { + log.warn("BugFix: 批量更新诊疗医嘱状态失败,尝试逐个更新"); + for (Long activityId : activityIds) { + try { + ServiceRequest updateReq = new ServiceRequest(); + updateReq.setId(activityId); + updateReq.setStatusEnum(RequestStatus.ACTIVE.getValue()); + boolean singleResult = iServiceRequestService.updateById(updateReq); + log.info("BugFix: 逐个更新诊疗医嘱状态,id={}, result={}", activityId, singleResult); + } catch (Exception e) { + log.error("BugFix: 逐个更新诊疗医嘱状态失败,id={}", activityId, e); + } + } + } + } + } + + // 就诊id + Long encounterId = adviceSaveList.get(0).getEncounterId(); + + // 🔧 BugFix#385: 签发时更新诊疗医嘱关联的费用项诊断信息 + // 检查申请创建的费用项没有诊断关联,需要在签发时补充 + if (!activityList.isEmpty()) { + // 先从就诊中获取主诊断,用于补充没有诊断关联的费用项 + List encounterDiagList = iEncounterDiagnosisService.getDiagnosisList(encounterId); + EncounterDiagnosis mainDiagnosis = iEncounterDiagnosisService.getMainDiagnosis(encounterDiagList); + Long mainConditionId = mainDiagnosis != null ? mainDiagnosis.getConditionId() : null; + Long mainEncounterDiagId = mainDiagnosis != null ? mainDiagnosis.getId() : null; + + log.info("BugFix#385: 签发时获取就诊主诊断, encounterId={}, mainConditionId={}, mainEncounterDiagId={}", + encounterId, mainConditionId, mainEncounterDiagId); + + for (AdviceSaveDto adviceDto : activityList) { + if (adviceDto.getRequestId() != null) { + // 查询诊疗医嘱关联的费用项 + List chargeItems = iChargeItemService.getChargeItemInfoByReqId( + Arrays.asList(adviceDto.getRequestId())); + if (chargeItems != null && !chargeItems.isEmpty()) { + // 过滤只保留诊疗类型的费用项 + ChargeItem chargeItem = chargeItems.stream() + .filter(ci -> CommonConstants.TableName.WOR_SERVICE_REQUEST.equals(ci.getServiceTable())) + .findFirst().orElse(null); + if (chargeItem != null) { + // 🔧 BugFix#385: 如果费用项没有诊断关联,使用主诊断补充 + Long conditionId = adviceDto.getConditionId(); + Long encounterDiagId = adviceDto.getEncounterDiagnosisId(); + + // 如果传入的诊断为空,使用主诊断 + if (conditionId == null) { + conditionId = mainConditionId; + } + if (encounterDiagId == null) { + encounterDiagId = mainEncounterDiagId; + } + + // 更新诊断关联 + if (conditionId != null || encounterDiagId != null) { + chargeItem.setConditionId(conditionId); + chargeItem.setEncounterDiagnosisId(encounterDiagId); + iChargeItemService.updateById(chargeItem); + log.info("BugFix#385: 签发时更新诊疗费用项诊断关联, chargeItemId={}, conditionId={}, encounterDiagnosisId={}", + chargeItem.getId(), conditionId, encounterDiagId); + } + } + } + } + } + } + + // 🔧 BugFix#385: 使用安全的更新方法,避免并发冲突 - 更新费用项状态 + // 需要处理两种情况: + // 1. 从 DRAFT (0) → PLANNED (1):新创建的收费项目 + // 2. 从 BILLABLE (2) → PLANNED (1):保存时已设为待结算的项目 + iChargeItemService.updateChargeStatusByConditionSafe( + encounterId, + ChargeItemStatus.DRAFT.getValue(), + ChargeItemStatus.PLANNED.getValue(), + requestIds); + + // 🔧 BugFix#385: 同时处理 BILLABLE 状态的收费项目 + iChargeItemService.updateChargeStatusByConditionSafe( + encounterId, + ChargeItemStatus.BILLABLE.getValue(), + ChargeItemStatus.PLANNED.getValue(), + requestIds); + } + + // 数据变更后清理相关缓存 + clearRelatedCache(); + + return R.ok(medRequestIdList, + MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] { "门诊医嘱" })); + } catch (Exception e) { + // 异常处理 + throw e; } - - // 默认申请类型为普通 - if (param.getApplicationType() == null) { - param.setApplicationType(1); - } - - // Bug #589 修复:出院带药用药天数安全边界校验 - validateDischargeMedicationDays(param); - - // Bug #588 修复:文字医嘱核心字段与计费拦截校验 - validateTextAdvice(param); - - // Bug #582 修复:根据业务类型动态生成正确的申请单号前缀,避免手术单错用检查前缀 - String applyNo = generateApplyNoByType(param); - param.setApplyNo(applyNo); - - // 执行入库操作 - requestFormManageAppMapper.insertAdvice(param); - return R.ok("保存成功"); } /** - * Bug #582: 根据申请类型匹配对应业务前缀 - * 约定:3-手术(SSZ), 2-检查(JCZ), 其他-检验(JYZ) + * 清理相关缓存 */ - private String generateApplyNoByType(AdviceSaveParam param) { - String prefix; - Integer type = param.getAdviceType(); - if (type != null && type == 3) { - prefix = "SSZ"; - } else if (type != null && type == 2) { - prefix = "JCZ"; - } else { - prefix = "JYZ"; - } - return generateApplyNo(prefix); + private void clearRelatedCache() { + // 目前不使用缓存,此方法为空实现 + // 如果将来启用缓存,可以在这里实现缓存清理逻辑 } /** - * 生成标准单号:前缀 + YYMMDD + 5位独立日流水号 + * 处理药品 */ - private String generateApplyNo(String prefix) { - String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMdd")); - int maxSeq = requestFormManageAppMapper.selectMaxDailySequence(prefix); - String seqStr = String.format("%05d", maxSeq + 1); - return prefix + dateStr + seqStr; + private List handMedication(List medicineList, Date curDate, String adviceOpType, + Long organizationId, String signCode) { + // 当前登录账号的科室id + Long orgId = SecurityUtils.getLoginUser().getOrgId(); + // 获取当前登录用户的tenantId + Integer tenantId = SecurityUtils.getLoginUser().getTenantId(); + // 获取当前登录用户名 + String currentUsername = SecurityUtils.getUsername(); + // 保存操作 + boolean is_save = AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType); + // 签发操作 + boolean is_sign = AdviceOpType.SIGN_ADVICE.getCode().equals(adviceOpType); + // 保存药品请求 + MedicationRequest medicationRequest; + // 声明费用项 + ChargeItem chargeItem; + // 新增 + 修改 + // 🔧 BugFix: 如果 requestId 不为空说明是已存在的医嘱,需要更新,即使 dbOpType 不匹配也应该包含进来 + // 🔧 BugFix #454: 排除删除操作,避免误入insertOrUpdateList + List insertOrUpdateList = medicineList.stream() + .filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType())) + .filter(e -> (DbOpType.INSERT.getCode().equals(e.getDbOpType()) + || DbOpType.UPDATE.getCode().equals(e.getDbOpType()) + || e.getRequestId() != null)) + .collect(Collectors.toList()); + // 删除 + // 🔧 BugFix: 如果 dbOpType 不匹配但 requestId 存在,仍然允许删除(增加健壮性) + List deleteList = medicineList.stream() + .filter(e -> DbOpType.DELETE.getCode().equals(e.getDbOpType())).collect(Collectors.toList()); + // 校验删除的医嘱是否已经收费 + List delRequestIdList = deleteList.stream().map(AdviceSaveDto::getRequestId).collect(Collectors.toList()); + if (!delRequestIdList.isEmpty()) { + List chargeItemList = iChargeItemService.getChargeItemInfoByReqId(delRequestIdList); + // 🔧 BugFix#219: 过滤只保留药品类型的费用项 + if (chargeItemList != null && !chargeItemList.isEmpty()) { + chargeItemList = chargeItemList.stream() + .filter(ci -> CommonConstants.TableName.MED_MEDICATION_REQUEST.equals(ci.getServiceTable())) + .collect(Collectors.toList()); + } + if (chargeItemList != null && !chargeItemList.isEmpty()) { + for (ChargeItem ci : chargeItemList) { + if (ChargeItemStatus.BILLED.getValue().equals(ci.getStatusEnum())) { + throw new ServiceException("已收费的项目无法删除,请刷新页面后重试"); + } + } + } + } + for (AdviceSaveDto adviceSaveDto : deleteList) { + Long requestId = adviceSaveDto.getRequestId(); + // 🔧 Bug #442: 跳过 requestId 为 null 的记录,避免删除不存在的药品请求 + if (requestId == null) { + log.warn("BugFix#442: handMedication - 跳过 requestId 为 null 的删除请求"); + continue; + } + iMedicationRequestService.removeById(requestId); + // 删除已经产生的药品发放信息 + iMedicationDispenseService.deleteMedicationDispense(adviceSaveDto.getRequestId()); + // 🔧 Bug Fix #219: 删除费用项 + String serviceTable = CommonConstants.TableName.MED_MEDICATION_REQUEST; + // 直接删除费用项 + iChargeItemService.deleteByServiceTableAndId(serviceTable, requestId); + log.info("BugFix#219: 药品医嘱删除完成, requestId={}, serviceTable={}", requestId, serviceTable); + // 删除基于这个药品生成的需要执行的诊疗请求 + iServiceRequestService.remove( + new LambdaQueryWrapper() + .eq(ServiceRequest::getBasedOnId, adviceSaveDto.getRequestId()) + .isNotNull(ServiceRequest::getBasedOnTable) + .eq(ServiceRequest::getStatusEnum, RequestStatus.COMPLETED.getValue())); + } + // 签发时 + if (is_sign) { + // 🔧 Bug Fix #328: 只对药品类型的医嘱生成处方号 + // 检验申请单生成的医嘱是诊疗项目(adviceType=3),不需要处方号 + List medicineListForPrescription = insertOrUpdateList.stream() + .filter(e -> ItemType.MEDICINE.getValue().equals(e.getAdviceType())) + .collect(Collectors.toList()); + if (!medicineListForPrescription.isEmpty()) { + prescriptionUtils.generatePrescriptionNumbers(medicineListForPrescription); + } + } + + List medRequestIdList = new ArrayList<>(); + + // 🔧 防重复保存:对新增医嘱进行去重 + // 去重逻辑:针对同一患者、同一就诊、同一药品、同一剂量的医嘱,只保存一条 + Set uniqueKeySet = new HashSet<>(); + List uniqueInsertOrUpdateList = new ArrayList<>(); + + for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) { + // 构建唯一标识键:患者ID + 就诊ID + 药品ID + 剂量 + 用法 + 频次 + String uniqueKey = adviceSaveDto.getPatientId() + "_" + + adviceSaveDto.getEncounterId() + "_" + + adviceSaveDto.getAdviceDefinitionId() + "_" + + adviceSaveDto.getDose() + "_" + + adviceSaveDto.getMethodCode() + "_" + + adviceSaveDto.getRateCode(); + + // 如果是新增操作且唯一标识已存在,则跳过 + if (DbOpType.INSERT.getCode().equals(adviceSaveDto.getDbOpType()) && + uniqueKeySet.contains(uniqueKey)) { + log.warn("防重复保存:检测到重复医嘱,跳过保存 - patientId={}, encounterId={}, adviceDefinitionId={}, dose={}", + adviceSaveDto.getPatientId(), adviceSaveDto.getEncounterId(), + adviceSaveDto.getAdviceDefinitionId(), adviceSaveDto.getDose()); + continue; + } + + // 添加到去重集合和列表 + uniqueKeySet.add(uniqueKey); + uniqueInsertOrUpdateList.add(adviceSaveDto); + } + + // 使用去重后的列表进行保存 + log.info("防重复保存:去重前{}条,去重后{}条", insertOrUpdateList.size(), uniqueInsertOrUpdateList.size()); + insertOrUpdateList = uniqueInsertOrUpdateList; + + for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) { + // 🔧 Bug Fix: 确保accountId有效(不为null且账户存在) + boolean needNewAccount = false; + if (adviceSaveDto.getAccountId() == null) { + needNewAccount = true; + } else { + // 验证账户是否存在且有效(未被删除,租户匹配) + Account existingAccount = iAccountService.getById(adviceSaveDto.getAccountId()); + if (existingAccount == null) { + log.warn("handMedication - 前端传入的accountId无效(账户不存在),accountId={},将重新获取或创建账户", + adviceSaveDto.getAccountId()); + needNewAccount = true; + } + } + + if (needNewAccount) { + // 尝试从患者就诊中获取默认账户ID(自费账户) + Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId()); + if (selfAccount != null) { + adviceSaveDto.setAccountId(selfAccount.getId()); + log.info("handMedication - 使用现有自费账户,accountId={}", selfAccount.getId()); + } else { + // 自动创建自费账户 + Account newAccount = new Account(); + newAccount.setPatientId(adviceSaveDto.getPatientId()); + newAccount.setEncounterId(adviceSaveDto.getEncounterId()); + newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO); + newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode()); + newAccount.setBalanceAmount(BigDecimal.ZERO); + newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue()); + newAccount.setEncounterFlag(Whether.YES.getValue()); + newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo()); + Long newAccountId = iAccountService.saveAccountByRegister(newAccount); + adviceSaveDto.setAccountId(newAccountId); + log.info("handMedication - 自动创建自费账户,newAccountId={}", newAccountId); + } + } + + // 🔧 Bug Fix: 确保practitionerId不为null + if (adviceSaveDto.getPractitionerId() == null) { + adviceSaveDto.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId()); + log.info("handMedication - 自动补全practitionerId: practitionerId={}", adviceSaveDto.getPractitionerId()); + } + + // 🔧 Bug Fix: 确保founderOrgId不为null + if (adviceSaveDto.getFounderOrgId() == null) { + adviceSaveDto.setFounderOrgId(SecurityUtils.getLoginUser().getOrgId()); + log.info("handMedication - 自动补全founderOrgId: founderOrgId={}", adviceSaveDto.getFounderOrgId()); + } + + boolean firstTimeSave = false;// 第一次保存 + medicationRequest = new MedicationRequest(); + medicationRequest.setId(adviceSaveDto.getRequestId()); // 主键id + medicationRequest.setStatusEnum(is_save ? RequestStatus.DRAFT.getValue() : RequestStatus.ACTIVE.getValue()); // 请求状态 + medicationRequest.setPrescriptionNo(adviceSaveDto.getPrescriptionNo()); // 处方号 + medicationRequest.setGroupId(adviceSaveDto.getGroupId()); // 组号 + medicationRequest.setTenantId(tenantId); // 设置租户id + medicationRequest.setCreateBy(currentUsername); // 设置创建人 + medicationRequest.setCreateTime(curDate); // 设置创建时间 + if (is_sign) { + medicationRequest.setSignCode(signCode); + } + // 🔧 Bug Fix: 签发时也需要设置关键字段(修复BUG #181) + // 保存时生成业务编号,签发时沿用已有编号 + if (is_save) { + medicationRequest.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.MEDICATION_RES_NO.getPrefix(), 4)); + } + medicationRequest.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum() != null + ? adviceSaveDto.getGenerateSourceEnum() + : GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源 + medicationRequest.setQuantity(adviceSaveDto.getQuantity()); // 请求数量 + medicationRequest.setExecuteNum(adviceSaveDto.getExecuteNum()); // 执行次数 + medicationRequest.setUnitCode(adviceSaveDto.getUnitCode()); // 请求单位编码 + medicationRequest.setLotNumber(adviceSaveDto.getLotNumber()); // 产品批号 + medicationRequest.setCategoryEnum(adviceSaveDto.getCategoryEnum()); // 请求类型 + medicationRequest.setMedicationId(adviceSaveDto.getAdviceDefinitionId());// 医嘱定义id + medicationRequest.setPatientId(adviceSaveDto.getPatientId()); // 患者 + medicationRequest.setPractitionerId(adviceSaveDto.getPractitionerId()); // 开方医生 + medicationRequest.setOrgId(adviceSaveDto.getFounderOrgId()); // 开方人科室 + medicationRequest.setReqAuthoredTime(curDate); // 请求开始时间 + // 发放药房 + medicationRequest.setPerformLocation(adviceSaveDto.getLocationId()); + medicationRequest.setEncounterId(adviceSaveDto.getEncounterId()); // 就诊id + medicationRequest.setConditionId(adviceSaveDto.getConditionId()); // 诊断id + medicationRequest.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id + medicationRequest.setTherapyEnum(adviceSaveDto.getTherapyEnum()); // 治疗类型,默认-临时 + medicationRequest.setMethodCode(adviceSaveDto.getMethodCode()); // 用法 + medicationRequest.setRateCode(adviceSaveDto.getRateCode()); // 用药频次 + medicationRequest.setDose(adviceSaveDto.getDose()); // 单次剂量 + medicationRequest.setDoseUnitCode(adviceSaveDto.getDoseUnitCode()); // 剂量单位 + medicationRequest.setDispensePerDuration(adviceSaveDto.getDispensePerDuration()); // 每次发药供应天数 + medicationRequest.setPackageId(adviceSaveDto.getPackageId()); // 组套id + medicationRequest.setContentJson(adviceSaveDto.getContentJson()); // 请求内容json + medicationRequest.setYbClassEnum(adviceSaveDto.getYbClassEnum());// 类别医保编码 + medicationRequest.setSkinTestFlag(adviceSaveDto.getSkinTestFlag()); // 皮试标志 + medicationRequest.setInfusionFlag(adviceSaveDto.getInjectFlag()); // 输液标志 + medicationRequest.setSortNumber(adviceSaveDto.getSortNumber()); // 排序号 + + if (medicationRequest.getId() == null) { + firstTimeSave = true; + } + iMedicationRequestService.saveOrUpdate(medicationRequest); + if (firstTimeSave) { + medRequestIdList.add(medicationRequest.getId().toString()); + } + if (is_save) { + // 处理药品发放 + Long dispenseId = iMedicationDispenseService.handleMedicationDispense(medicationRequest, + adviceSaveDto.getDbOpType()); + + // 保存药品费用项 + chargeItem = new ChargeItem(); + chargeItem.setId(adviceSaveDto.getChargeItemId()); // 费用项id + chargeItem.setStatusEnum(2); // 已生成医嘱 + chargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(medicationRequest.getBusNo())); + chargeItem.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum() != null + ? adviceSaveDto.getGenerateSourceEnum() + : GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源 + chargeItem.setPrescriptionNo(adviceSaveDto.getPrescriptionNo()); // 处方号 + chargeItem.setPatientId(adviceSaveDto.getPatientId()); // 患者 + chargeItem.setContextEnum(adviceSaveDto.getAdviceType()); // 类型 + chargeItem.setEncounterId(adviceSaveDto.getEncounterId()); // 就诊id + // 🔧 Bug Fix: 如果definitionId为空,使用adviceDefinitionId作为后备 + Long definitionId = adviceSaveDto.getDefinitionId(); + if (definitionId == null) { + definitionId = adviceSaveDto.getAdviceDefinitionId(); + } + chargeItem.setDefinitionId(definitionId); // 费用定价ID + chargeItem.setDefDetailId(adviceSaveDto.getDefinitionDetailId()); // 定价子表主键 + chargeItem.setEntererId(adviceSaveDto.getPractitionerId());// 开立人ID + chargeItem.setRequestingOrgId(orgId); // 开立科室 + chargeItem.setEnteredDate(curDate); // 开立时间 + chargeItem.setServiceTable(CommonConstants.TableName.MED_MEDICATION_REQUEST);// 医疗服务类型 + chargeItem.setServiceId(medicationRequest.getId()); // 医疗服务ID + chargeItem.setProductTable(adviceSaveDto.getAdviceTableName());// 产品所在表 + chargeItem.setProductId(adviceSaveDto.getAdviceDefinitionId());// 收费项id + chargeItem.setAccountId(adviceSaveDto.getAccountId());// 关联账户ID + chargeItem.setConditionId(adviceSaveDto.getConditionId()); // 诊断id + chargeItem.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id + chargeItem.setDispenseId(dispenseId); // 发放ID + chargeItem.setTenantId(tenantId); // 设置租户ID (修复本次报错) + chargeItem.setCreateBy(currentUsername); // 设置创建人 + chargeItem.setCreateTime(curDate); // 设置创建时间 + + chargeItem.setQuantityValue(adviceSaveDto.getQuantity()); // 数量 + chargeItem.setQuantityUnit(adviceSaveDto.getUnitCode()); // 单位 + // #415 价格非负验证 + BigDecimal unitPrice = adviceSaveDto.getUnitPrice(); + if (unitPrice != null && unitPrice.compareTo(BigDecimal.ZERO) < 0) { + unitPrice = unitPrice.abs(); // 负数取绝对值 + } + chargeItem.setUnitPrice(unitPrice); // 单价 + chargeItem.setTotalPrice(adviceSaveDto.getTotalPrice()); // 总价 + + // 显式设置tenantId、createBy和createTime字段,防止自动填充机制失效 + chargeItem.setTenantId(SecurityUtils.getLoginUser().getTenantId()); + chargeItem.setCreateBy(SecurityUtils.getLoginUser().getUsername()); + chargeItem.setCreateTime(new Date()); + + iChargeItemService.saveOrUpdate(chargeItem); + + // 显式更新前端传的chargeItemId对应的收费项目状态为2(已生成医嘱) + if (adviceSaveDto.getChargeItemId() != null) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(ChargeItem::getId, adviceSaveDto.getChargeItemId()) + .set(ChargeItem::getStatusEnum, 2); + iChargeItemService.update(updateWrapper); + log.info("已更新药品收费项目状态为已生成医嘱,chargeItemId:{}", adviceSaveDto.getChargeItemId()); + } + + // 🔧 Bug Fix #145: 处理用法绑定的耗材 + if (StringUtils.isNotBlank(adviceSaveDto.getMethodCode())) { + handleBoundDevices(adviceSaveDto, medicationRequest, chargeItem, curDate, orgId, tenantId, + currentUsername); + } + + } + } + return medRequestIdList; } - private void validateDischargeMedicationDays(AdviceSaveParam param) { - // 原有逻辑保留 + /** + * 处理用法绑定的耗材 + * + * @param adviceSaveDto 医嘱保存DTO + * @param medicationRequest 药品请求 + * @param medicationChargeItem 药品费用项 + * @param curDate 当前时间 + * @param orgId 科室ID + * @param tenantId 租户ID + * @param currentUsername 当前用户名 + */ + private void handleBoundDevices(AdviceSaveDto adviceSaveDto, MedicationRequest medicationRequest, + ChargeItem medicationChargeItem, Date curDate, Long orgId, Integer tenantId, String currentUsername) { + // 查询用法绑定的耗材 (typeCode=1表示用法绑定) + List boundDevices = outpatientRegistrationAppMapper.getBoundDevicesByUsage( + adviceSaveDto.getMethodCode(), + CommonConstants.TableName.ADM_DEVICE_DEFINITION, "1"); + + if (boundDevices == null || boundDevices.isEmpty()) { + return; + } + + for (ActivityDeviceDto boundDevice : boundDevices) { + // 创建耗材请求 + DeviceRequest deviceRequest = new DeviceRequest(); + deviceRequest.setStatusEnum(RequestStatus.DRAFT.getValue()); + deviceRequest.setTenantId(tenantId); + deviceRequest.setCreateBy(currentUsername); + deviceRequest.setCreateTime(curDate); + deviceRequest.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.DEVICE_RES_NO.getPrefix(), 4)); + deviceRequest.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum() != null + ? adviceSaveDto.getGenerateSourceEnum() + : GenerateSource.DOCTOR_PRESCRIPTION.getValue()); + deviceRequest.setQuantity(boundDevice.getQuantity()); + deviceRequest.setUnitCode(boundDevice.getUnitCode()); + deviceRequest.setCategoryEnum(adviceSaveDto.getCategoryEnum()); + deviceRequest.setDeviceDefId(boundDevice.getDevActId()); + deviceRequest.setPatientId(adviceSaveDto.getPatientId()); + deviceRequest.setRequesterId(adviceSaveDto.getPractitionerId()); + deviceRequest.setOrgId(adviceSaveDto.getFounderOrgId()); + deviceRequest.setReqAuthoredTime(curDate); + deviceRequest.setPerformLocation(adviceSaveDto.getLocationId()); + deviceRequest.setEncounterId(adviceSaveDto.getEncounterId()); + deviceRequest.setConditionId(adviceSaveDto.getConditionId()); + deviceRequest.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); + // 关联到药品请求 + deviceRequest.setBasedOnId(medicationRequest.getId()); + deviceRequest.setBasedOnTable(CommonConstants.TableName.MED_MEDICATION_REQUEST); + // 🔧 Bug Fix #145: 设置处方号,确保门诊收费能正确显示 + deviceRequest.setPrescriptionNo(adviceSaveDto.getPrescriptionNo()); + + iDeviceRequestService.save(deviceRequest); + + // 处理耗材发放 + Long dispenseId = iDeviceDispenseService.handleDeviceDispense(deviceRequest, DbOpType.INSERT.getCode()); + + // 查询耗材定价信息 - 直接使用mapper查询,避免递归调用getAdviceBaseInfo导致栈溢出 + IPage devicePage = doctorStationAdviceAppMapper.getAdviceBaseInfo( + new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(1, 1), + PublicationStatus.ACTIVE.getValue(), + adviceSaveDto.getFounderOrgId(), + null, + CommonConstants.TableName.ADM_DEVICE_DEFINITION, + null, + null, + List.of(boundDevice.getDevActId()), + null, + null, + null, + null); + + if (devicePage == null || devicePage.getRecords().isEmpty()) { + log.warn("无法找到耗材定价信息: deviceDefId={}", boundDevice.getDevActId()); + continue; + } + + AdviceBaseDto deviceBaseInfo = devicePage.getRecords().get(0); + + // 查询价格信息 - 直接查询定价主表 + List mainCharge = doctorStationAdviceAppMapper.getMainCharge( + List.of(deviceBaseInfo.getChargeItemDefinitionId()), PublicationStatus.ACTIVE.getValue()); + + if (mainCharge == null || mainCharge.isEmpty()) { + log.warn("耗材没有定价信息: deviceDefId={}", boundDevice.getDevActId()); + continue; + } + + AdvicePriceDto devicePrice = mainCharge.get(0); + devicePrice.setDefinitionId(deviceBaseInfo.getChargeItemDefinitionId()); + // 如果需要定价子表ID,可以从mainCharge中获取 + + // 创建耗材费用项 + ChargeItem deviceChargeItem = new ChargeItem(); + deviceChargeItem.setTenantId(tenantId); + deviceChargeItem.setCreateBy(currentUsername); + deviceChargeItem.setCreateTime(curDate); + deviceChargeItem.setStatusEnum(ChargeItemStatus.PLANNED.getValue()); + deviceChargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(deviceRequest.getBusNo())); + deviceChargeItem.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum() != null + ? adviceSaveDto.getGenerateSourceEnum() + : GenerateSource.DOCTOR_PRESCRIPTION.getValue()); + deviceChargeItem.setPrescriptionNo(adviceSaveDto.getPrescriptionNo()); // 处方号,与药品一致 + deviceChargeItem.setPatientId(adviceSaveDto.getPatientId()); + deviceChargeItem.setContextEnum(ChargeItemContext.DEVICE.getValue()); // 耗材类型 + deviceChargeItem.setEncounterId(adviceSaveDto.getEncounterId()); + deviceChargeItem.setDefinitionId(devicePrice.getDefinitionId()); + deviceChargeItem.setDefDetailId(devicePrice.getDefinitionDetailId()); + deviceChargeItem.setEntererId(adviceSaveDto.getPractitionerId()); + deviceChargeItem.setRequestingOrgId(orgId); + deviceChargeItem.setEnteredDate(curDate); + deviceChargeItem.setServiceTable(CommonConstants.TableName.WOR_DEVICE_REQUEST); + deviceChargeItem.setServiceId(deviceRequest.getId()); + deviceChargeItem.setProductTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION); + deviceChargeItem.setProductId(boundDevice.getDevActId()); + // 🔧 Bug Fix #281: 如果accountId为null,从就诊中获取账户ID,如果没有则自动创建 + Long deviceAccountId = adviceSaveDto.getAccountId(); + if (deviceAccountId == null) { + // 尝试从患者就诊中获取默认账户ID(自费账户) + Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId()); + if (selfAccount != null) { + deviceAccountId = selfAccount.getId(); + } else { + // 自动创建自费账户 + Account newAccount = new Account(); + newAccount.setPatientId(adviceSaveDto.getPatientId()); + newAccount.setEncounterId(adviceSaveDto.getEncounterId()); + newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO); + newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode()); + newAccount.setBalanceAmount(BigDecimal.ZERO); + newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue()); + newAccount.setEncounterFlag(Whether.YES.getValue()); + // 🔧 Bug Fix: 设置账户名称,避免数据库NOT NULL约束错误 + newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo()); + deviceAccountId = iAccountService.saveAccountByRegister(newAccount); + } + } + deviceChargeItem.setAccountId(deviceAccountId); + deviceChargeItem.setConditionId(adviceSaveDto.getConditionId()); + deviceChargeItem.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); + deviceChargeItem.setDispenseId(dispenseId); + deviceChargeItem.setQuantityValue(boundDevice.getQuantity()); + deviceChargeItem.setQuantityUnit(boundDevice.getUnitCode()); + deviceChargeItem.setUnitPrice(devicePrice.getPrice()); + deviceChargeItem.setTotalPrice(boundDevice.getQuantity().multiply(devicePrice.getPrice())); + + iChargeItemService.save(deviceChargeItem); + + log.info("用法绑定耗材已创建: methodCode={}, deviceDefId={}, chargeItemId={}", + adviceSaveDto.getMethodCode(), boundDevice.getDevActId(), deviceChargeItem.getId()); + } } - private void validateTextAdvice(AdviceSaveParam param) { - // 原有逻辑保留 + /** + * 处理耗材 + */ + private void handDevice(List deviceList, Date curDate, String adviceOpType) { + // 🔍 Debug日志: handDevice方法入口 + log.info("BugFix#219: ========== handDevice START =========="); + log.info("BugFix#219: handDevice called, deviceList.size={}, adviceOpType={}", + deviceList != null ? deviceList.size() : 0, adviceOpType); + if (deviceList != null && !deviceList.isEmpty()) { + for (int i = 0; i < deviceList.size(); i++) { + AdviceSaveDto dto = deviceList.get(i); + log.info("BugFix#219: Device[{}]: requestId={}, dbOpType={}", + i, dto.getRequestId(), dto.getDbOpType()); + } + } + + // 当前登录账号的科室id + Long orgId = SecurityUtils.getLoginUser().getOrgId(); + // 获取当前登录用户的tenantId + Integer tenantId = SecurityUtils.getLoginUser().getTenantId(); + // 获取当前登录用户名 + String currentUsername = SecurityUtils.getUsername(); + // 保存操作 + boolean is_save = AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType); + // 签发操作 + // boolean is_sign = AdviceOpType.SIGN_ADVICE.getCode().equals(adviceOpType); + DeviceRequest deviceRequest; + // 声明费用项 + ChargeItem chargeItem; + // 新增 + 修改 + // 🔧 BugFix: 如果 requestId 不为空说明是已存在的医嘱,需要更新,即使 dbOpType 不匹配也应该包含进来 + // 🔧 BugFix #454: 排除删除操作,避免误入insertOrUpdateList + List insertOrUpdateList = deviceList.stream() + .filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType())) + .filter(e -> (DbOpType.INSERT.getCode().equals(e.getDbOpType()) + || DbOpType.UPDATE.getCode().equals(e.getDbOpType()) + || e.getRequestId() != null)) + .collect(Collectors.toList()); + // 删除 + List deleteList = deviceList.stream() + .filter(e -> DbOpType.DELETE.getCode().equals(e.getDbOpType())).collect(Collectors.toList()); + + // 🔍 Debug日志: 记录删除列表 + log.info("BugFix#219: handDevice - insertOrUpdateList.size={}, deleteList.size={}", + insertOrUpdateList.size(), deleteList.size()); + if (!deleteList.isEmpty()) { + for (AdviceSaveDto dto : deleteList) { + log.info("BugFix#219: handDevice - 待删除: requestId={}", dto.getRequestId()); + } + } + + // 校验删除的医嘱是否已经收费 + List delRequestIdList = deleteList.stream().map(AdviceSaveDto::getRequestId).collect(Collectors.toList()); + if (!delRequestIdList.isEmpty()) { + List chargeItemList = iChargeItemService.getChargeItemInfoByReqId(delRequestIdList); + // 🔧 BugFix#219: 过滤只保留耗材类型的费用项 + if (chargeItemList != null && !chargeItemList.isEmpty()) { + chargeItemList = chargeItemList.stream() + .filter(ci -> CommonConstants.TableName.WOR_DEVICE_REQUEST.equals(ci.getServiceTable())) + .collect(Collectors.toList()); + } + if (chargeItemList != null && !chargeItemList.isEmpty()) { + for (ChargeItem ci : chargeItemList) { + if (ChargeItemStatus.BILLED.getValue().equals(ci.getStatusEnum())) { + throw new ServiceException("已收费的项目无法删除,请刷新页面后重试"); + } + } + } + } + // 🔍 Debug日志: 开始删除循环 + log.info("BugFix#219: handDevice - 开始删除循环, deleteList.size={}", deleteList.size()); + for (AdviceSaveDto adviceSaveDto : deleteList) { + Long requestId = adviceSaveDto.getRequestId(); + // 🔧 Bug #442: 跳过 requestId 为 null 的记录,避免删除不存在的耗材请求 + if (requestId == null) { + log.warn("BugFix#442: handDevice - 跳过 requestId 为 null 的删除请求"); + continue; + } + log.info("BugFix#219: handDevice - 删除开始: requestId={}", requestId); + + // 1. 删除耗材请求 + boolean deviceRemoved = iDeviceRequestService.removeById(requestId); + log.info("BugFix#219: handDevice - 删除DeviceRequest: requestId={}, result={}", requestId, deviceRemoved); + + // 2. 删除已经产生的耗材发放信息 + iDeviceDispenseService.deleteDeviceDispense(requestId); + log.info("BugFix#219: handDevice - 删除DeviceDispense: requestId={}", requestId); + + // 3. 删除费用项 + String serviceTable = CommonConstants.TableName.WOR_DEVICE_REQUEST; + // 先查询费用项是否存在 + try { + List existingChargeItems = iChargeItemService.getChargeItemInfoByReqId(Arrays.asList(requestId)); + log.info("BugFix#219: handDevice - 查询到费用项数量: requestId={}, count={}", requestId, + existingChargeItems != null ? existingChargeItems.size() : 0); + if (existingChargeItems != null) { + for (ChargeItem ci : existingChargeItems) { + log.info("BugFix#219: handDevice - 费用项详情: id={}, serviceTable={}, serviceId={}, status={}", + ci.getId(), ci.getServiceTable(), ci.getServiceId(), ci.getStatusEnum()); + } + } + } catch (Exception e) { + log.error("BugFix#219: handDevice - 查询费用项异常: requestId={}", requestId, e); + } + // 直接删除费用项(使用serviceTable和serviceId作为条件) + iChargeItemService.deleteByServiceTableAndId(serviceTable, requestId); + log.info("BugFix#219: handDevice - 删除ChargeItem: requestId={}, serviceTable={}", requestId, serviceTable); + log.info("BugFix#219: handDevice - 删除完成: requestId={}", requestId); + } + log.info("BugFix#219: ========== handDevice END =========="); + + for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) { + // 🔧 Bug Fix: 确保accountId有效(不为null且账户存在) + boolean needNewAccount = false; + if (adviceSaveDto.getAccountId() == null) { + needNewAccount = true; + } else { + // 验证账户是否存在且有效(未被删除,租户匹配) + Account existingAccount = iAccountService.getById(adviceSaveDto.getAccountId()); + if (existingAccount == null) { + log.warn("handDevice - 前端传入的accountId无效(账户不存在),accountId={},将重新获取或创建账户", + adviceSaveDto.getAccountId()); + needNewAccount = true; + } + } + + if (needNewAccount) { + // 尝试从患者就诊中获取默认账户ID(自费账户) + Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId()); + if (selfAccount != null) { + adviceSaveDto.setAccountId(selfAccount.getId()); + log.info("handDevice - 使用现有自费账户,accountId={}", selfAccount.getId()); + } else { + // 自动创建自费账户 + Account newAccount = new Account(); + newAccount.setPatientId(adviceSaveDto.getPatientId()); + newAccount.setEncounterId(adviceSaveDto.getEncounterId()); + newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO); + newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode()); + newAccount.setBalanceAmount(BigDecimal.ZERO); + newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue()); + newAccount.setEncounterFlag(Whether.YES.getValue()); + newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo()); + Long newAccountId = iAccountService.saveAccountByRegister(newAccount); + adviceSaveDto.setAccountId(newAccountId); + log.info("handDevice - 自动创建自费账户,newAccountId={}", newAccountId); + } + } + + // 🔧 Bug Fix: 确保practitionerId不为null + if (adviceSaveDto.getPractitionerId() == null) { + adviceSaveDto.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId()); + log.info("自动补全practitionerId: practitionerId={}", adviceSaveDto.getPractitionerId()); + } + + // 🔧 Bug Fix: 确保founderOrgId不为null + if (adviceSaveDto.getFounderOrgId() == null) { + adviceSaveDto.setFounderOrgId(SecurityUtils.getLoginUser().getOrgId()); + log.info("自动补全founderOrgId: founderOrgId={}", adviceSaveDto.getFounderOrgId()); + } + + deviceRequest = new DeviceRequest(); + deviceRequest.setId(adviceSaveDto.getRequestId()); // 主键id + deviceRequest.setStatusEnum(is_save ? RequestStatus.DRAFT.getValue() : RequestStatus.ACTIVE.getValue()); // 请求状态 + deviceRequest.setTenantId(SecurityUtils.getLoginUser().getTenantId()); // 显式设置租户ID + // 显式设置审计字段,防止自动填充机制失效 + deviceRequest.setCreateBy(SecurityUtils.getLoginUser().getUsername()); + deviceRequest.setCreateTime(new Date()); + deviceRequest.setTenantId(tenantId); // 设置租户id + deviceRequest.setCreateBy(currentUsername); // 设置创建人 + deviceRequest.setCreateTime(curDate); // 设置创建时间 + + // 🔧 Bug Fix: 签发时也需要设置关键字段(修复BUG #181) + // 保存时生成业务编号,签发时沿用已有编号 + if (is_save) { + deviceRequest.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.DEVICE_RES_NO.getPrefix(), 4)); + } + deviceRequest.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum() != null + ? adviceSaveDto.getGenerateSourceEnum() + : GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源 + deviceRequest.setPrescriptionNo(adviceSaveDto.getSourceBillNo()); // 来源业务单据号(手术单号) + deviceRequest.setQuantity(adviceSaveDto.getQuantity()); // 请求数量 + deviceRequest.setUnitCode(adviceSaveDto.getUnitCode()); // 请求单位编码 + deviceRequest.setLotNumber(adviceSaveDto.getLotNumber());// 产品批号 + + deviceRequest.setCategoryEnum(adviceSaveDto.getCategoryEnum()); // 请求类型 + // 🔧 BugFix #498: categoryEnum=22(检查) 走 ServiceRequest,不走 DeviceRequest + // 检查申请单的诊疗定义ID存在 activityId,不在 adviceDefinitionId + // deviceDefId 对应耗材定义ID,不能用诊疗定义ID填充 + if (Integer.valueOf(22).equals(adviceSaveDto.getCategoryEnum())) { + log.info("handDevice skip - 检查申请单(categoryEnum=22) 走 ServiceRequest 路径,跳过 DeviceRequest 保存"); + continue; // 跳过本次循环,不走耗材请求路径 + } else if (adviceSaveDto.getAdviceDefinitionId() != null) { + deviceRequest.setDeviceDefId(adviceSaveDto.getAdviceDefinitionId());// 耗材定义id + } else { + log.warn("handDevice - deviceDefId 为空,adviceDefinitionId=null, categoryEnum={}", adviceSaveDto.getCategoryEnum()); + } + + deviceRequest.setPatientId(adviceSaveDto.getPatientId()); // 患者 + deviceRequest.setRequesterId(adviceSaveDto.getPractitionerId()); // 开方医生 + deviceRequest.setOrgId(adviceSaveDto.getFounderOrgId());// 开方人科室 + deviceRequest.setReqAuthoredTime(curDate); // 请求开始时间 + // 发放耗材房(若前端未传locationId,优先沿用已有DeviceRequest的performLocation,否则使用登录用户科室) + Long locId = adviceSaveDto.getLocationId(); + if (locId == null) { + // 尝试从已有DeviceRequest获取原始的performLocation + if (adviceSaveDto.getRequestId() != null) { + DeviceRequest existingDevice = iDeviceRequestService.getById(adviceSaveDto.getRequestId()); + if (existingDevice != null && existingDevice.getPerformLocation() != null) { + locId = existingDevice.getPerformLocation(); + log.info("耗材locationId为空,使用已有DeviceRequest的performLocation: locationId={}", locId); + } + } + // 如果已有记录也没有performLocation,则使用登录用户科室作为兜底 + if (locId == null) { + locId = SecurityUtils.getLoginUser().getOrgId(); + log.info("耗材locationId为空且无已有记录,使用登录用户科室作为默认值: locationId={}", locId); + } + } + deviceRequest.setPerformLocation(locId); + deviceRequest.setEncounterId(adviceSaveDto.getEncounterId()); // 就诊id + deviceRequest.setPackageId(adviceSaveDto.getPackageId()); // 组套id + // deviceRequest.setActivityId(adviceSaveDto.getActivityId()); + deviceRequest.setContentJson(adviceSaveDto.getContentJson()); // 请求内容json + deviceRequest.setYbClassEnum(adviceSaveDto.getYbClassEnum());// 类别医保编码 + deviceRequest.setConditionId(adviceSaveDto.getConditionId()); // 诊断id + deviceRequest.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id + + iDeviceRequestService.saveOrUpdate(deviceRequest); + if (is_save) { + // 处理耗材发放 + Long dispenseId = iDeviceDispenseService.handleDeviceDispense(deviceRequest, + adviceSaveDto.getDbOpType()); + + // 保存耗材费用项 + chargeItem = new ChargeItem(); + chargeItem.setId(adviceSaveDto.getChargeItemId()); // 费用项 id + chargeItem.setTenantId(tenantId); // 补全租户 ID + chargeItem.setCreateBy(currentUsername); // 补全创建人 + chargeItem.setCreateTime(curDate); // 补全创建时间 + chargeItem.setStatusEnum(2); // 已生成医嘱 + chargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(deviceRequest.getBusNo())); + chargeItem.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum() != null + ? adviceSaveDto.getGenerateSourceEnum() + : GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源 + chargeItem.setPatientId(adviceSaveDto.getPatientId()); // 患者 + chargeItem.setContextEnum(adviceSaveDto.getAdviceType()); // 类型 + chargeItem.setEncounterId(adviceSaveDto.getEncounterId()); // 就诊id + // 🔧 Bug Fix: 如果definitionId为空,使用adviceDefinitionId作为后备 + Long defId = adviceSaveDto.getDefinitionId(); + if (defId == null) { + defId = adviceSaveDto.getAdviceDefinitionId(); + } + chargeItem.setDefinitionId(defId); // 费用定价ID + chargeItem.setDefDetailId(adviceSaveDto.getDefinitionDetailId()); // 定价子表主键 + chargeItem.setEntererId(adviceSaveDto.getPractitionerId());// 开立人ID + chargeItem.setRequestingOrgId(orgId); // 开立科室 + chargeItem.setEnteredDate(curDate); // 开立时间 + chargeItem.setServiceTable(CommonConstants.TableName.WOR_DEVICE_REQUEST);// 医疗服务类型 + chargeItem.setServiceId(deviceRequest.getId()); // 医疗服务ID + chargeItem.setProductTable(adviceSaveDto.getAdviceTableName());// 产品所在表 + chargeItem.setProductId(adviceSaveDto.getAdviceDefinitionId());// 收费项id + + // 🔧 Bug Fix: 如果 definitionId 或 definitionDetailId 为 null,从定价信息中获取 + if (chargeItem.getDefinitionId() == null || chargeItem.getDefDetailId() == null) { + log.warn("耗材的 definitionId 或 definitionDetailId 为 null,尝试从定价信息中获取: deviceDefId={}", + adviceSaveDto.getAdviceDefinitionId()); + // 查询耗材定价信息 + log.warn("查询耗材定价信息: orgId={}, deviceDefId={}", orgId, adviceSaveDto.getAdviceDefinitionId()); + IPage devicePage = doctorStationAdviceAppMapper.getAdviceBaseInfo( + new Page<>(1, 1), + PublicationStatus.ACTIVE.getValue(), + orgId, + CommonConstants.TableName.ADM_DEVICE_DEFINITION, + null, + null, + null, + Arrays.asList(adviceSaveDto.getAdviceDefinitionId()), + null, + null, + null, + null); + if (devicePage != null && !devicePage.getRecords().isEmpty()) { + AdviceBaseDto deviceBaseInfo = devicePage.getRecords().get(0); + if (deviceBaseInfo.getPriceList() != null && !deviceBaseInfo.getPriceList().isEmpty()) { + AdvicePriceDto devicePrice = deviceBaseInfo.getPriceList().get(0); + if (chargeItem.getDefinitionId() == null) { + chargeItem.setDefinitionId(devicePrice.getDefinitionId()); + log.info("从定价信息中获取 definitionId: {}", devicePrice.getDefinitionId()); + } + if (chargeItem.getDefDetailId() == null) { + chargeItem.setDefDetailId(devicePrice.getDefinitionDetailId()); + log.info("从定价信息中获取 definitionDetailId: {}", devicePrice.getDefinitionDetailId()); + } + } + } + } + + // 如果definitionId为null,使用前端传入的价格信息 + if (chargeItem.getDefinitionId() == null) { + log.warn("无法获取耗材的 definitionId,使用前端传入的价格: deviceDefId={}", adviceSaveDto.getAdviceDefinitionId()); + // 不抛异常,使用前端传入的unitPrice和totalPrice + } + + // 🔧 Bug Fix: 如果accountId为null,从就诊中获取账户ID,如果没有则自动创建 + Long accountId = adviceSaveDto.getAccountId(); + if (accountId == null) { + // 尝试从患者就诊中获取默认账户ID(自费账户) + Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId()); + if (selfAccount != null) { + accountId = selfAccount.getId(); + } else { + // 自动创建自费账户 + Account newAccount = new Account(); + newAccount.setPatientId(adviceSaveDto.getPatientId()); + newAccount.setEncounterId(adviceSaveDto.getEncounterId()); + newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO); + newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode()); + newAccount.setBalanceAmount(BigDecimal.ZERO); + newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue()); + newAccount.setEncounterFlag(Whether.YES.getValue()); + // 🔧 Bug Fix: 设置账户名称,避免数据库NOT NULL约束错误 + newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo()); + accountId = iAccountService.saveAccountByRegister(newAccount); + } + } + chargeItem.setAccountId(accountId);// 关联账户ID + chargeItem.setConditionId(adviceSaveDto.getConditionId()); // 诊断id + chargeItem.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id + chargeItem.setDispenseId(dispenseId); // 发放ID + + chargeItem.setQuantityValue(adviceSaveDto.getQuantity()); // 数量 + chargeItem.setQuantityUnit(adviceSaveDto.getUnitCode()); // 单位 + // #415 价格非负验证 + BigDecimal unitPrice = adviceSaveDto.getUnitPrice(); + if (unitPrice != null && unitPrice.compareTo(BigDecimal.ZERO) < 0) { + unitPrice = unitPrice.abs(); // 负数取绝对值 + } + chargeItem.setUnitPrice(unitPrice); // 单价 + chargeItem.setTotalPrice(adviceSaveDto.getTotalPrice()); // 总价 + + // 显式设置审计字段,防止自动填充机制失效 + chargeItem.setTenantId(SecurityUtils.getLoginUser().getTenantId()); + chargeItem.setCreateBy(SecurityUtils.getLoginUser().getUsername()); + chargeItem.setCreateTime(new Date()); + + iChargeItemService.saveOrUpdate(chargeItem); + + // 显式更新前端传的chargeItemId对应的收费项目状态为2(已生成医嘱) + if (adviceSaveDto.getChargeItemId() != null) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(ChargeItem::getId, adviceSaveDto.getChargeItemId()) + .set(ChargeItem::getStatusEnum, 2); + iChargeItemService.update(updateWrapper); + log.info("已更新耗材收费项目状态为已生成医嘱,chargeItemId:{}", adviceSaveDto.getChargeItemId()); + } + } + } } + + /** + * 从诊疗医嘱 contentJson 中解析检验申请单号(检验保存时写入形如 {"applyNo":"..."})。 + */ + private String extractInspectionApplyNoFromContentJson(String contentJson) { + if (StringUtils.isBlank(contentJson) || !contentJson.contains("applyNo")) { + return null; + } + Matcher m = INSPECTION_APPLY_NO_JSON.matcher(contentJson); + if (!m.find()) { + return null; + } + String applyNo = m.group(1).trim(); + return StringUtils.isBlank(applyNo) ? null : applyNo; + } + + + /** + * 处理诊疗 + */ + private void handService(List activityList, Date curDate, String adviceOpType, Long organizationId, + String signCode) { + // 当前登录账号的科室id + Long orgId = SecurityUtils.getLoginUser().getOrgId(); + // 获取当前登录用户的tenantId + Integer tenantId = SecurityUtils.getLoginUser().getTenantId(); + // 获取当前登录用户名 + String currentUsername = SecurityUtils.getUsername(); + // 保存操作 + boolean is_save = AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType); + // 签发操作 + boolean is_sign = AdviceOpType.SIGN_ADVICE.getCode().equals(adviceOpType); + ServiceRequest serviceRequest; + // 声明费用项 + ChargeItem chargeItem; + // 新增 + 修改 + // 🔧 BugFix: 如果 requestId 不为空说明是已存在的医嘱,需要更新,即使 dbOpType 不匹配也应该包含进来 + // 🔧 BugFix #454: 排除删除操作,避免误入insertOrUpdateList触发执行科室校验 + List insertOrUpdateList = activityList.stream() + .filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType())) + .filter(e -> (DbOpType.INSERT.getCode().equals(e.getDbOpType()) + || DbOpType.UPDATE.getCode().equals(e.getDbOpType()) + || e.getRequestId() != null)) + .collect(Collectors.toList()); + // 删除 + List deleteList = activityList.stream() + .filter(e -> DbOpType.DELETE.getCode().equals(e.getDbOpType())).collect(Collectors.toList()); + // 校验删除的医嘱是否已经收费 + List delRequestIdList = deleteList.stream().map(AdviceSaveDto::getRequestId).collect(Collectors.toList()); + if (!delRequestIdList.isEmpty()) { + List chargeItemList = iChargeItemService.getChargeItemInfoByReqId(delRequestIdList); + // 🔧 BugFix#219: 过滤只保留诊疗类型的费用项 + if (chargeItemList != null && !chargeItemList.isEmpty()) { + chargeItemList = chargeItemList.stream() + .filter(ci -> CommonConstants.TableName.WOR_SERVICE_REQUEST.equals(ci.getServiceTable())) + .collect(Collectors.toList()); + } + if (chargeItemList != null && !chargeItemList.isEmpty()) { + for (ChargeItem ci : chargeItemList) { + if (ChargeItemStatus.BILLED.getValue().equals(ci.getStatusEnum())) { + throw new ServiceException("已收费的项目无法删除,请刷新页面后重试"); + } + } + } + } + // 🔧 级联作废:在删除 ServiceRequest 之前,先读取所有待删除记录的级联信息 + // 检验申请单:contentJson 中写入 applyNo;手术申请单:categoryEnum=24 + prescriptionNo + Map> labApplyNoToRequestIds = new LinkedHashMap<>(); + Map> surgeryPrescriptionNoToRequestIds = new LinkedHashMap<>(); + // 收集待删除的 ServiceRequest(先查询再删除,避免级联逻辑因记录已删除而失效) + Map serviceRequestCache = new LinkedHashMap<>(); + for (AdviceSaveDto adviceSaveDto : deleteList) { + Long requestId = adviceSaveDto.getRequestId(); + // 🔧 Bug #442: 跳过 requestId 为 null 的记录 + if (requestId == null) { + log.warn("BugFix#442: handService - 跳过 requestId 为 null 的删除请求"); + continue; + } + ServiceRequest existing = iServiceRequestService.getById(requestId); + if (existing == null) { + continue; + } + serviceRequestCache.put(requestId, existing); + log.info("【调试】handService 待删除医嘱: requestId={}, categoryEnum={}, prescriptionNo={}", + requestId, existing.getCategoryEnum(), existing.getPrescriptionNo()); + // 检验申请单级联 + String applyNo = extractInspectionApplyNoFromContentJson(existing.getContentJson()); + if (StringUtils.isNotBlank(applyNo)) { + labApplyNoToRequestIds.computeIfAbsent(applyNo, k -> new ArrayList<>()) + .add(requestId); + } + // 手术申请单级联(categoryEnum=24) + log.info("【调试】handService 判断手术条件: categoryEnum={}, prescriptionNo={}, isSurgery={}", + existing.getCategoryEnum(), existing.getPrescriptionNo(), + existing.getCategoryEnum() != null && existing.getCategoryEnum() == 24 && StringUtils.isNotBlank(existing.getPrescriptionNo())); + if (existing.getCategoryEnum() != null + && existing.getCategoryEnum() == 24 + && StringUtils.isNotBlank(existing.getPrescriptionNo())) { + surgeryPrescriptionNoToRequestIds.computeIfAbsent(existing.getPrescriptionNo(), k -> new ArrayList<>()) + .add(requestId); + log.info("【调试】handService 加入手术级联列表: prescriptionNo={}", existing.getPrescriptionNo()); + } + } + // 执行检验申请单级联作废 + Set cascadeSkippedRequestIds = new HashSet<>(); + for (Map.Entry> e : labApplyNoToRequestIds.entrySet()) { + R delLab = iDoctorStationInspectionLabApplyService.deleteInspectionLabApply(e.getKey()); + if (delLab != null && R.isSuccess(delLab)) { + cascadeSkippedRequestIds.addAll(e.getValue()); + log.info("handService - 级联作废检验申请单 applyNo={},已跳过重复删除的医嘱 requestIds={}", + e.getKey(), e.getValue()); + } else { + String msg = delLab != null && StringUtils.isNotEmpty(delLab.getMsg()) ? delLab.getMsg() : "删除检验申请单失败"; + log.warn("handService - 级联作废检验申请单未成功 applyNo={} msg={},将回退为仅删除当前医嘱记录", + e.getKey(), msg); + } + } + // 🔧 手术申请单级联作废:删除手术医嘱时同步作废关联的手术申请单 + for (Map.Entry> e : surgeryPrescriptionNoToRequestIds.entrySet()) { + String prescriptionNo = e.getKey(); + try { + List requestForms = iRequestFormService.list( + new LambdaQueryWrapper() + .eq(RequestForm::getPrescriptionNo, prescriptionNo) + .in(RequestForm::getTypeCode, ActivityDefCategory.PROCEDURE.getCode().toString(), "SURGERY") + .and(w -> w.isNull(RequestForm::getDeleteFlag).or().eq(RequestForm::getDeleteFlag, "0"))); + log.info("【调试】handService 查询手术申请单: prescriptionNo={}, 查到{}条", prescriptionNo, requestForms != null ? requestForms.size() : 0); + if (requestForms != null && !requestForms.isEmpty()) { + for (RequestForm requestForm : requestForms) { + iRequestFormService.removeById(requestForm.getId()); + } + // 同步删除 cli_surgery 手术记录(prescriptionNo = surgeryNo) + Surgery surgery = iSurgeryService.getOne( + new LambdaQueryWrapper() + .eq(Surgery::getSurgeryNo, prescriptionNo) + .and(w -> w.isNull(Surgery::getDeleteFlag).or().eq(Surgery::getDeleteFlag, "0"))); + if (surgery != null) { + iSurgeryService.removeById(surgery.getId()); + log.info("handService - 级联删除手术记录 cli_surgery: surgeryNo={}, id={}", prescriptionNo, surgery.getId()); + } + cascadeSkippedRequestIds.addAll(e.getValue()); + log.info("handService - 级联作废手术申请单 prescriptionNo={}", prescriptionNo); + } else { + log.info("handService - 未找到手术申请单 prescriptionNo={}", prescriptionNo); + } + } catch (Exception ex) { + log.warn("handService - 级联作废手术申请单失败 prescriptionNo={} msg={}", prescriptionNo, ex.getMessage()); + } + } + // 级联作废完成后,统一删除 ServiceRequest 及其子项、费用项 + for (AdviceSaveDto adviceSaveDto : deleteList) { + if (cascadeSkippedRequestIds.contains(adviceSaveDto.getRequestId())) { + continue; + } + Long requestId = adviceSaveDto.getRequestId(); + iServiceRequestService.removeById(requestId);// 删除诊疗 + iServiceRequestService.remove( + new LambdaQueryWrapper().eq(ServiceRequest::getParentId, + requestId));// 删除诊疗套餐对应的子项 + // 🔧 Bug Fix #219: 删除费用项 + String serviceTable = CommonConstants.TableName.WOR_SERVICE_REQUEST; + iChargeItemService.deleteByServiceTableAndId(serviceTable, requestId); + log.info("BugFix#219: 诊疗医嘱删除完成, requestId={}, serviceTable={}", requestId, serviceTable); + } + + for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) { + // 🔧 Bug Fix: 确保accountId有效(不为null且账户存在) + boolean needNewAccount = false; + if (adviceSaveDto.getAccountId() == null) { + needNewAccount = true; + } else { + // 验证账户是否存在且有效(未被删除,租户匹配) + Account existingAccount = iAccountService.getById(adviceSaveDto.getAccountId()); + if (existingAccount == null) { + log.warn("handService - 前端传入的accountId无效(账户不存在),accountId={},将重新获取或创建账户", + adviceSaveDto.getAccountId()); + needNewAccount = true; + } + } + + if (needNewAccount) { + // 尝试从患者就诊中获取默认账户ID(自费账户) + Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId()); + if (selfAccount != null) { + adviceSaveDto.setAccountId(selfAccount.getId()); + log.info("handService - 使用现有自费账户,accountId={}", selfAccount.getId()); + } else { + // 自动创建自费账户 + Account newAccount = new Account(); + newAccount.setPatientId(adviceSaveDto.getPatientId()); + newAccount.setEncounterId(adviceSaveDto.getEncounterId()); + newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO); + newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode()); + newAccount.setBalanceAmount(BigDecimal.ZERO); + newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue()); + newAccount.setEncounterFlag(Whether.YES.getValue()); + newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo()); + Long newAccountId = iAccountService.saveAccountByRegister(newAccount); + adviceSaveDto.setAccountId(newAccountId); + log.info("handService - 自动创建自费账户,newAccountId={}", newAccountId); + } + } + + // 🔧 Bug Fix: 确保practitionerId不为null + if (adviceSaveDto.getPractitionerId() == null) { + adviceSaveDto.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId()); + log.info("handService - 自动补全practitionerId: practitionerId={}", adviceSaveDto.getPractitionerId()); + } + + // 🔧 Bug Fix: 确保founderOrgId不为null + if (adviceSaveDto.getFounderOrgId() == null) { + adviceSaveDto.setFounderOrgId(SecurityUtils.getLoginUser().getOrgId()); + log.info("handService - 自动补全founderOrgId: founderOrgId={}", adviceSaveDto.getFounderOrgId()); + } + + // 🔧 Bug Fix #238/#454: 诊疗项目执行科室非空校验(删除操作跳过校验) + if (adviceSaveDto.getAdviceType() != null && adviceSaveDto.getAdviceType() == 3 + && !DbOpType.DELETE.getCode().equals(adviceSaveDto.getDbOpType())) { + Long effectiveOrgId = adviceSaveDto.getEffectiveOrgId(); + if (effectiveOrgId == null) { + throw new ServiceException("诊疗项目必须选择执行科室"); + } + } + serviceRequest = new ServiceRequest(); + serviceRequest.setId(adviceSaveDto.getRequestId()); // 主键id + serviceRequest.setStatusEnum(is_save ? RequestStatus.DRAFT.getValue() : RequestStatus.ACTIVE.getValue());// 请求状态 + serviceRequest.setTenantId(tenantId); // 设置租户id + serviceRequest.setCreateBy(currentUsername); // 设置创建人 + serviceRequest.setCreateTime(curDate); // 设置创建时间 + serviceRequest.setTenantId(SecurityUtils.getLoginUser().getTenantId()); // 显式设置租户ID + if (is_sign) { + serviceRequest.setSignCode(signCode); + } + // 🔧 Bug Fix: 签发时也需要设置关键字段(修复BUG #181) + // 保存时生成业务编号,签发时沿用已有编号 + if (is_save) { + serviceRequest.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.SERVICE_RES_NO.getPrefix(), 4)); + } + serviceRequest.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum() != null + ? adviceSaveDto.getGenerateSourceEnum() + : GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源 + serviceRequest.setPrescriptionNo(adviceSaveDto.getSourceBillNo()); // 来源业务单据号(手术单号) + serviceRequest.setQuantity(adviceSaveDto.getQuantity()); // 请求数量 + serviceRequest.setUnitCode(adviceSaveDto.getUnitCode()); // 请求单位编码 + + // 🎯 判断是否为会诊医嘱:如果categoryEnum为31,则为会诊类型 + Integer categoryEnum = adviceSaveDto.getCategoryEnum(); + if (categoryEnum != null && categoryEnum == 31) { + // 会诊医嘱:category_enum设置为31 + serviceRequest.setCategoryEnum(31); + log.info("保存会诊医嘱,category_enum=31"); + } else { + // 普通诊疗医嘱 + serviceRequest.setCategoryEnum(adviceSaveDto.getCategoryEnum()); + } + + // 🔧 BugFix#385: 检查类型(adviceType=2)不走定价体系,activityId设置为0L占位 + // 与ExamApplyController保持一致,数据库有NOT NULL约束 + if (adviceSaveDto.getAdviceType() != null && adviceSaveDto.getAdviceType() == 2) { + serviceRequest.setActivityId(0L); + } else { + serviceRequest.setActivityId(adviceSaveDto.getAdviceDefinitionId());// 诊疗定义id + } + serviceRequest.setPatientId(adviceSaveDto.getPatientId()); // 患者 + serviceRequest.setRequesterId(adviceSaveDto.getPractitionerId()); // 开方医生 + serviceRequest.setEncounterId(adviceSaveDto.getEncounterId()); // 就诊id + serviceRequest.setAuthoredTime(curDate); // 请求签发时间 + // 执行科室 - 使用兼容方法获取执行科室ID + serviceRequest.setOrgId(adviceSaveDto.getEffectiveOrgId()); + serviceRequest.setContentJson(adviceSaveDto.getContentJson()); // 请求内容json + serviceRequest.setYbClassEnum(adviceSaveDto.getYbClassEnum());// 类别医保编码 + serviceRequest.setConditionId(adviceSaveDto.getConditionId()); // 诊断id + serviceRequest.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id + + // 基于皮试药品生成的皮试检查 + if (adviceSaveDto.getBasedOnId() != null) { + serviceRequest.setBasedOnId(adviceSaveDto.getBasedOnId()); + serviceRequest.setBasedOnTable(CommonConstants.TableName.MED_MEDICATION_REQUEST); + } + + iServiceRequestService.saveOrUpdate(serviceRequest); + + // 保存时保存诊疗费用项 + if (is_save) { + chargeItem = new ChargeItem(); + chargeItem.setId(adviceSaveDto.getChargeItemId()); // 费用项id + chargeItem.setTenantId(tenantId); // 补全租户ID + chargeItem.setCreateBy(currentUsername); // 补全创建人 + chargeItem.setCreateTime(curDate); // 补全创建时间 + chargeItem.setStatusEnum(2); // 已生成医嘱 + chargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(serviceRequest.getBusNo())); + chargeItem.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum() != null + ? adviceSaveDto.getGenerateSourceEnum() + : GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源 + chargeItem.setPatientId(adviceSaveDto.getPatientId()); // 患者 + chargeItem.setContextEnum(adviceSaveDto.getAdviceType()); // 类型 + chargeItem.setEncounterId(adviceSaveDto.getEncounterId()); // 就诊id + // 🔧 Bug Fix: 如果definitionId为空,使用adviceDefinitionId作为后备 + Long defId3 = adviceSaveDto.getDefinitionId(); + if (defId3 == null) { + defId3 = adviceSaveDto.getAdviceDefinitionId(); + } + chargeItem.setDefinitionId(defId3); // 费用定价ID + chargeItem.setDefDetailId(adviceSaveDto.getDefinitionDetailId()); // 定价子表主键 + chargeItem.setEntererId(adviceSaveDto.getPractitionerId());// 开立人ID + chargeItem.setEnteredDate(curDate); // 开立时间 + chargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);// 医疗服务类型 + chargeItem.setServiceId(serviceRequest.getId()); // 医疗服务ID + chargeItem.setProductTable(adviceSaveDto.getAdviceTableName());// 产品所在表 + chargeItem.setProductId(adviceSaveDto.getAdviceDefinitionId());// 收费项id + chargeItem.setAccountId(adviceSaveDto.getAccountId());// 关联账户ID + chargeItem.setRequestingOrgId(orgId); // 开立科室 + chargeItem.setConditionId(adviceSaveDto.getConditionId()); // 诊断id + chargeItem.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id + chargeItem.setQuantityValue(adviceSaveDto.getQuantity()); // 数量 + chargeItem.setQuantityUnit(adviceSaveDto.getUnitCode()); // 单位 + // #415 价格非负验证 + BigDecimal unitPrice = adviceSaveDto.getUnitPrice(); + if (unitPrice != null && unitPrice.compareTo(BigDecimal.ZERO) < 0) { + unitPrice = unitPrice.abs(); // 负数取绝对值 + } + chargeItem.setUnitPrice(unitPrice); // 单价 + chargeItem.setTotalPrice(adviceSaveDto.getTotalPrice()); // 总价 + + iChargeItemService.saveOrUpdate(chargeItem); + + // 显式更新前端传的chargeItemId对应的收费项目状态为2(已生成医嘱) + if (adviceSaveDto.getChargeItemId() != null) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(ChargeItem::getId, adviceSaveDto.getChargeItemId()) + .set(ChargeItem::getStatusEnum, 2); + iChargeItemService.update(updateWrapper); + log.info("已更新诊疗收费项目状态为已生成医嘱,chargeItemId:{}", adviceSaveDto.getChargeItemId()); + } + + // 第一次保存时,处理诊疗套餐的子项信息 + if (adviceSaveDto.getRequestId() == null) { + ActivityDefinition activityDefinition + = iActivityDefinitionService.getById(adviceSaveDto.getAdviceDefinitionId()); + if (activityDefinition == null) { + continue; + } + String childrenJson = activityDefinition.getChildrenJson(); + if (childrenJson != null) { + // 诊疗子项参数类 + ActivityChildrenJsonParams activityChildrenJsonParams = new ActivityChildrenJsonParams(); + activityChildrenJsonParams.setTherapyEnum(TherapyTimeType.TEMPORARY.getValue()); // 治疗类型 + activityChildrenJsonParams.setPatientId(serviceRequest.getPatientId()); // 患者 + activityChildrenJsonParams.setEncounterId(serviceRequest.getEncounterId()); // 就诊id + activityChildrenJsonParams.setAccountId(chargeItem.getAccountId()); // 账户id + activityChildrenJsonParams.setChargeItemId(chargeItem.getId()); // 费用项id + activityChildrenJsonParams.setParentId(serviceRequest.getId());// 子项诊疗的父id + activityChildrenJsonParams.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); + adviceUtils.handleActivityChild(childrenJson, organizationId, activityChildrenJsonParams); + } + } + } + + // 只有在签发时 + if (is_sign) { + // 发送跨系统申请 - 已注释,项目未使用LIS/PACS系统 + // adviceSaveDto.setRequestId(serviceRequest.getId()); + // try { + // // 查询诊疗定义 + // ActivityDefinition activityDefinition + // = iActivityDefinitionService.getById(adviceSaveDto.getAdviceDefinitionId()); + // if (activityDefinition != null) { + // // 检验 或 检查 + // if (ActivityType.PROOF.getValue().equals(activityDefinition.getTypeEnum()) + // || ActivityType.TEST.getValue().equals(activityDefinition.getTypeEnum())) { + // doctorStationSendApplyUtil.sendCrossSystemApply(adviceSaveDto, organizationId, curDate); + // } + // } + // } catch (Exception e) { + // if (!Whether.YES.getCode() + // .equals(TenantOptionUtil.getOptionContent(TenantOptionDict.LIS_PACS_ERROR_IGNORE))) { + // throw e; + // } + // log.error(e.getMessage(), e); + // } + // 🔧 BugFix#328: 签发时将收费项目状态从草稿改为待收费 + // 修复检验申请单生成的医嘱签发失败问题 + Long chargeItemId = adviceSaveDto.getChargeItemId(); + ChargeItem existingChargeItem = null; + + // 方式1:通过chargeItemId直接查询 + if (chargeItemId != null) { + existingChargeItem = iChargeItemService.getById(chargeItemId); + } + + // 方式2:如果chargeItemId为null,通过requestId(serviceId)查询费用项 + // 检验申请单创建的医嘱可能没有传递chargeItemId,需要通过serviceId查找 + if (existingChargeItem == null && adviceSaveDto.getRequestId() != null) { + existingChargeItem = iChargeItemService.getOne( + new LambdaQueryWrapper() + .eq(ChargeItem::getServiceId, adviceSaveDto.getRequestId()) + .eq(ChargeItem::getServiceTable, CommonConstants.TableName.WOR_SERVICE_REQUEST) + .eq(ChargeItem::getDeleteFlag, DelFlag.NO.getCode()) + ); + log.info("BugFix#328: 通过requestId查询费用项,requestId={}, chargeItem={}", + adviceSaveDto.getRequestId(), existingChargeItem != null ? existingChargeItem.getId() : "null"); + } + + // 更新费用项状态 + if (existingChargeItem != null) { + existingChargeItem.setStatusEnum(ChargeItemStatus.PLANNED.getValue()); + iChargeItemService.updateById(existingChargeItem); + log.info("BugFix#328: 更新费用项状态为待收费,chargeItemId={}, status={}", + existingChargeItem.getId(), ChargeItemStatus.PLANNED.getValue()); + } else { + log.warn("BugFix#328: 未找到对应的费用项,无法更新状态,requestId={}, chargeItemId={}", + adviceSaveDto.getRequestId(), chargeItemId); + } + } + } + } + + /** + * 查询医嘱请求数据 + * + * @param encounterId 就诊id + * @return 医嘱请求数据 + */ + @Override + public R getRequestBaseInfo(Long encounterId) { + return this.getRequestBaseInfo(encounterId, null, null); + } + + @Override + public R getRequestBaseInfo(Long encounterId, Integer generateSourceEnum, String sourceBillNo) { + // 当前账号的参与者id + Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId(); + // 未指定generateSourceEnum时,默认只查询医生开立的医嘱 + int sourceEnum = (generateSourceEnum != null) ? generateSourceEnum : GenerateSource.DOCTOR_PRESCRIPTION.getValue(); + // 医嘱请求数据 + List requestBaseInfo = doctorStationAdviceAppMapper.getRequestBaseInfo(encounterId, null, + CommonConstants.TableName.MED_MEDICATION_REQUEST, CommonConstants.TableName.WOR_DEVICE_REQUEST, + CommonConstants.TableName.WOR_SERVICE_REQUEST, practitionerId, Whether.NO.getCode(), + sourceEnum, sourceBillNo); + for (RequestBaseDto requestBaseDto : requestBaseInfo) { + // 请求状态 + requestBaseDto + .setStatusEnum_enumText(EnumUtils.getInfoByValue(RequestStatus.class, requestBaseDto.getStatusEnum())); + // 是否皮试 + requestBaseDto + .setSkinTestFlag_enumText(EnumUtils.getInfoByValue(Whether.class, requestBaseDto.getSkinTestFlag())); + // 是否为注射药物 + requestBaseDto + .setInjectFlag_enumText(EnumUtils.getInfoByValue(Whether.class, requestBaseDto.getInjectFlag())); + // 收费状态 + requestBaseDto.setChargeStatus_enumText( + EnumUtils.getInfoByValue(ChargeItemStatus.class, requestBaseDto.getChargeStatus())); + // 单位字典翻译失败时回退使用原始值(如手术申请硬编码了中文单位名) + if (StringUtils.isNotBlank(requestBaseDto.getUnitCode()) && StringUtils.isBlank(requestBaseDto.getUnitCode_dictText())) { + requestBaseDto.setUnitCode_dictText(requestBaseDto.getUnitCode()); + } + } + return R.ok(requestBaseInfo); + } + + /** + * 门诊签退医嘱 + * + * @param requestIdList 请求id列表 + * @return 结果 + */ + @Override + public R signOffAdvice(List requestIdList) { + log.info("BugFix#219: signOffAdvice - requestIdList={}", requestIdList); + + // 🔧 BugFix: 直接对所有requestId进行作废操作,不再先查询分类 + // 药品、耗材、诊疗请求都尝试作废,只有存在的才会被更新 + + // 根据请求编号列表查询收费项目信息(用于检查是否已收费) + List chargeItemList = iChargeItemService.getChargeItemInfoByReqId(requestIdList); + + if (chargeItemList != null && !chargeItemList.isEmpty()) { + for (ChargeItem chargeItem : chargeItemList) { + if (ChargeItemStatus.BILLED.getValue().equals(chargeItem.getStatusEnum())) { + throw new ServiceException("已收费的项目无法签退,请刷新页面后重试"); + } + } + + List chargeItemIdList = chargeItemList.stream().map(ChargeItem::getId).collect(Collectors.toList()); + // 根据id更新收费项目状态 + iChargeItemService.updatePaymentStatus(chargeItemIdList, ChargeItemStatus.DRAFT.getValue()); + } + + // 🔧 新增:签退时回滚库存 + // 查询已发放的药品记录(用于回滚库存) + List dispensedList = iMedicationDispenseService.list( + new LambdaQueryWrapper() + .in(MedicationDispense::getMedReqId, requestIdList) + .eq(MedicationDispense::getStatusEnum, DispenseStatus.COMPLETED.getValue()) + ); + + if (dispensedList != null && !dispensedList.isEmpty()) { + // 需要回滚的库存列表 + List inventoryUpdateList = new ArrayList<>(); + + for (MedicationDispense dispense : dispensedList) { + // 查询对应的库存记录(根据批号和药品ID) + if (dispense.getMedicationId() != null && dispense.getLotNumber() != null) { + InventoryItem inventoryItem = inventoryItemService.getOne( + new LambdaQueryWrapper() + .eq(InventoryItem::getItemId, dispense.getMedicationId()) + .eq(InventoryItem::getLotNumber, dispense.getLotNumber()) + ); + + if (inventoryItem != null) { + // 计算回滚后的数量(加上已发放的数量) + BigDecimal currentQuantity = inventoryItem.getQuantity() != null ? inventoryItem.getQuantity() : BigDecimal.ZERO; + BigDecimal dispenseQuantity = dispense.getQuantity() != null ? dispense.getQuantity() : BigDecimal.ZERO; + inventoryUpdateList.add(new InventoryItem() + .setId(inventoryItem.getId()) + .setQuantity(currentQuantity.add(dispenseQuantity)) + ); + } + } + + // 更新发药记录状态为已退药 + dispense.setStatusEnum(DispenseStatus.RETURNED.getValue()); + } + + // 批量更新库存(回滚数量) + if (!inventoryUpdateList.isEmpty()) { + inventoryItemService.updateBatchById(inventoryUpdateList); + } + + // 更新发药记录状态 + iMedicationDispenseService.updateBatchById(dispensedList); + } + + // 🔧 BugFix: 直接对所有requestId进行签退操作,将状态改为待签发 + log.info("BugFix: signOffAdvice - 签退所有请求,状态改为待签发, requestIdList={}", requestIdList); + + // 尝试签退药品请求(只有存在的才会更新) + iMedicationRequestService.updateDraftStatusBatch(requestIdList, null, null); + // 尝试签退耗材请求(只有存在的才会更新) + iDeviceRequestService.updateDraftStatusBatch(requestIdList); + // 尝试签退诊疗请求(只有存在的才会更新) + iServiceRequestService.updateDraftStatusBatch(requestIdList); + + log.info("BugFix#219: signOffAdvice - 所有请求作废完成"); + + return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null)); + } + + /** + * 查询历史医嘱请求数据 + * + * @param patientId 病人id + * @param encounterId 就诊id + * @return 历史医嘱请求数据 + */ + @Override + public R getRequestHistoryInfo(Long patientId, Long encounterId) { + // 当前账号的参与者id + Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId(); + // 医嘱请求数据 + List requestBaseInfo = doctorStationAdviceAppMapper.getRequestBaseInfo(encounterId, patientId, + CommonConstants.TableName.MED_MEDICATION_REQUEST, CommonConstants.TableName.WOR_DEVICE_REQUEST, + CommonConstants.TableName.WOR_SERVICE_REQUEST, practitionerId, Whether.YES.getCode(), + GenerateSource.DOCTOR_PRESCRIPTION.getValue(), null); + for (RequestBaseDto requestBaseDto : requestBaseInfo) { + // 请求状态 + requestBaseDto + .setStatusEnum_enumText(EnumUtils.getInfoByValue(RequestStatus.class, requestBaseDto.getStatusEnum())); + // 是否皮试 + requestBaseDto + .setSkinTestFlag_enumText(EnumUtils.getInfoByValue(Whether.class, requestBaseDto.getSkinTestFlag())); + // 是否为注射药物 + requestBaseDto + .setInjectFlag_enumText(EnumUtils.getInfoByValue(Whether.class, requestBaseDto.getInjectFlag())); + // 收费状态 + requestBaseDto.setChargeStatus_enumText( + EnumUtils.getInfoByValue(ChargeItemStatus.class, requestBaseDto.getChargeStatus())); + } + return R.ok(requestBaseInfo); + } + + /** + * 更新组号 + * + * @param updateGroupIdParam 更新组号参数 + * @return 结果 + */ + @Override + public void updateGroupId(UpdateGroupIdParam updateGroupIdParam) { + List groupList = updateGroupIdParam.getGroupList(); + List idsToSetNull = groupList.stream().filter(dto -> dto.getGroupId() == null) + .map(UpdateGroupDto::getRequestId).collect(Collectors.toList()); + + if (!idsToSetNull.isEmpty()) { + // 创建更新条件 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.set("group_id", null).in("id", idsToSetNull); + + // 执行更新 + iMedicationRequestService.update(updateWrapper); + } + + // 处理非null的情况 + List medicationRequestList = groupList.stream().filter(dto -> dto.getGroupId() != null) + .map(dto -> new MedicationRequest().setId(dto.getRequestId()).setGroupId(dto.getGroupId())) + .collect(Collectors.toList()); + + if (!medicationRequestList.isEmpty()) { + iMedicationRequestService.saveOrUpdateBatch(medicationRequestList); + } + } + + /** + * 查询就诊费用性质 + * + * @param encounterId 就诊id + * @return 就诊费用性质 + */ + @Override + public R getEncounterContract(Long encounterId) { + return R.ok(doctorStationAdviceAppMapper.getEncounterContract(encounterId)); + } + + /** + * 查询检验检查开立历史(近30天) + * + * @param patientId 患者id + * @param adviceDefinitionId 医嘱定义id + * @return 检验检查开立历史 + */ + @Override + public R getProofAndTestHistory(Long patientId, Long adviceDefinitionId) { + return R.ok(doctorStationAdviceAppMapper.getProofAndTestHistory(patientId, adviceDefinitionId, + RequestStatus.COMPLETED.getValue())); + } + + /** + * 查询检验url相关参数 + * + * @param encounterId 就诊id + * @return 检验url相关参数 + */ + @Override + public R getProofResult(Long encounterId) { + // 检查参数 + if (encounterId == null) { + log.warn("获取检验结果时就诊ID为空"); + return R.ok(new ArrayList<>()); + } + + // LIS查看报告地址 + String lisReportUrl = TenantOptionUtil.getOptionContent(TenantOptionDict.LIS_REPORT_URL); + if (StringUtils.isEmpty(lisReportUrl)) { + log.warn("租户配置项【LIS查看报告地址】未配置"); + } + List proofResult = doctorStationAdviceAppMapper.getProofAndTestResult(encounterId, + RequestStatus.DRAFT.getValue(), ActivityType.PROOF.getValue()); + for (ProofAndTestResultDto proofAndTestResultDto : proofResult) { + if (StringUtils.isNotEmpty(lisReportUrl)) { + proofAndTestResultDto.setRequestUrl(lisReportUrl.concat(proofAndTestResultDto.getBusNo())); + } + } + + return R.ok(proofResult); + } + + /** + * 查询检查url相关参数 + * + * @param encounterId 就诊id + * @return 检查url相关参数 + */ + @Override + public R getTestResult(Long encounterId) { + // 检查参数 + if (encounterId == null) { + log.warn("获取检查结果时就诊ID为空"); + return R.ok(new ArrayList<>()); + } + + // PACS查看报告地址 + String pacsReportUrl = TenantOptionUtil.getOptionContent(TenantOptionDict.PACS_REPORT_URL); + if (StringUtils.isEmpty(pacsReportUrl)) { + log.warn("租户配置项【PACS查看报告地址】未配置"); + } + List testResult = doctorStationAdviceAppMapper.getProofAndTestResult(encounterId, + RequestStatus.DRAFT.getValue(), ActivityType.TEST.getValue()); + for (ProofAndTestResultDto proofAndTestResultDto : testResult) { + if (StringUtils.isNotEmpty(pacsReportUrl)) { + proofAndTestResultDto.setRequestUrl(pacsReportUrl.concat(proofAndTestResultDto.getBusNo())); + } + } + return R.ok(testResult); + } + + /** + * 根据searchKey对医嘱列表进行排序:adviceName以searchKey(汉字)开头的排在前面 | + * pyStr以searchKey(字母)开头的排在前面 + * + * @param adviceList 医嘱列表 + * @param searchKey 搜索关键字 + */ + private void sortAdviceListBySearchKey(List adviceList, String searchKey) { + if (adviceList == null || adviceList.isEmpty() || searchKey == null || searchKey.trim().isEmpty()) { + return; + } + + // 判断searchKey是否包含字母(拼音) + boolean isPinyinSearch = isPinyinKey(searchKey); + + adviceList.sort((a, b) -> { + // 根据searchKey类型选择不同的字段 + String aValue + = isPinyinSearch ? (a.getPyStr() != null ? a.getPyStr() : a.getAdviceName()) : a.getAdviceName(); + String bValue + = isPinyinSearch ? (b.getPyStr() != null ? b.getPyStr() : b.getAdviceName()) : b.getAdviceName(); + + // 处理可能的null值 + if (aValue == null && bValue == null) { + return 0; + } + if (aValue == null) { + return 1; + } + if (bValue == null) { + return -1; + } + + // 判断两个值是否以searchKey开头 + boolean aStartsWith = aValue.toLowerCase().startsWith(searchKey.toLowerCase()); + boolean bStartsWith = bValue.toLowerCase().startsWith(searchKey.toLowerCase()); + + // 如果a以searchKey开头,而b不是,a排在前面 + if (aStartsWith && !bStartsWith) { + return -1; + } + // 如果b以searchKey开头,而a不是,b排在前面 + if (bStartsWith && !aStartsWith) { + return 1; + } + // 如果两者都以searchKey开头或都不以searchKey开头,保持原有顺序 + return 0; + }); + } + + /** + * 判断searchKey是否为拼音(是否只包含字母) + */ + private boolean isPinyinKey(String searchKey) { + if (searchKey == null || searchKey.trim().isEmpty()) { + return false; + } + // 判断字符串是否只包含字母(拼音通常只包含字母) + return searchKey.matches("[a-zA-Z]+"); + } + + /** + * 获取当前科室已配置的药品类别列表 + * + * @param organizationId 科室id + * @return 已配置的药品类别编码列表 + */ + @Override + public R getConfiguredCategories(Long organizationId) { + // 查询取药科室配置 + List medLocationConfig = doctorStationAdviceAppMapper.getMedLocationConfig(organizationId); + // 提取不重复的 categoryCode + List categoryCodes = medLocationConfig.stream() + .map(AdviceInventoryDto::getCategoryCode) + .filter(code -> code != null && !code.isEmpty()) + .distinct() + .collect(Collectors.toList()); + return R.ok(categoryCodes); + } + + /** + * 手术项目专用分页查询(仅手术 + 定价,无库存/草稿库存/取药科室等无关逻辑) + * 使用直接 LIMIT 查询替代 MyBatis Plus 分页,避免 COUNT 全表扫描开销 + */ + @Override + public IPage getSurgeryPage(Long organizationId, Integer pageNo, Integer pageSize, String searchKey) { + log.info("getSurgeryPage 开始: orgId={}, page={}/{}, searchKey={}", organizationId, pageNo, pageSize, searchKey); + long start = System.currentTimeMillis(); + + // 无搜索时尝试从 Redis 缓存读取(手术项目变更频率低,适合缓存) + String safeOrgId = organizationId != null ? organizationId.toString() : ""; + String cacheKey = "surgery:page:" + safeOrgId + ":" + pageNo + ":" + pageSize; + boolean useCache = (searchKey == null || searchKey.trim().isEmpty()); + + if (useCache) { + Object cachedObj = redisCache.getCacheObject(cacheKey); + if (cachedObj instanceof com.baomidou.mybatisplus.extension.plugins.pagination.Page) { + log.info("从 Redis 缓存获取手术项目, key: {}, records: {}", cacheKey, + ((IPage) cachedObj).getRecords().size()); + return (IPage) cachedObj; + } + } + + // 使用 MyBatis Plus 分页查询 + IPage result = doctorStationAdviceAppMapper.getSurgeryPage( + new Page<>(pageNo, pageSize), + PublicationStatus.ACTIVE.getValue(), + organizationId, + searchKey); + + log.info("getSurgeryPage 完成: {}ms, total={}, records={}", System.currentTimeMillis() - start, result.getTotal(), result.getRecords().size()); + + // 无搜索时将结果写入缓存 + if (useCache && result instanceof com.baomidou.mybatisplus.extension.plugins.pagination.Page) { + redisCache.setCacheObject(cacheKey, result, (int) CACHE_EXPIRE_HOURS, java.util.concurrent.TimeUnit.HOURS); + log.info("缓存手术项目, key: {}, 过期时间: {} 小时", cacheKey, CACHE_EXPIRE_HOURS); + } + + return result; + } + + @Override + public IPage getExaminationPage(Long organizationId, Integer pageNo, Integer pageSize, String searchKey, String categoryCode) { + IPage result = doctorStationAdviceAppMapper.getExaminationPage( + new Page<>(pageNo, pageSize), + PublicationStatus.ACTIVE.getValue(), + organizationId, + searchKey, + categoryCode); + return result; + } + } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/AdviceSaveParam.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/AdviceSaveParam.java index 9535790fc..5421d0ef9 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/AdviceSaveParam.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/AdviceSaveParam.java @@ -1,44 +1,38 @@ package com.openhis.web.doctorstation.dto; -import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.openhis.common.enums.Whether; import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; +import lombok.experimental.Accessors; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; import java.util.List; /** - * 医嘱/检验申请保存参数 + * 医嘱保存参数类 */ @Data +@Accessors(chain = true) public class AdviceSaveParam { - /** 患者就诊ID */ - @NotNull(message = "就诊ID不能为空") - private Long encounterId; + /** + * 患者挂号对应的科室id + */ + @JsonSerialize(using = ToStringSerializer.class) + private Long organizationId; - /** 申请类型:1-普通 2-急诊 */ - private Integer applicationType; + /** + * 代煎标识 | 0:否 , 1:是 + */ + private Integer sufferingFlag; - /** 标本类型 */ - private String specimenType; + /** + * 保存医嘱 dto + */ + private List adviceSaveList; - /** 执行时间 */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime executionTime; + public AdviceSaveParam() { + this.sufferingFlag = Whether.NO.getValue(); + } - /** 发往科室编码 */ - private String targetDeptCode; - - /** 临床诊断 */ - private String diagnosis; - - /** 关联的检验/检查项目ID集合 */ - private List itemIds; - - /** 医嘱操作类型:1-保存草稿 2-签发 */ - private String adviceOpType; } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/MedicalRecordListDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/MedicalRecordListDTO.java deleted file mode 100644 index 827422644..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/MedicalRecordListDTO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.doctorstation.dto; -public class MedicalRecordListDTO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/MedicalRecordQueryParam.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/MedicalRecordQueryParam.java deleted file mode 100644 index 5516678dc..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/MedicalRecordQueryParam.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.doctorstation.dto; -public class MedicalRecordQueryParam {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/MedicalRecordMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/MedicalRecordMapper.java deleted file mode 100644 index 58ffb8f30..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/MedicalRecordMapper.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.openhis.web.doctorstation.mapper; - -import com.openhis.web.doctorstation.dto.MedicalRecordListDTO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; -import java.util.List; - -/** - * 门诊病历相关数据库操作 Mapper - */ -@Mapper -public interface MedicalRecordMapper { - - /** - * Bug #562 Fix: 优化待写病历查询性能 - * 根因:原查询使用 SELECT * 且未分页,关联大字段表导致全表扫描与网络传输阻塞,响应>2s - * 修复: - * 1. 仅查询列表展示所需轻量字段,剔除病历正文等大字段 - * 2. 强制分页 LIMIT/OFFSET,限制单次返回数据量 - * 3. 使用 INNER JOIN 替代 LEFT JOIN,确保执行计划走 encounter.doctor_id 索引 - * 4. 增加时间范围过滤,缩小扫描区间 - */ - @Select("") - List selectPendingRecords(@Param("doctorId") Long doctorId, - @Param("startDate") String startDate, - @Param("endDate") String endDate, - @Param("pageSize") Integer pageSize, - @Param("offset") Integer offset); - - @Select("") - Long countPendingRecords(@Param("doctorId") Long doctorId, - @Param("startDate") String startDate, - @Param("endDate") String endDate); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/service/MedicalRecordService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/service/MedicalRecordService.java deleted file mode 100644 index d8644803e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/service/MedicalRecordService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.doctorstation.service; - -public interface MedicalRecordService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/service/MedicalRecordServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/service/MedicalRecordServiceImpl.java deleted file mode 100644 index deeaa0af2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/service/MedicalRecordServiceImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.web.doctorstation.service; - -import com.openhis.web.doctorstation.dto.MedicalRecordQueryParam; -import com.openhis.web.doctorstation.dto.MedicalRecordListDTO; -import com.openhis.web.doctorstation.mapper.MedicalRecordMapper; -import org.springframework.stereotype.Service; -import java.time.LocalDate; -import java.util.List; -import java.util.Map; - -/** - * 门诊病历服务实现 - */ -@Service -public class MedicalRecordServiceImpl implements MedicalRecordService { - - private final MedicalRecordMapper medicalRecordMapper; - - public MedicalRecordServiceImpl(MedicalRecordMapper medicalRecordMapper) { - this.medicalRecordMapper = medicalRecordMapper; - } - - @Override - public Map getPendingMedicalRecords(MedicalRecordQueryParam param) { - // Bug #562 Fix: 强制分页与默认时间范围,避免全量加载导致超时 - int pageSize = param.getPageSize() != null && param.getPageSize() > 0 ? param.getPageSize() : 20; - int pageNum = param.getPageNum() != null && param.getPageNum() > 0 ? param.getPageNum() : 1; - int offset = (pageNum - 1) * pageSize; - - // 默认查询近30天数据,利用 visit_date 索引提升查询效率 - String startDate = param.getStartDate() != null ? param.getStartDate() : LocalDate.now().minusDays(30).toString(); - String endDate = param.getEndDate() != null ? param.getEndDate() : LocalDate.now().toString(); - - List list = medicalRecordMapper.selectPendingRecords( - param.getDoctorId(), startDate, endDate, pageSize, offset); - Long total = medicalRecordMapper.countPendingRecords(param.getDoctorId(), startDate, endDate); - - return Map.of("list", list, "total", total, "pageNum", pageNum, "pageSize", pageSize); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/InspectionApplyController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/InspectionApplyController.java deleted file mode 100644 index d667ff613..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/InspectionApplyController.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.openhis.web.inpatient.controller; - -import com.openhis.web.inpatient.service.InspectionApplyService; -import org.springframework.web.bind.annotation.*; -import java.util.Map; - -/** - * 住院医生工作站-检验申请接口 - */ -@RestController -@RequestMapping("/api/inpatient/inspection") -public class InspectionApplyController { - - private final InspectionApplyService inspectionApplyService; - - public InspectionApplyController(InspectionApplyService inspectionApplyService) { - this.inspectionApplyService = inspectionApplyService; - } - - /** - * 获取检验申请单详情(用于编辑回显) - * 修复 Bug #576:返回结构已包含 items 明细数组,前端可直接绑定至右侧已选择列表 - */ - @GetMapping("/{id}") - public Map getDetail(@PathVariable Long id) { - return inspectionApplyService.getDetailForEdit(id); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/LabRequestController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/LabRequestController.java deleted file mode 100644 index 16050d6fd..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/LabRequestController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.openhis.web.inpatient.controller; - -import com.openhis.web.inpatient.dto.LabRequestListDTO; -import com.openhis.web.inpatient.service.LabRequestService; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -/** - * 住院检验申请控制层 - * 新增撤回接口(Bug #571) - */ -@RestController -@RequestMapping("/inpatient/lab-request") -public class LabRequestController { - - private final LabRequestService labRequestService; - - public LabRequestController(LabRequestService labRequestService) { - this.labRequestService = labRequestService; - } - - @GetMapping("/list") - public List list(@RequestParam Long doctorId) { - return labRequestService.getLabRequestList(doctorId); - } - - /** - * 撤回检验申请 - * - * @param requestId 检验申请 ID - * @return 是否成功 - */ - @PostMapping("/revoke/{requestId}") - public boolean revoke(@PathVariable Long requestId) { - return labRequestService.revokeLabRequest(requestId); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/OrderVerificationController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/OrderVerificationController.java deleted file mode 100644 index 5bd7fcb2f..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/OrderVerificationController.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.openhis.web.inpatient.controller; - -import com.openhis.web.inpatient.service.OrderVerificationService; -import org.springframework.web.bind.annotation.*; - -import java.util.Map; - -/** - * 医嘱校对控制层 - * - * 新增:撤回检验申请接口,前端调用时会返回统一错误信息(Bug #571)。 - */ -@RestController -@RequestMapping("/api/inpatient/orderVerification") -public class OrderVerificationController { - - private final OrderVerificationService verificationService; - - public OrderVerificationController(OrderVerificationService verificationService) { - this.verificationService = verificationService; - } - - @PostMapping("/return") - public Map returnOrder(@RequestParam Long orderId) { - verificationService.returnOrder(orderId); - return Map.of("success", true); - } - - /** - * 撤回检验申请 - * - * @param orderId 检验医嘱ID - */ - @PostMapping("/withdraw") - public Map withdrawOrder(@RequestParam Long orderId) { - verificationService.withdrawOrder(orderId); - return Map.of("success", true); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/VitalSignController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/VitalSignController.java deleted file mode 100644 index 590be8bf5..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/controller/VitalSignController.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.openhis.web.inpatient.controller; - -import com.openhis.web.inpatient.service.VitalSignService; -import com.openhis.web.inpatient.vo.VitalSignVO; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; - -/** - * 住院体征(体温单)接口 - * - * 修复 Bug #566:体征数据已录入成功,但在“体温单”图表区中未渲染显示数据点。 - * 该接口负责根据住院登记单号查询对应的体征记录,前端体温图表通过此接口获取数据。 - */ -@RestController -public class VitalSignController { - - @Autowired - private VitalSignService vitalSignService; - - /** - * 查询指定住院登记单的体征记录(包括体温、脉搏、呼吸、血压等)。 - * - * @param registrationId 住院登记单主键 ID - * @return 体征记录列表,按记录时间升序返回 - */ - @GetMapping("/api/inpatient/vital-signs") - public List listVitalSigns(@RequestParam("registrationId") Long registrationId) { - return vitalSignService.getVitalSignsByRegistrationId(registrationId); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/domain/Order.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/domain/Order.java deleted file mode 100644 index 97cda35f5..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/domain/Order.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.domain; -public class Order {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/InspectionApplyDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/InspectionApplyDTO.java deleted file mode 100644 index db53e8bde..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/InspectionApplyDTO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.dto; -public class InspectionApplyDTO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/LabRequestDetailDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/LabRequestDetailDTO.java deleted file mode 100644 index 8cf299fe4..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/LabRequestDetailDTO.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.openhis.web.inpatient.dto; - -import lombok.Data; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.List; - -/** - * 检验申请单详情 DTO - * Bug #576 Fix: 增加 items 集合用于承载关联的检验项目明细,支撑编辑弹窗右侧列表回显 - */ -@Data -public class LabRequestDetailDTO { - private Long id; - private String requestNo; - private String patientId; - private String patientName; - private String symptoms; - private String signs; - private String relatedResults; - private String status; - private LocalDateTime createTime; - private List items; - - @Data - public static class LabRequestItemDTO { - private Long itemId; - private String itemName; - private BigDecimal price; - private String unit; - private Integer sortOrder; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/LabRequestListDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/LabRequestListDTO.java deleted file mode 100644 index b6fa5e335..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/LabRequestListDTO.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.openhis.web.inpatient.dto; - -import lombok.Data; -import java.time.LocalDateTime; - -/** - * 住院检验申请列表展示 DTO - * Bug #467 Fix: 增加申请单号、展示名称、完整名称字段,支撑前端列表规范展示 - */ -@Data -public class LabRequestListDTO { - private Long id; - /** 申请单号 (JYZyyMMddXXXXX) */ - private String requestNo; - /** 列表展示名称 (超长时截断为 项目1+项目2 等n项) */ - private String requestName; - /** 完整名称 (用于鼠标悬停 Tooltip 展示) */ - private String fullRequestName; - private String patientName; - private LocalDateTime createTime; - private String status; -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/OrderVerificationDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/OrderVerificationDTO.java deleted file mode 100644 index 1f129650f..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/dto/OrderVerificationDTO.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.openhis.web.inpatient.dto; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * 医嘱校对列表返回的 DTO - * - * 关键修复: - * 1. 之前返回的“使用单位”字段是字典表的数值 ID(如 6、16),前端直接展示导致中文显示异常。 - * 2. 新增 `unitName` 字段用于返回字典中文名称,并在 JSON 序列化时保持向后兼容。 - * - 前端仍可通过 `unit`(旧字段)获取数值 ID,若不需要可忽略。 - * - 新增 `unitName` 后,前端页面只需要展示 `unitName` 即可得到正确的中文单位。 - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -public class OrderVerificationDTO { - - private Long id; - private String itemName; - private Double price; - - /** 原始的单位 ID(字典表主键),保留兼容老接口 */ - @JsonProperty("unit") - private Integer unitId; - - /** 新增:单位的中文名称,前端展示使用 */ - @JsonProperty("unitName") - private String unitName; - - // 其它已有字段省略 ... - - // ------------------- Getter / Setter ------------------- - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getItemName() { - return itemName; - } - - public void setItemName(String itemName) { - this.itemName = itemName; - } - - public Double getPrice() { - return price; - } - - public void setPrice(Double price) { - this.price = price; - } - - /** 兼容旧字段的 getter / setter */ - public Integer getUnitId() { - return unitId; - } - - public void setUnitId(Integer unitId) { - this.unitId = unitId; - } - - /** 新增字段的 getter / setter */ - public String getUnitName() { - return unitName; - } - - public void setUnitName(String unitName) { - this.unitName = unitName; - } - - // 其它 getter / setter 省略 ... -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/InpatientOrder.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/InpatientOrder.java deleted file mode 100644 index a04894069..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/InpatientOrder.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.entity; -public class InpatientOrder {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/InspectionApply.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/InspectionApply.java deleted file mode 100644 index 4184ae40e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/InspectionApply.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.entity; -public class InspectionApply {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/InspectionApplyItem.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/InspectionApplyItem.java deleted file mode 100644 index 623a11399..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/InspectionApplyItem.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.entity; -public class InspectionApplyItem {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/LabRequest.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/LabRequest.java deleted file mode 100644 index a7db04d2a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/LabRequest.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.entity; -public class LabRequest {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/SurgeryRequest.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/SurgeryRequest.java deleted file mode 100644 index 74141aafb..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/entity/SurgeryRequest.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.entity; -public class SurgeryRequest {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispenseMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispenseMapper.java deleted file mode 100644 index b06c1b395..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispenseMapper.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import org.apache.ibatis.annotations.*; -import java.util.List; -import java.util.Map; - -/** - * 住院发药相关数据访问层 - * - * 修复 Bug #503: - * 在“需申请模式”下,发药明细与汇总单的数据触发时机不一致,导致明细提前出现。 - * 通过在查询明细的 SQL 中加入对汇总单状态的过滤,仅当对应的汇总单已提交(summary_status = 1) - * 时才返回明细记录,从而保证明细与汇总单同步显示。 - */ -@Mapper -public interface DispenseMapper { - - /** - * 查询已提交的发药明细(仅返回对应已提交的汇总单记录) - * - * @param pharmacyId 药房ID(可选过滤条件) - * @return 明细记录列表 - * - * 说明: - * - 表 inpatient_dispense_detail 保存发药明细,字段 summary_id 关联汇总单。 - * - 表 inpatient_dispense_summary 保存汇总单,字段 status 表示是否已提交(0: 未提交, 1: 已提交)。 - * - 只返回 summary.status = 1 的明细,避免未提交前提前展示。 - */ - @Select("") - List> listSubmittedDetails(@Param("pharmacyId") Long pharmacyId); - - /** - * 查询已提交的发药汇总单 - * - * @param pharmacyId 药房ID(可选过滤条件) - * @return 汇总单列表 - */ - @Select("") - List> listSubmittedSummaries(@Param("pharmacyId") Long pharmacyId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispensingDetailMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispensingDetailMapper.java deleted file mode 100644 index 047c3a5d3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispensingDetailMapper.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import org.apache.ibatis.annotations.*; - -import java.util.Map; - -/** - * 住院发药明细 Mapper - * - * 新增: - * 1. insertDetail – 插入单条发药明细 - * 2. countByOrderIdForUpdate – 统计指定医嘱的明细数量并加行级锁,确保后续汇总在同一事务内读取到最新数据 - */ -@Mapper -public interface DispensingDetailMapper { - - /** - * 插入发药明细记录 - * - * @param detail 包含 orderId、drug_id、quantity、price 等字段的 map - * @return 受影响行数 - */ - @Insert("") - int insertDetail(@Param("detail") Map detail); - - /** - * 统计指定医嘱的明细数量并加行级锁(FOR UPDATE),用于在同一事务中安全生成汇总单。 - * - * @param orderId 医嘱主键 - * @return 明细行数 - */ - @Select("SELECT COUNT(*) FROM dispensing_detail WHERE order_id = #{orderId} FOR UPDATE") - int countByOrderIdForUpdate(@Param("orderId") Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispensingMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispensingMapper.java deleted file mode 100644 index 98b136927..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispensingMapper.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import org.apache.ibatis.annotations.*; -import java.util.List; -import java.util.Map; - -/** - * 住院发退药数据访问层 - * 配合 InpatientDispensingServiceImpl 修复 Bug #503 状态流转逻辑 - */ -@Mapper -public interface DispensingMapper { - - @Update("UPDATE med_order SET exec_status = #{status} WHERE id = #{orderId}") - int updateOrderExecStatus(@Param("orderId") Long orderId, @Param("status") String status); - - @Insert("INSERT INTO phm_dispensing_detail (order_id, submit_status, create_time) " + - "VALUES (#{orderId}, #{submitStatus}, NOW())") - int initDispensingRecord(@Param("orderId") Long orderId, @Param("submitStatus") String submitStatus); - - @Insert("INSERT INTO phm_dispensing_summary (order_id, ward_code, status, create_time) " + - "SELECT #{orderId}, ward_code, 'PENDING', NOW() FROM med_order WHERE id = #{orderId}") - int syncToSummaryList(@Param("orderId") Long orderId); - - @Update("") - int batchUpdateSubmitStatus(@Param("orderIds") List orderIds, @Param("status") String status); - - @Insert("") - int batchSyncToSummaryList(@Param("orderIds") List orderIds); - - @Select("") - List> selectDispensingDetails(@Param("wardCode") String wardCode, @Param("requiredStatus") String requiredStatus); - - @Select("SELECT s.*, o.drug_name, o.patient_name " + - "FROM phm_dispensing_summary s " + - "JOIN med_order o ON s.order_id = o.id " + - "WHERE o.ward_code = #{wardCode} AND s.status = #{status} " + - "ORDER BY s.create_time DESC") - List> selectDispensingSummary(@Param("wardCode") String wardCode, @Param("status") String status); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispensingSummaryMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispensingSummaryMapper.java deleted file mode 100644 index 5d16043f7..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/DispensingSummaryMapper.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import org.apache.ibatis.annotations.*; - -import java.util.Map; - -/** - * 住院发药汇总单 Mapper - * - * 新增: - * 1. insertSummaryByOrderId – 基于已写入的明细数据聚合生成汇总单,所有聚合在数据库完成,避免业务层时序问题。 - */ -@Mapper -public interface DispensingSummaryMapper { - - /** - * 根据医嘱 ID 聚合已写入的发药明细,生成对应的汇总单记录。 - * - * 汇总字段示例(实际字段请依据业务表结构): - * - order_id - * - total_quantity (SUM(quantity)) - * - total_amount (SUM(quantity * price)) - * - created_at - * - * @param orderId 医嘱主键 - * @return 受影响行数 - */ - @Insert("") - int insertSummaryByOrderId(@Param("orderId") Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDispensingMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDispensingMapper.java deleted file mode 100644 index 3f730ade2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDispensingMapper.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import com.openhis.web.inpatient.vo.DispensingDetailVO; -import com.openhis.web.inpatient.vo.DispensingSummaryVO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -import java.util.List; - -/** - * 住院发退药数据访问层 - * 修复 Bug #503:统一明细单与汇总单的查询过滤条件,依据字典配置模式同步触发时机 - */ -@Mapper -public interface InpatientDispensingMapper { - - /** - * 查询发药明细单 - * @param wardId 病区ID - * @param submitMode 提交模式 (1:需申请, 2:自动) - * @return 明细列表 - */ - @Select("") - List selectDispensingDetails(@Param("wardId") Long wardId, @Param("submitMode") Integer submitMode); - - /** - * 查询发药汇总单 - * @param wardId 病区ID - * @param submitMode 提交模式 (1:需申请, 2:自动) - * @return 汇总列表 - */ - @Select("") - List selectDispensingSummary(@Param("wardId") Long wardId, @Param("submitMode") Integer submitMode); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDrugMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDrugMapper.java deleted file mode 100644 index ad7f31bae..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDrugMapper.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import org.apache.ibatis.annotations.*; -import java.util.List; -import java.util.Map; - -/** - * 住院药品发放/退药数据访问层 - * - * 修复 Bug #503: - * 通过新增明细插入、退药插入、汇总单 UPSERT 及状态查询方法, - * 确保业务层在同一事务内先写明细再写汇总,彻底消除“发药明细与汇总单触发时机不一致”的风险。 - * 适配 PostgreSQL 语法(ON CONFLICT DO UPDATE)。 - */ -@Mapper -public interface InpatientDrugMapper { - - /** - * 插入发药明细记录 - */ - @Insert("INSERT INTO inpatient_drug_dispense_detail " + - "(order_id, drug_id, quantity, operator, dispense_time, is_return) " + - "VALUES (#{orderId}, #{drugId}, #{quantity}, #{operator}, NOW(), 0)") - int insertDrugDispenseDetail(@Param("orderId") Long orderId, - @Param("drugId") Long drugId, - @Param("quantity") Integer quantity, - @Param("operator") String operator); - - /** - * 插入退药明细记录(数量使用负数保存) - */ - @Insert("INSERT INTO inpatient_drug_dispense_detail " + - "(order_id, drug_id, quantity, operator, dispense_time, is_return) " + - "VALUES (#{orderId}, #{drugId}, #{quantity}, #{operator}, NOW(), 1)") - int insertDrugReturnDetail(@Param("orderId") Long orderId, - @Param("drugId") Long drugId, - @Param("quantity") Integer quantity, - @Param("operator") String operator); - - /** - * 汇总单 UPSERT:累计每个医嘱、药品的发药/退药数量。 - * 使用 PostgreSQL 的 ON CONFLICT 语法保证幂等性与原子性。 - */ - @Insert("INSERT INTO inpatient_drug_dispense_summary " + - "(order_id, drug_id, total_quantity, last_update) " + - "VALUES (#{orderId}, #{drugId}, #{quantity}, NOW()) " + - "ON CONFLICT (order_id, drug_id) DO UPDATE SET " + - "total_quantity = inpatient_drug_dispense_summary.total_quantity + EXCLUDED.total_quantity, " + - "last_update = NOW()") - int upsertDrugDispenseSummary(@Param("orderId") Long orderId, - @Param("drugId") Long drugId, - @Param("quantity") Integer quantity); - - /** - * 查询药品发药提交模式(auto:自动发药,其他视为需申请模式) - */ - @Select("SELECT value FROM system_config WHERE key = 'nurse_drug_submit_mode' LIMIT 1") - String getDrugSubmitMode(); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientLabMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientLabMapper.java deleted file mode 100644 index 718083fce..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientLabMapper.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import org.apache.ibatis.annotations.*; -import java.util.List; -import java.util.Map; - -/** - * 住院检验申请数据访问层 - * - * 新增: - * 1. selectApplyStatusById – 查询检验申请当前状态,用于撤回前校验。 - * 2. updateApplyStatusToWithdraw – 将状态更新为 “已撤回”(WITHDRAWN),并记录撤回人、时间。 - * - * 这些方法配合 InpatientLabServiceImpl 中的业务校验,防止在不可撤回状态下执行删除导致异常。 - */ -@Mapper -public interface InpatientLabMapper { - - @Select("SELECT * FROM lab_apply WHERE id = #{applyId}") - Map selectLabApplyById(@Param("applyId") Long applyId); - - @Select("SELECT status FROM lab_apply WHERE id = #{applyId}") - String selectApplyStatusById(@Param("applyId") Long applyId); - - @Insert("INSERT INTO lab_apply (patient_id, exam_item_id, status, create_by, create_time) " + - "VALUES (#{patientId}, #{examItemId}, 'SUBMITTED', #{operator}, NOW())") - int insertLabApply(@Param("patientId") Long patientId, - @Param("examItemId") Long examItemId, - @Param("operator") String operator); - - @Select("SELECT * FROM lab_apply WHERE patient_id = #{patientId}") - List> selectLabAppliesByPatientId(@Param("patientId") Long patientId); - - /** - * 将检验申请状态置为已撤回,并记录撤回人、撤回时间。 - * 状态码约定:'WITHDRAWN' 表示已撤回。 - */ - @Update("UPDATE lab_apply SET " + - "status = 'WITHDRAWN', " + - "withdraw_by = #{operator}, " + - "withdraw_time = NOW(), " + - "update_time = NOW() " + - "WHERE id = #{applyId}") - int updateApplyStatusToWithdraw(@Param("applyId") Long applyId, - @Param("operator") String operator); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientOrderMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientOrderMapper.java deleted file mode 100644 index d7e452238..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientOrderMapper.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.mapper; -public interface InpatientOrderMapper {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientVitalMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientVitalMapper.java deleted file mode 100644 index 872d4bc3e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientVitalMapper.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import com.openhis.web.inpatient.vo.VitalSignVO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -import java.util.List; - -/** - * 住院体征(体温、脉搏、呼吸等)数据访问层 - * - * 修复 Bug #566:体温单图表区未渲染数据点。 - * 原因:前端图表组件(ECharts)默认读取字段名为 `value`(数值)和 `time`(时间)。 - * 旧的 SQL 只返回 `temperature`、`record_time`,导致前端无法匹配字段,图表渲染为空。 - * - * 解决方案: - * 1. 在查询中为体温数值添加别名 `value`,为记录时间添加别名 `time`。 - * 2. 同时保留原始字段别名(temperature、recordTime),以兼容后端其他业务。 - * 3. 增加注释说明字段映射关系,防止后续误删。 - */ -@Mapper -public interface InpatientVitalMapper { - - /** - * 查询指定患者的体温记录(用于体温单图表渲染)。 - * - * @param patientId 患者主键 ID - * @return 体温记录列表,包含以下字段: - * - temperature : 原始体温数值 - * - recordTime : 原始记录时间 - * - value : 与前端图表对应的体温数值别名 - * - time : 与前端图表对应的记录时间别名 - */ - @Select("") - List selectTemperatureRecords(@Param("patientId") Long patientId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InspectionApplyMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InspectionApplyMapper.java deleted file mode 100644 index 365a2ec02..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InspectionApplyMapper.java +++ /dev/null @@ -1,39 +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 java.util.List; -import java.util.Map; - -/** - * 检验申请单 Mapper - * 修复 Bug #576:补充明细项目查询接口,确保编辑时能正确回显已选检验项目 - */ -@Mapper -public interface InspectionApplyMapper { - - /** - * 根据主键查询检验申请单主表信息 - */ - @Select("SELECT id, patient_id, patient_name, status, symptom, sign, result, create_time, update_time " + - "FROM lab_request WHERE id = #{id}") - Map selectRequestById(@Param("id") Long id); - - /** - * 根据申请单ID查询关联的检验项目明细 - * 修复点:新增此查询,解决编辑接口未返回明细数据导致前端“已选择”列表为空的问题 - * - * 说明: - * - 表 `lab_request_item` 中的 `unit` 字段存储的是字典表的 ID。 - * - 为了在前端展示中文单位,需要关联字典表 `sys_dict`(id、dict_name)获取对应名称。 - * - 返回结果中保留原始 `unit`(ID),并额外返回 `unit_name`(中文)供前端使用。 - */ - @Select("SELECT i.id, i.request_id, i.item_code, i.item_name, i.price, i.quantity, i.unit, " + - " d.dict_name AS unit_name " + - "FROM lab_request_item i " + - "LEFT JOIN sys_dict d ON d.id = i.unit " + - "WHERE i.request_id = #{requestId} " + - "ORDER BY i.id ASC") - List> selectItemsByRequestId(@Param("requestId") Long requestId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/LabRequestMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/LabRequestMapper.java deleted file mode 100644 index 12733ffb9..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/LabRequestMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import com.openhis.web.inpatient.entity.LabRequest; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; -import org.apache.ibatis.annotations.Update; - -/** - * 检验申请数据库操作 Mapper - */ -@Mapper -public interface LabRequestMapper { - - @Select("SELECT id, patient_id, status, sign_time, sign_doctor_id, update_time FROM hisdev.lab_request WHERE id = #{id}") - LabRequest selectById(@Param("id") Long id); - - /** - * Bug #571 Fix: 使用显式字段更新替代全量覆盖 - * 避免 MyBatis 动态 SQL 在字段为 null 时误触发 NOT NULL 约束或覆盖其他业务字段 - */ - @Update("UPDATE hisdev.lab_request SET status = #{status}, sign_time = #{signTime}, sign_doctor_id = #{signDoctorId}, update_time = #{updateTime} WHERE id = #{id}") - int updateById(LabRequest request); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/OrderMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/OrderMapper.java deleted file mode 100644 index 81b18321c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/OrderMapper.java +++ /dev/null @@ -1,35 +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 - * - * 新增:撤回检验申请的状态更新SQL(Bug #571)以及退回状态更新(Bug #505)。 - */ -@Mapper -public interface OrderMapper { - - @Select("SELECT * FROM adm_order WHERE id = #{orderId}") - Map selectOrderById(@Param("orderId") Long orderId); - - @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); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/OrderVerificationMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/OrderVerificationMapper.java deleted file mode 100644 index d13cc618a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/OrderVerificationMapper.java +++ /dev/null @@ -1,28 +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; - -/** - * 住院医嘱校对数据访问层 - * - * 修复 Bug #505:提供医嘱状态查询与退回更新方法,支撑退回前置校验逻辑。 - */ -@Mapper -public interface OrderVerificationMapper { - - /** - * 查询医嘱核心状态(执行状态、发药状态、计费状态) - */ - @Select("SELECT id, exec_status, dispense_status, billing_status FROM med_order WHERE id = #{orderId}") - Map selectOrderStatusById(@Param("orderId") Long orderId); - - /** - * 将医嘱状态更新为已退回,并重置执行状态为未执行 - */ - @Update("UPDATE med_order SET status = 'RETURNED', exec_status = 'UNEXECUTED' WHERE id = #{orderId}") - int updateOrderToReturned(@Param("orderId") Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/SurgeryRequestMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/SurgeryRequestMapper.java deleted file mode 100644 index 9140281cb..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/SurgeryRequestMapper.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import com.openhis.web.inpatient.entity.SurgeryRequest; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; -import org.apache.ibatis.annotations.Update; - -/** - * 手术申请数据库操作 Mapper - */ -@Mapper -public interface SurgeryRequestMapper { - - @Select("SELECT id, patient_id, status, sign_time, sign_doctor_id, nurse_verify_status, update_time FROM hisdev.surgery_request WHERE id = #{id}") - SurgeryRequest selectById(@Param("id") Long id); - - /** - * 精确字段更新,避免全量覆盖导致脏数据 - */ - @Update("UPDATE hisdev.surgery_request SET status = #{status}, sign_time = #{signTime}, sign_doctor_id = #{signDoctorId}, nurse_verify_status = #{nurseVerifyStatus}, update_time = #{updateTime} WHERE id = #{id}") - int updateById(SurgeryRequest request); - - /** - * 级联更新关联手术医嘱状态 - */ - @Update("UPDATE hisdev.surgery_order SET status = #{orderStatus}, update_time = NOW() WHERE surgery_request_id = #{requestId}") - int updateOrderStatusByRequestId(@Param("requestId") Long requestId, @Param("orderStatus") String orderStatus); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/VitalSignMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/VitalSignMapper.java deleted file mode 100644 index 0a0a3d7de..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/VitalSignMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.openhis.web.inpatient.mapper; - -import com.openhis.web.inpatient.vo.VitalSignVO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -import java.util.List; - -/** - * 住院体征(体温单)数据访问层 - * - * 修复 Bug #566:新增查询已录入体征数据的 SQL,供前端体温图表使用。 - */ -@Mapper -public interface VitalSignMapper { - - /** - * 查询指定住院登记单的体征记录,按记录时间升序返回。 - * - * @param registrationId 住院登记单 ID - * @return 体征记录列表 - */ - @Select("") - List selectByRegistrationId(@Param("registrationId") Long registrationId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/VitalSignsMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/VitalSignsMapper.java deleted file mode 100644 index 01ad3da4a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/VitalSignsMapper.java +++ /dev/null @@ -1,21 +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 java.util.List; -import java.util.Map; - -/** - * 住院体征数据 Mapper - * 修复 Bug #566:确保查询结果按时间升序返回,且字段名与前端映射一致 - */ -@Mapper -public interface VitalSignsMapper { - - @Select("SELECT id, patient_id, record_time, temperature, heart_rate, pulse, status " + - "FROM his_vital_signs " + - "WHERE patient_id = #{patientId} AND status = 1 " + - "ORDER BY record_time ASC") - List> selectVitalSignsByPatient(@Param("patientId") Long patientId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/DictConfigService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/DictConfigService.java deleted file mode 100644 index c942ace46..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/DictConfigService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.inpatient.service; - -public interface DictConfigService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/DispensingService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/DispensingService.java deleted file mode 100644 index c724631e9..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/DispensingService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.inpatient.service; - -public interface DispensingService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/DispensingServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/DispensingServiceImpl.java deleted file mode 100644 index b89305044..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/DispensingServiceImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.openhis.web.inpatient.service; - -import com.openhis.web.inpatient.mapper.DispensingDetailMapper; -import com.openhis.web.inpatient.mapper.DispensingSummaryMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 住院发退药业务实现 - * - * 修复 Bug #503:发药明细与发药汇总单的触发时机不一致导致业务脱节风险。 - * - * 解决思路: - * 1. 将发药明细的写入与发药汇总单的生成放在同一个事务中,确保两者要么同时成功,要么同时回滚。 - * 2. 在写入明细后立即查询已写入的明细行数,只有在明细写入成功且行数大于 0 时才生成汇总单。 - * 3. 将生成汇总单的 SQL 改为基于已写入的明细数据进行聚合,而不是基于旧的业务状态字段,避免因状态延迟导致汇总单提前生成。 - * 4. 为防止并发冲突,在生成汇总单时使用行级锁 (FOR UPDATE) 锁定相关明细记录。 - */ -@Service -public class DispensingServiceImpl implements DispensingService { - - private final DispensingDetailMapper dispensingDetailMapper; - private final DispensingSummaryMapper dispensingSummaryMapper; - - public DispensingServiceImpl(DispensingDetailMapper dispensingDetailMapper, - DispensingSummaryMapper dispensingSummaryMapper) { - this.dispensingDetailMapper = dispensingDetailMapper; - this.dispensingSummaryMapper = dispensingSummaryMapper; - } - - /** - * 发药操作,包含明细写入和汇总单生成,保持事务原子性。 - * - * @param orderId 住院医嘱主键 - * @param drugList 发药明细列表,每条包含 drugId、quantity 等信息 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void dispense(Long orderId, List> drugList) { - if (orderId == null || drugList == null || drugList.isEmpty()) { - throw new IllegalArgumentException("发药参数缺失或明细为空"); - } - - // 1. 写入发药明细(每条明细都在同一事务中) - for (Map drug : drugList) { - drug.put("orderId", orderId); - dispensingDetailMapper.insertDetail(drug); - } - - // 2. 立即统计已写入的明细行数(使用 FOR UPDATE 锁定相关记录,防止并发导致统计不一致) - int detailCount = dispensingDetailMapper.countByOrderIdForUpdate(orderId); - if (detailCount <= 0) { - // 若明细写入异常,主动抛异常回滚事务 - throw new IllegalStateException("发药明细写入失败,无法生成汇总单"); - } - - // 3. 基于已写入的明细聚合生成发药汇总单 - // 汇总单的业务字段(如总数量、总金额)全部由数据库聚合计算,避免业务层自行计算导致时序不一致 - dispensingSummaryMapper.insertSummaryByOrderId(orderId); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientDispensingService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientDispensingService.java deleted file mode 100644 index f96fca044..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientDispensingService.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.openhis.web.inpatient.service; - -import com.openhis.web.inpatient.vo.DispensingDetailVO; -import com.openhis.web.inpatient.vo.DispensingSummaryVO; -import java.util.List; - -public interface InpatientDispensingService { - List getDispensingDetailList(Long orderId); - List getDispensingSummaryList(Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientDrugService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientDrugService.java deleted file mode 100644 index c4f941b4e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientDrugService.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.service; -public interface InpatientDrugService {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientLabService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientLabService.java deleted file mode 100644 index e85b3823a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientLabService.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.openhis.web.inpatient.service; - -import java.util.List; -import java.util.Map; - -/** - * 住院检验申请业务接口 - * - * 新增 withdrawLabApply 方法用于撤回检验申请。 - */ -public interface InpatientLabService { - - List> listLabApplies(Long patientId); - - void submitLabApply(Long patientId, Long examItemId, String operator); - - /** - * 撤回检验申请 - * - * @param applyId 检验申请主键 - * @param operator 操作人姓名 - * @throws IllegalStateException 当检验已进入不可撤回状态时抛出 - */ - void withdrawLabApply(Long applyId, String operator); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientOrderVerificationService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientOrderVerificationService.java deleted file mode 100644 index 708a1d386..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientOrderVerificationService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.inpatient.service; - -public interface InpatientOrderVerificationService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InspectionApplyService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InspectionApplyService.java deleted file mode 100644 index 050b85dc2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InspectionApplyService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.openhis.web.inpatient.service; - -import java.util.Map; - -/** - * 检验申请业务接口 - */ -public interface InspectionApplyService { - - /** - * 获取检验申请单详情(用于编辑回显) - * @param id 申请单主键 - * @return 包含主表字段及明细项目列表的完整数据 - */ - Map getDetailForEdit(Long id); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InspectionApplyServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InspectionApplyServiceImpl.java deleted file mode 100644 index a9d079e0c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InspectionApplyServiceImpl.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.openhis.web.inpatient.service; - -import com.openhis.web.inpatient.dto.InspectionApplyDTO; -import com.openhis.web.inpatient.entity.InspectionApply; -import com.openhis.web.inpatient.entity.InspectionApplyItem; -import com.openhis.web.inpatient.mapper.InspectionApplyMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * 住院检验申请服务实现 - */ -@Service -public class InspectionApplyServiceImpl implements InspectionApplyService { - - private final InspectionApplyMapper inspectionApplyMapper; - - public InspectionApplyServiceImpl(InspectionApplyMapper inspectionApplyMapper) { - this.inspectionApplyMapper = inspectionApplyMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public boolean createApply(InspectionApplyDTO dto) { - InspectionApply apply = new InspectionApply(); - apply.setPatientId(dto.getPatientId()); - apply.setSymptoms(dto.getSymptoms()); - apply.setSigns(dto.getSigns()); - apply.setStatus("PENDING_SIGN"); - apply.setCreateTime(java.time.LocalDateTime.now()); - inspectionApplyMapper.insert(apply); - - if (dto.getItems() != null && !dto.getItems().isEmpty()) { - for (InspectionApplyItem item : dto.getItems()) { - item.setApplyId(apply.getId()); - inspectionApplyMapper.insertItem(item); - } - } - return true; - } - - /** - * Bug #576 Fix: 获取检验申请单详情(含关联明细项目) - * 原逻辑仅查询主表,导致编辑弹窗右侧“已选择”列表无数据。 - * 现补充明细查询并注入 DTO 返回。 - */ - @Override - public InspectionApplyDTO getApplyById(Long id) { - InspectionApply apply = inspectionApplyMapper.selectById(id); - if (apply == null) { - throw new IllegalArgumentException("检验申请单不存在"); - } - - InspectionApplyDTO dto = new InspectionApplyDTO(); - dto.setId(apply.getId()); - dto.setPatientId(apply.getPatientId()); - dto.setSymptoms(apply.getSymptoms()); - dto.setSigns(apply.getSigns()); - dto.setStatus(apply.getStatus()); - dto.setCreateTime(apply.getCreateTime()); - - // 修复点:查询并绑定关联的检验项目明细 - List items = inspectionApplyMapper.selectItemsByApplyId(id); - dto.setItems(items); - - return dto; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public boolean updateApply(InspectionApplyDTO dto) { - InspectionApply apply = new InspectionApply(); - apply.setId(dto.getId()); - apply.setSymptoms(dto.getSymptoms()); - apply.setSigns(dto.getSigns()); - apply.setUpdateTime(java.time.LocalDateTime.now()); - inspectionApplyMapper.updateById(apply); - - // 简化处理:实际业务需对比差异进行增删改,此处仅演示核心修复逻辑 - if (dto.getItems() != null) { - inspectionApplyMapper.deleteItemsByApplyId(dto.getId()); - for (InspectionApplyItem item : dto.getItems()) { - item.setApplyId(dto.getId()); - inspectionApplyMapper.insertItem(item); - } - } - return true; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/LabRequestService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/LabRequestService.java deleted file mode 100644 index 09553973b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/LabRequestService.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.openhis.web.inpatient.service; - -import com.openhis.web.inpatient.dto.LabRequestListDTO; -import java.util.List; - -/** - * 住院检验申请服务接口 - */ -public interface LabRequestService { - - /** - * 获取检验申请列表 - * - * @param doctorId 医生 ID - * @return 列表数据 - */ - List getLabRequestList(Long doctorId); - - /** - * 撤回检验申请(Bug #571) - * - * @param requestId 检验申请主键 - * @return 是否撤回成功 - */ - boolean revokeLabRequest(Long requestId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/LabRequestServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/LabRequestServiceImpl.java deleted file mode 100644 index 22a4b66c8..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/LabRequestServiceImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.openhis.web.inpatient.service; - -import com.openhis.web.inpatient.entity.LabRequest; -import com.openhis.web.inpatient.mapper.LabRequestMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; - -/** - * 检验申请服务实现 - */ -@Service -public class LabRequestServiceImpl implements LabRequestService { - - private final LabRequestMapper labRequestMapper; - - public LabRequestServiceImpl(LabRequestMapper labRequestMapper) { - this.labRequestMapper = labRequestMapper; - } - - /** - * Bug #571 Fix: 修复检验申请撤回逻辑 - * 原逻辑未正确清空签发信息且状态枚举映射异常,导致数据库更新失败或触发约束报错。 - * 现改为精确字段更新,并增加状态前置校验。 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public boolean revokeRequest(Long requestId) { - if (requestId == null) { - throw new IllegalArgumentException("申请单ID不能为空"); - } - - LabRequest request = labRequestMapper.selectById(requestId); - if (request == null) { - throw new RuntimeException("检验申请单不存在"); - } - - // 仅允许撤回“已签发”状态的申请 - if (!"SIGNED".equals(request.getStatus())) { - throw new RuntimeException("仅已签发的检验申请可执行撤回操作"); - } - - // 修正状态流转:已签发 -> 待签发 - request.setStatus("PENDING_SIGN"); - // 清空签发人与签发时间,避免脏数据残留 - request.setSignTime(null); - request.setSignDoctorId(null); - request.setUpdateTime(LocalDateTime.now()); - - int updateResult = labRequestMapper.updateById(request); - if (updateResult <= 0) { - throw new RuntimeException("撤回操作失败,数据更新异常"); - } - return true; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationService.java deleted file mode 100644 index 8dd305bfc..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationService.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.openhis.web.inpatient.service; - -/** - * 医嘱校对业务接口 - * - * 新增:withdrawOrder 用于检验申请撤回(Bug #571)。 - */ -public interface OrderVerificationService { - - /** - * 退回医嘱(原有退回功能)。 - * - * @param orderId 医嘱ID - */ - void returnOrder(Long orderId); - - /** - * 撤回检验申请(Bug #571)。 - * - * @param orderId 检验医嘱ID - */ - void withdrawOrder(Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationServiceImpl.java deleted file mode 100644 index 746162444..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationServiceImpl.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.openhis.web.inpatient.service; - -import com.openhis.web.inpatient.dto.OrderVerificationDTO; -import com.openhis.web.inpatient.mapper.OrderVerificationMapper; -import com.openhis.web.pharmacy.mapper.DispensingRecordMapper; -import com.openhis.web.pharmacy.entity.DispensingRecord; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.List; - -/** - * 医嘱校对服务实现 - * 负责护士端医嘱校对、执行、退回等核心流转逻辑 - * - * 关键修复 (Bug #503): - * 1. 引入 submissionMode 参数控制数据落盘时机,严格遵循字典配置的“病区护士执行提交药品模式”。 - * 2. 若为“需申请模式”,执行阶段仅更新医嘱状态,不触发药房表写入;汇总申请时统一批量生成明细与汇总。 - * 3. 若为“自动模式”,执行阶段同步写入明细与汇总单,确保两者状态强一致。 - */ -@Service -public class OrderVerificationServiceImpl implements OrderVerificationService { - - private final DispensingRecordMapper dispensingRecordMapper; - private final OrderVerificationMapper orderVerificationMapper; - - public OrderVerificationServiceImpl(DispensingRecordMapper dispensingRecordMapper, - OrderVerificationMapper orderVerificationMapper) { - this.dispensingRecordMapper = dispensingRecordMapper; - this.orderVerificationMapper = orderVerificationMapper; - } - - @Override - public List getVerificationList(Long patientId) { - if (patientId == null) { - throw new IllegalArgumentException("患者ID不能为空"); - } - List rawList = orderVerificationMapper.selectVerificationList(patientId); - // 统一皮试状态映射 - for (OrderVerificationDTO dto : rawList) { - dto.setSkinTestStatus(mapSkinTestStatus(dto.getSkinTestStatus())); - } - return rawList; - } - - private String mapSkinTestStatus(String status) { - // 保持原有映射逻辑 - return status; - } - - /** - * 发药执行(护士端) - * 修复 Bug #503:根据提交模式控制药房数据写入时机,避免明细与汇总脱节。 - */ - @Transactional(rollbackFor = Exception.class) - public boolean dispenseMedication(Long orderId, Long drugId, Integer quantity, - BigDecimal price, String createdBy, String submissionMode) { - if (orderId == null || drugId == null || quantity == null || quantity <= 0) { - throw new IllegalArgumentException("发药参数不完整或数量非法"); - } - - // 1. 更新医嘱执行状态 - orderVerificationMapper.updateOrderStatus(orderId, "EXECUTED"); - - // 2. 根据字典模式控制药房数据落盘 - if ("自动模式".equals(submissionMode)) { - // 自动模式:执行即生成明细与汇总,保证同步 - DispensingRecord record = new DispensingRecord(); - record.setOrderId(orderId); - record.setDrugId(drugId); - record.setQuantity(quantity); - record.setCreatedBy(createdBy); - dispensingRecordMapper.insert(record); - - // 同步 UPSERT 汇总单 - dispensingRecordMapper.upsertSummaryAfterDispense(orderId, drugId, quantity, price); - } - // 需申请模式:此处不写入药房表,等待 submitSummaryDispensing 统一处理 - return true; - } - - /** - * 汇总发药申请(护士端) - * 修复 Bug #503:在“需申请模式”下,作为唯一触发点,批量生成明细与汇总单, - * 确保药房端明细与汇总数据同时可见、数量一致。 - */ - @Transactional(rollbackFor = Exception.class) - public boolean submitSummaryDispensing(List orderIds, String createdBy) { - if (orderIds == null || orderIds.isEmpty()) { - throw new IllegalArgumentException("申请单号列表不能为空"); - } - - List pendingOrders = orderVerificationMapper.selectPendingDispensing(orderIds); - for (OrderVerificationDTO order : pendingOrders) { - DispensingRecord record = new DispensingRecord(); - record.setOrderId(order.getOrderId()); - record.setDrugId(order.getDrugId()); - record.setQuantity(order.getQuantity()); - record.setCreatedBy(createdBy); - dispensingRecordMapper.insert(record); - - dispensingRecordMapper.upsertSummaryAfterDispense( - order.getOrderId(), order.getDrugId(), order.getQuantity(), order.getPrice()); - } - - // 标记已申请状态,防止重复提交 - orderVerificationMapper.batchUpdateDispensingStatus(orderIds, "APPLIED"); - return true; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/SurgeryRequestService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/SurgeryRequestService.java deleted file mode 100644 index 44e0059b4..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/SurgeryRequestService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.inpatient.service; - -public interface SurgeryRequestService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/SurgeryRequestServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/SurgeryRequestServiceImpl.java deleted file mode 100644 index 0172867fb..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/SurgeryRequestServiceImpl.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.openhis.web.inpatient.service; - -import com.openhis.web.inpatient.entity.SurgeryRequest; -import com.openhis.web.inpatient.mapper.SurgeryRequestMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; - -/** - * 手术申请服务实现 - */ -@Service -public class SurgeryRequestServiceImpl implements SurgeryRequestService { - - private final SurgeryRequestMapper surgeryRequestMapper; - - public SurgeryRequestServiceImpl(SurgeryRequestMapper surgeryRequestMapper) { - this.surgeryRequestMapper = surgeryRequestMapper; - } - - /** - * 删除手术申请单(仅待签发状态) - */ - @Override - @Transactional(rollbackFor = Exception.class) - public boolean deleteRequest(Long requestId) { - if (requestId == null) { - throw new IllegalArgumentException("申请单ID不能为空"); - } - - SurgeryRequest request = surgeryRequestMapper.selectById(requestId); - if (request == null) { - throw new RuntimeException("手术申请单不存在"); - } - - if (!"PENDING_SIGN".equals(request.getStatus())) { - throw new RuntimeException("仅待签发状态的手术申请可删除"); - } - - // 状态更新为已作废 - request.setStatus("CANCELLED"); - request.setUpdateTime(LocalDateTime.now()); - - int updateResult = surgeryRequestMapper.updateById(request); - if (updateResult <= 0) { - throw new RuntimeException("删除失败,数据更新异常"); - } - - // 级联作废对应的手术医嘱 - surgeryRequestMapper.updateOrderStatusByRequestId(requestId, "CANCELLED"); - return true; - } - - /** - * 撤回手术申请单(仅已签发状态,防护士已校对冲突) - */ - @Override - @Transactional(rollbackFor = Exception.class) - public boolean revokeRequest(Long requestId) { - if (requestId == null) { - throw new IllegalArgumentException("申请单ID不能为空"); - } - - SurgeryRequest request = surgeryRequestMapper.selectById(requestId); - if (request == null) { - throw new RuntimeException("手术申请单不存在"); - } - - if (!"SIGNED".equals(request.getStatus())) { - throw new RuntimeException("仅已签发状态的手术申请可撤回"); - } - - // 防冲突实时校验:若病区护士已校对通过,拦截撤回 - if (Boolean.TRUE.equals(request.getNurseVerifyStatus())) { - throw new RuntimeException("撤回失败!该手术申请已由病区护士已校对,请致电病区护士处理。"); - } - - // 状态回滚:已签发 -> 待签发 - request.setStatus("PENDING_SIGN"); - request.setSignTime(null); - request.setSignDoctorId(null); - request.setUpdateTime(LocalDateTime.now()); - - int updateResult = surgeryRequestMapper.updateById(request); - if (updateResult <= 0) { - throw new RuntimeException("撤回失败,数据更新异常"); - } - - // 级联更新对应的手术医嘱状态为待签发 - surgeryRequestMapper.updateOrderStatusByRequestId(requestId, "PENDING_SIGN"); - return true; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/VitalSignService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/VitalSignService.java deleted file mode 100644 index 1fb22c2b9..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/VitalSignService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.inpatient.service; - -public interface VitalSignService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/VitalSignsService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/VitalSignsService.java deleted file mode 100644 index c21a6d77c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/VitalSignsService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.inpatient.service; - -public interface VitalSignsService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/VitalSignsServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/VitalSignsServiceImpl.java deleted file mode 100644 index 444ea117f..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/VitalSignsServiceImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.openhis.web.inpatient.service; - -import com.openhis.web.inpatient.mapper.VitalSignsMapper; -import org.springframework.stereotype.Service; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * 住院体征服务实现 - * 修复 Bug #566:统一时间格式为 yyyy-MM-dd HH:mm,避免前端解析异常导致坐标映射失败 - */ -@Service -public class VitalSignsServiceImpl implements VitalSignsService { - - private final VitalSignsMapper vitalSignsMapper; - private static final DateTimeFormatter TIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); - - public VitalSignsServiceImpl(VitalSignsMapper vitalSignsMapper) { - this.vitalSignsMapper = vitalSignsMapper; - } - - @Override - public List> getVitalSignsData(Long patientId) { - List> records = vitalSignsMapper.selectVitalSignsByPatient(patientId); - return records.stream().map(r -> { - // 统一时间格式供前端直接作为 xAxis 分类 - if (r.get("record_time") != null) { - r.put("timeStr", r.get("record_time").toString().replace("T", " ").substring(0, 16)); - r.put("recordTime", r.get("record_time")); - } - return r; - }).collect(Collectors.toList()); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientDispensingServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientDispensingServiceImpl.java deleted file mode 100644 index 4cf657aac..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientDispensingServiceImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.inpatient.mapper.InpatientDispensingMapper; -import com.openhis.web.inpatient.service.InpatientDispensingService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Map; - -/** - * 住院发退药业务逻辑层 - * - * 修复说明 (Bug #503): - * 引入字典参数 `nurse_exec_submit_mode` 控制发药数据可见时机。 - * 统一明细单与汇总单的查询入口,确保两者触发时机严格同步。 - */ -@Service -public class InpatientDispensingServiceImpl implements InpatientDispensingService { - - @Autowired - private InpatientDispensingMapper dispensingMapper; - - /** - * 获取《字典管理》中维护的 '病区护士执行提交药品模式' - * 1: 需申请模式 (默认) - * 2: 自动模式 - */ - private String getNurseSubmitMode() { - // 实际项目中应通过字典服务获取: sysDictService.getDictValue("nurse_exec_submit_mode") - // 此处默认返回 "1" (需申请模式) - return "1"; - } - - @Override - public List> getDispensingDetails(Long wardId) { - String mode = getNurseSubmitMode(); - // 明细单与汇总单共用同一查询逻辑,由 submitMode 决定过滤条件 - return dispensingMapper.selectDispensingRecords(wardId, mode); - } - - @Override - public List> getDispensingSummary(Long wardId) { - String mode = getNurseSubmitMode(); - // 汇总单查询逻辑与明细单完全一致,消除数据脱节 - return dispensingMapper.selectDispensingRecords(wardId, mode); - } - - @Override - public void submitDispensingApplication(List detailIds, String operator) { - if (detailIds == null || detailIds.isEmpty()) { - return; - } - // 实际业务逻辑:更新 apply_status = 'APPLIED', apply_time = NOW() - dispensingMapper.updateApplyStatusByIds(detailIds); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientDrugServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientDrugServiceImpl.java deleted file mode 100644 index ea09dd0e3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientDrugServiceImpl.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.inpatient.mapper.InpatientDrugMapper; -import com.openhis.web.inpatient.service.InpatientDrugService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 住院发药/退药业务实现 - * - * 修复 Bug #503: - * 旧实现中,护士“执行”医嘱即触发明细落库,而汇总单需等待“汇总发药申请”才生成, - * 导致药房端明细与汇总数据触发时机脱节,存在账务与库存风险。 - * - * 解决思路: - * 1. 将发药/退药操作严格收敛至同一事务中,确保原子性。 - * 2. 遵循“先明细后汇总”的写入顺序,利用 PostgreSQL 事务隔离级别保证一致性。 - * 3. 结合字典配置 `nurse_drug_submit_mode`,若为“需申请模式”, - * 业务层仅允许在汇总申请流程中调用本方法,实现“申请才显示”的同步逻辑。 - */ -@Service -public class InpatientDrugServiceImpl implements InpatientDrugService { - - @Autowired - private InpatientDrugMapper drugMapper; - - /** - * 发药(包括首次发药和追加发药) - * 修复后:明细与汇总在同一事务内同步写入,消除触发时机不一致风险。 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void dispenseDrugs(Long orderId, List> drugList) { - if (drugList == null || drugList.isEmpty()) { - throw new IllegalArgumentException("drugList cannot be null or empty"); - } - - // 获取系统配置的提交模式,默认为需申请模式 (非 auto 即视为 apply) - String mode = drugMapper.getDrugSubmitMode(); - boolean isApplyMode = !"auto".equalsIgnoreCase(mode); - - // 在需申请模式下,仅在“汇总发药申请”业务流中调用此方法。 - // 这里不做强制校验(前端/网关已拦截),只记录日志便于排查。 - if (isApplyMode) { - // 可根据实际需求加入审计日志 - } - - // 逐条写入明细并同步更新汇总 - for (Map drugInfo : drugList) { - Long drugId = ((Number) drugInfo.get("drugId")).longValue(); - Integer quantity = ((Number) drugInfo.get("quantity")).intValue(); - String operator = (String) drugInfo.getOrDefault("operator", "system"); - - // 1. 写入明细 - drugMapper.insertDrugDispenseDetail(orderId, drugId, quantity, operator); - - // 2. 更新/插入汇总(UPSERT) - drugMapper.upsertDrugDispenseSummary(orderId, drugId, quantity); - } - } - - /** - * 退药(数量使用负数保存,业务同上) - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void returnDrugs(Long orderId, List> drugList) { - if (drugList == null || drugList.isEmpty()) { - throw new IllegalArgumentException("drugList cannot be null or empty"); - } - - for (Map drugInfo : drugList) { - Long drugId = ((Number) drugInfo.get("drugId")).longValue(); - Integer quantity = -Math.abs(((Number) drugInfo.get("quantity")).intValue()); // 负数 - String operator = (String) drugInfo.getOrDefault("operator", "system"); - - // 1. 写入退药明细 - drugMapper.insertDrugReturnDetail(orderId, drugId, quantity, operator); - - // 2. 汇总单同样使用 UPSERT,负数会自动扣减 - drugMapper.upsertDrugDispenseSummary(orderId, drugId, quantity); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientLabServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientLabServiceImpl.java deleted file mode 100644 index 15bdec2c3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientLabServiceImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.inpatient.mapper.InpatientLabMapper; -import com.openhis.web.inpatient.service.InpatientLabService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 住院检验申请业务实现 - * - * 修复说明 (Bug #571): - * 检验申请执行“撤回”操作时,原实现直接调用 delete 操作, - * 当检验已进入“已采血”或“已报告”等不可撤回状态时仍会尝试删除, - * 触发数据库约束异常并返回通用错误提示,导致前端显示“系统异常”。 - * - * 解决思路: - * 1. 在撤回前先查询检验申请的当前状态; - * 2. 仅当状态为 “已提交”(SUBMITTED) 或 “待采血”(PENDING) 时允许撤回; - * 3. 对不可撤回的状态返回业务异常,前端可捕获并展示明确提示 - * “该检验已采血或已报告,不能撤回,请联系检验科处理”。 - * 4. 将撤回操作封装在同一事务中,确保状态检查与更新原子化。 - */ -@Service -public class InpatientLabServiceImpl implements InpatientLabService { - - @Autowired - private InpatientLabMapper labMapper; - - /** - * 撤回检验申请 - * - * @param applyId 检验申请主键 - * @param operator 操作人姓名 - * @throws IllegalStateException 当检验已进入不可撤回状态时抛出 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void withdrawLabApply(Long applyId, String operator) { - // 1. 查询当前状态 - String currentStatus = labMapper.selectApplyStatusById(applyId); - if (currentStatus == null) { - throw new IllegalArgumentException("检验申请不存在"); - } - - // 2. 只允许在“已提交”或“待采血”状态下撤回 - if (!"SUBMITTED".equals(currentStatus) && !"PENDING".equals(currentStatus)) { - // 返回业务可读的异常信息,前端会捕获并展示 - throw new IllegalStateException( - "该检验已采血或已报告,不能撤回,请联系检验科处理" - ); - } - - // 3. 更新状态为撤回,并记录操作人、撤回时间 - labMapper.updateApplyStatusToWithdraw(applyId, operator); - } - - // 其余业务方法保持不变 - @Override - public List> listLabApplies(Long patientId) { - return labMapper.selectLabAppliesByPatientId(patientId); - } - - @Override - public void submitLabApply(Long patientId, Long examItemId, String operator) { - labMapper.insertLabApply(patientId, examItemId, operator); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InspectionApplyServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InspectionApplyServiceImpl.java deleted file mode 100644 index 5c6068ce7..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InspectionApplyServiceImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.inpatient.mapper.InspectionApplyMapper; -import com.openhis.web.inpatient.service.InspectionApplyService; -import org.springframework.stereotype.Service; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * 检验申请业务实现 - * 修复 Bug #576:在获取编辑详情时,显式查询并组装明细项目数据,确保前端右侧列表正确回显 - */ -@Service -public class InspectionApplyServiceImpl implements InspectionApplyService { - - private final InspectionApplyMapper inspectionApplyMapper; - - public InspectionApplyServiceImpl(InspectionApplyMapper inspectionApplyMapper) { - this.inspectionApplyMapper = inspectionApplyMapper; - } - - @Override - public Map getDetailForEdit(Long id) { - if (id == null) { - throw new IllegalArgumentException("申请单ID不能为空"); - } - - // 1. 查询主表数据(症状、体征等) - Map request = inspectionApplyMapper.selectRequestById(id); - if (request == null) { - throw new RuntimeException("检验申请单不存在或已被删除"); - } - - // 2. 修复 Bug #576:关联查询明细项目列表 - // 原逻辑缺失此步骤,导致前端接收不到 items 数据,右侧“已选择”框架显示为空 - List> items = inspectionApplyMapper.selectItemsByRequestId(id); - request.put("items", items != null ? items : Collections.emptyList()); - - return request; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/NurseOrderServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/NurseOrderServiceImpl.java deleted file mode 100644 index 38bd53bab..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/NurseOrderServiceImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.inpatient.mapper.OrderMapper; -import com.openhis.web.inpatient.domain.Order; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * 护士站医嘱业务实现 - * - * 修复 Bug #505: - * 原逻辑未校验药房发药状态,导致已发药医嘱可被直接退回,破坏逆向闭环。 - * 修复方案:在退回操作入口增加 dispense_status 与 execute_status 前置校验, - * 拦截非法流转,强制走“取消执行->退药申请->药房确认->状态回滚”标准流程。 - */ -@Service -public class NurseOrderServiceImpl { - - @Autowired - private OrderMapper orderMapper; - - /** - * 护士端医嘱退回操作 - * - * @param orderIds 待退回的医嘱ID列表 - */ - @Transactional(rollbackFor = Exception.class) - public void returnOrders(List orderIds) { - if (orderIds == null || orderIds.isEmpty()) { - throw new IllegalArgumentException("医嘱ID列表不能为空"); - } - - for (Long orderId : orderIds) { - Order order = orderMapper.selectById(orderId); - if (order == null) { - throw new IllegalArgumentException("医嘱不存在: " + orderId); - } - - // ================= Bug #505 核心修复 ================= - // 1. 物理状态校验:已发药严禁直接退回 - if (order.getDispenseStatus() != null && order.getDispenseStatus() == 1) { - throw new IllegalStateException("该药品已由药房发放,请先执行退药处理,不可直接退回"); - } - - // 2. 执行状态校验:已执行需先走取消执行流程 - if (order.getExecuteStatus() != null && order.getExecuteStatus() == 1) { - throw new IllegalStateException("该医嘱已执行,请先在【医嘱执行】模块取消执行后再退回"); - } - // ================================================== - - // 原有退回逻辑:状态回退至医生站待审核/未执行状态 - order.setStatus(0); // 0: 未执行/已退回 - order.setDispenseStatus(0); - order.setExecuteStatus(0); - orderMapper.updateById(order); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerificationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerificationServiceImpl.java deleted file mode 100644 index 539064563..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerificationServiceImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.inpatient.mapper.OrderVerificationMapper; -import com.openhis.web.inpatient.service.OrderVerificationService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.util.Map; - -/** - * 住院医嘱校对业务实现 - * - * 修复 Bug #505:【业务逻辑缺陷】药品医嘱已由药房发药,护士仍能在“医嘱校对”模块执行“退回”操作 - * - * 根因:原退回接口缺失前置状态校验,未拦截“已发药”、“已执行”、“已计费”的医嘱,导致逆向流程断裂。 - * 修复方案: - * 1. 在退回操作前强制校验医嘱的 exec_status、dispense_status、billing_status。 - * 2. 若 dispense_status 为“已发药”,直接抛出阻断异常,提示走标准退药逆向流程。 - * 3. 若 exec_status 非“未执行”或 billing_status 为“已计费”,同步拦截,确保账务与物理库存闭环。 - */ -@Service -public class OrderVerificationServiceImpl implements OrderVerificationService { - - private final OrderVerificationMapper orderVerificationMapper; - - public OrderVerificationServiceImpl(OrderVerificationMapper orderVerificationMapper) { - this.orderVerificationMapper = orderVerificationMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void returnOrder(Long orderId) { - if (orderId == null) { - throw new IllegalArgumentException("医嘱ID不能为空"); - } - - Map order = orderVerificationMapper.selectOrderStatusById(orderId); - if (order == null) { - throw new RuntimeException("医嘱不存在,无法执行退回"); - } - - String execStatus = (String) order.get("exec_status"); - String dispenseStatus = (String) order.get("dispense_status"); - String billingStatus = (String) order.get("billing_status"); - - // 核心状态约束校验(修复 Bug #505) - // 1. 物理状态:必须为“未发药/未领药” - if ("已发药".equals(dispenseStatus) || "DISPENSED".equals(dispenseStatus)) { - throw new RuntimeException("该药品已由药房发放,请先执行退药处理,不可直接退回"); - } - // 2. 执行状态:必须为“未执行” - if (!"未执行".equals(execStatus) && !"UNEXECUTED".equals(execStatus)) { - throw new RuntimeException("医嘱已执行,请先在【医嘱执行】模块取消执行后再退回"); - } - // 3. 财务状态:必须为“未计费” - if ("已计费".equals(billingStatus) || "BILLED".equals(billingStatus)) { - throw new RuntimeException("医嘱已产生计费,请先撤销计费后再退回"); - } - - // 校验通过,执行状态流转 - int updated = orderVerificationMapper.updateOrderToReturned(orderId); - if (updated == 0) { - throw new RuntimeException("医嘱退回失败,数据状态异常"); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java deleted file mode 100644 index 7b419393d..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/OrderVerifyServiceImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.openhis.web.inpatient.service.impl; - -import com.openhis.web.outpatient.mapper.OrderMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 住院医嘱校对业务实现 - * - * 修复 Bug #505: - * 增加前置状态校验,拦截已执行或已发药的药品医嘱直接退回。 - * 严格遵循“逆向闭环”原则:已发药必须走退药流程,不可跨状态直接退回。 - */ -@Service -public class OrderVerifyServiceImpl { - - private final OrderMapper orderMapper; - - public OrderVerifyServiceImpl(OrderMapper orderMapper) { - this.orderMapper = orderMapper; - } - - /** - * 批量退回已校对医嘱 - * - * @param orderIds 医嘱ID列表 - */ - @Transactional(rollbackFor = Exception.class) - public void returnOrders(List orderIds) { - if (orderIds == null || orderIds.isEmpty()) { - throw new IllegalArgumentException("退回医嘱列表不能为空"); - } - - for (Long orderId : orderIds) { - Map order = orderMapper.selectOrderById(orderId); - if (order == null) { - throw new IllegalArgumentException("医嘱不存在,ID=" + orderId); - } - - String execStatus = String.valueOf(order.get("exec_status")); - String dispenseStatus = String.valueOf(order.get("dispense_status")); - - // 核心状态约束校验:执行状态或物理发药状态已流转,严禁直接退回 - if ("EXECUTED".equals(execStatus) || "DISPENSED".equals(dispenseStatus)) { - throw new RuntimeException("该药品已由药房发放,请先执行退药处理,不可直接退回"); - } - } - - // 校验通过后,执行原有退回逻辑(状态流转至医生站) - for (Long orderId : orderIds) { - orderMapper.updateOrderStatus(orderId, "RETURNED"); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/vo/DispensingDetailVO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/vo/DispensingDetailVO.java deleted file mode 100644 index 3e11ab0d4..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/vo/DispensingDetailVO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.vo; -public class DispensingDetailVO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/vo/DispensingSummaryVO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/vo/DispensingSummaryVO.java deleted file mode 100644 index 7a9963e28..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/vo/DispensingSummaryVO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.inpatient.vo; -public class DispensingSummaryVO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/vo/VitalSignVO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/vo/VitalSignVO.java deleted file mode 100644 index bba9ab2eb..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/vo/VitalSignVO.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.openhis.web.inpatient.vo; - -import java.time.LocalDateTime; - -/** - * 体征(体温单)视图对象 - * - * 修复 Bug #566:定义前端需要的字段结构,确保图表能够正确解析体温等关键指标。 - */ -public class VitalSignVO { - - private Long id; - private Long registrationId; - private LocalDateTime recordTime; - private Double temperature; // 体温(℃) - private Integer pulse; // 脉搏(次/分) - private Integer respiration; // 呼吸(次/分) - private Integer systolicBp; // 收缩压(mmHg) - private Integer diastolicBp; // 舒张压(mmHg) - - // getters & setters - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Long getRegistrationId() { - return registrationId; - } - - public void setRegistrationId(Long registrationId) { - this.registrationId = registrationId; - } - - public LocalDateTime getRecordTime() { - return recordTime; - } - - public void setRecordTime(LocalDateTime recordTime) { - this.recordTime = recordTime; - } - - public Double getTemperature() { - return temperature; - } - - public void setTemperature(Double temperature) { - this.temperature = temperature; - } - - public Integer getPulse() { - return pulse; - } - - public void setPulse(Integer pulse) { - this.pulse = pulse; - } - - public Integer getRespiration() { - return respiration; - } - - public void setRespiration(Integer respiration) { - this.respiration = respiration; - } - - public Integer getSystolicBp() { - return systolicBp; - } - - public void setSystolicBp(Integer systolicBp) { - this.systolicBp = systolicBp; - } - - public Integer getDiastolicBp() { - return diastolicBp; - } - - public void setDiastolicBp(Integer diastolicBp) { - this.diastolicBp = diastolicBp; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/mapper/OrderMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/mapper/OrderMapper.java deleted file mode 100644 index 5d81ff9fb..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/mapper/OrderMapper.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.nurse.mapper; -public interface OrderMapper {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/mapper/VitalSignMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/mapper/VitalSignMapper.java deleted file mode 100644 index 5cc463850..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/mapper/VitalSignMapper.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.openhis.web.nurse.mapper; - -import org.apache.ibatis.annotations.Insert; -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 #566:提供按时间排序的查询接口,解决前端图表渲染空数据问题。 - */ -@Mapper -public interface VitalSignMapper { - - /** - * 查询患者体征数据并按时间升序排列 - */ - @Select("SELECT id, patient_id, record_time, temperature, heart_rate, pulse " + - "FROM his_vital_sign " + - "WHERE patient_id = #{patientId} " + - "ORDER BY record_time ASC") - List> selectByPatientIdOrderByTime(@Param("patientId") String patientId); - - /** - * 插入新体征记录 - */ - @Insert("INSERT INTO his_vital_sign (patient_id, record_time, temperature, heart_rate, pulse, create_time) " + - "VALUES (#{patientId}, #{recordTime}, #{temperature}, #{heartRate}, #{pulse}, NOW())") - int insertVitalSign(Map signData); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/OrderExecutionService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/OrderExecutionService.java deleted file mode 100644 index 077b9252c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/OrderExecutionService.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.nurse.service; -public interface OrderExecutionService {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/OrderService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/OrderService.java deleted file mode 100644 index bf5473a3a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/OrderService.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.nurse.service; -public interface OrderService {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/OrderVerificationService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/OrderVerificationService.java deleted file mode 100644 index 5e43688ce..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/OrderVerificationService.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.nurse.service; -public interface OrderVerificationService {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/VitalSignService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/VitalSignService.java deleted file mode 100644 index 3f1152e67..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/VitalSignService.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.nurse.service; -public interface VitalSignService {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/NurseOrderServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/NurseOrderServiceImpl.java deleted file mode 100644 index 26838d756..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/NurseOrderServiceImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.openhis.web.nurse.service.impl; - -import com.openhis.web.outpatient.mapper.OrderMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 护士站医嘱业务逻辑处理 - * 修复 Bug #505:增加退回前置状态强校验,阻断已发药/已执行/已计费医嘱的直接退回 - */ -@Service -public class NurseOrderServiceImpl { - - private final OrderMapper orderMapper; - - public NurseOrderServiceImpl(OrderMapper orderMapper) { - this.orderMapper = orderMapper; - } - - /** - * 执行医嘱退回操作 - * @param orderIds 医嘱ID列表 - */ - @Transactional(rollbackFor = Exception.class) - public void returnOrders(List orderIds) { - for (Long orderId : orderIds) { - Map order = orderMapper.selectOrderById(orderId); - if (order == null) { - throw new RuntimeException("医嘱不存在"); - } - - String execStatus = (String) order.get("execution_status"); - String dispStatus = (String) order.get("dispensing_status"); - String billStatus = (String) order.get("billing_status"); - - // Bug #505 后端强校验:已执行、已发药、已计费状态严禁直接退回 - // 必须走逆向物理流程(退药申请 -> 药房确认退药 -> 库存/账务回滚 -> 状态解除) - if ("EXECUTED".equals(execStatus) || "DISPENSED".equals(dispStatus) || "BILLED".equals(billStatus)) { - throw new RuntimeException("该药品已由药房发放,请先执行退药处理,不可直接退回"); - } - - // 状态校验通过,执行退回逻辑 - orderMapper.updateOrderStatus(orderId, OrderMapper.ORDER_STATUS_RETURNED); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/OrderExecutionServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/OrderExecutionServiceImpl.java deleted file mode 100644 index 44fe736c8..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/OrderExecutionServiceImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.openhis.web.nurse.service.impl; - -import com.openhis.web.nurse.mapper.OrderMapper; -import com.openhis.web.nurse.service.OrderExecutionService; -import com.openhis.web.system.service.SysConfigService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 护士医嘱执行业务实现 - * - * 修复 Bug #503:执行医嘱时根据系统配置自动流转申请状态。 - * - 需申请模式:执行后仅更新 execution_status,application_status 保持 PENDING,等待护士手动汇总申请。 - * - 自动模式:执行后同步将 application_status 更新为 APPLIED,实现明细与汇总即时同步。 - */ -@Service -public class OrderExecutionServiceImpl implements OrderExecutionService { - - private final OrderMapper orderMapper; - private final SysConfigService sysConfigService; - - private static final String CONFIG_KEY_SUBMIT_MODE = "WARD_NURSE_DRUG_SUBMIT_MODE"; - private static final String MODE_AUTO = "AUTO"; - - public OrderExecutionServiceImpl(OrderMapper orderMapper, SysConfigService sysConfigService) { - this.orderMapper = orderMapper; - this.sysConfigService = sysConfigService; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void executeOrders(List orderIds) { - if (orderIds == null || orderIds.isEmpty()) { - throw new IllegalArgumentException("医嘱ID列表不能为空"); - } - - String mode = sysConfigService.getConfigValue(CONFIG_KEY_SUBMIT_MODE); - boolean isAutoMode = MODE_AUTO.equals(mode); - - for (Long orderId : orderIds) { - validateExecutionPreconditions(orderId); - - // 1. 更新执行状态为已执行 - orderMapper.updateExecutionStatus(orderId, "EXECUTED"); - - // 2. 根据模式同步申请状态 (Bug #503 核心修复) - if (isAutoMode) { - orderMapper.updateApplicationStatus(orderId, "APPLIED"); - } else { - // 需申请模式:显式标记为待申请,防止脏数据导致提前显示 - orderMapper.updateApplicationStatus(orderId, "PENDING"); - } - } - } - - private void validateExecutionPreconditions(Long orderId) { - Map order = orderMapper.selectOrderById(orderId); - if (order == null) { - throw new RuntimeException("医嘱不存在,orderId=" + orderId); - } - String status = (String) order.get("execution_status"); - if ("EXECUTED".equals(status)) { - throw new RuntimeException("该医嘱已执行,请勿重复操作"); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/OrderServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/OrderServiceImpl.java deleted file mode 100644 index 181b0c9e2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/OrderServiceImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.openhis.web.nurse.service.impl; - -import com.openhis.web.nurse.service.OrderService; -import com.openhis.web.outpatient.mapper.OrderMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 护士站医嘱业务逻辑实现 - * 修复 Bug #505:增加已发药医嘱退回前置校验,阻断非法逆向流转。 - */ -@Service -public class OrderServiceImpl implements OrderService { - - private final OrderMapper orderMapper; - - public OrderServiceImpl(OrderMapper orderMapper) { - this.orderMapper = orderMapper; - } - - /** - * 护士端退回医嘱 - * 核心约束:执行状态必须为“未执行”,物理状态必须为“未发药/未领药”,财务状态必须为“未计费”。 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void returnOrders(List orderIds, String operator) { - for (Long orderId : orderIds) { - Map order = orderMapper.selectOrderById(orderId); - if (order == null) { - throw new IllegalArgumentException("医嘱不存在: " + orderId); - } - - String dispensingStatus = (String) order.get("dispensing_status"); - String execStatus = (String) order.get("exec_status"); - - // Bug #505 修复:已发药状态严禁直接退回 - if ("DISPENSED".equalsIgnoreCase(dispensingStatus)) { - throw new IllegalStateException("该药品已由药房发放,请先执行退药处理,不可直接退回"); - } - - // 附加校验:已执行状态不可直接退回(需走取消执行流程) - if ("EXECUTED".equalsIgnoreCase(execStatus)) { - throw new IllegalStateException("该医嘱已执行,请先在【医嘱执行】模块取消执行后再退回"); - } - - // 状态校验通过后,执行退回逻辑 - orderMapper.updateOrderStatus(orderId, OrderMapper.ORDER_STATUS_RETURNED, operator); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/OrderVerificationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/OrderVerificationServiceImpl.java deleted file mode 100644 index 18a35de33..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/OrderVerificationServiceImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.openhis.web.nurse.service.impl; - -import com.openhis.web.nurse.mapper.OrderMapper; -import com.openhis.web.nurse.service.OrderVerificationService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 医嘱校对业务实现 - * - * 修复 Bug #505:增加医嘱退回前置状态校验,拦截已发药/已执行/已计费医嘱的直接退回操作。 - * 严格遵循逆向闭环流程:退药申请 -> 药房确认退药 -> 状态回滚 -> 允许退回。 - */ -@Service -public class OrderVerificationServiceImpl implements OrderVerificationService { - - private final OrderMapper orderMapper; - - public OrderVerificationServiceImpl(OrderMapper orderMapper) { - this.orderMapper = orderMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void returnOrders(List orderIds) { - if (orderIds == null || orderIds.isEmpty()) { - throw new IllegalArgumentException("医嘱ID列表不能为空"); - } - - for (Long orderId : orderIds) { - validateReturnPreconditions(orderId); - } - - // 批量更新状态为已退回 - orderMapper.batchUpdateOrderStatus(orderIds, "RETURNED"); - } - - /** - * 核心状态约束校验 (Bug #505 修复) - * 护士能执行“退回”操作必须同时满足: - * 1. 执行状态:必须为“未执行” - * 2. 物理状态:必须为“未发药/未领药” - * 3. 财务状态:必须为“未计费” - */ - private void validateReturnPreconditions(Long orderId) { - Map order = orderMapper.selectOrderById(orderId); - if (order == null) { - throw new RuntimeException("医嘱不存在,orderId=" + orderId); - } - - String executionStatus = (String) order.get("execution_status"); - String dispensingStatus = (String) order.get("dispensing_status"); - String billingStatus = (String) order.get("billing_status"); - - if ("EXECUTED".equals(executionStatus)) { - throw new RuntimeException("该医嘱已执行,请先在【医嘱执行】模块取消执行"); - } - if ("DISPENSED".equals(dispensingStatus)) { - throw new RuntimeException("该药品已由药房发放,请先执行退药处理,不可直接退回"); - } - if ("BILLED".equals(billingStatus)) { - throw new RuntimeException("该医嘱已计费,请先撤销计费"); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/VitalSignServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/VitalSignServiceImpl.java deleted file mode 100644 index 242ec3d6b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/nurse/service/impl/VitalSignServiceImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.openhis.web.nurse.service.impl; - -import com.openhis.web.nurse.mapper.VitalSignMapper; -import com.openhis.web.nurse.service.VitalSignService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 生命体征业务实现 - * 修复 Bug #566:确保保存后数据可被正确查询,且时间轴排序一致。 - */ -@Service -public class VitalSignServiceImpl implements VitalSignService { - - private final VitalSignMapper vitalSignMapper; - - public VitalSignServiceImpl(VitalSignMapper vitalSignMapper) { - this.vitalSignMapper = vitalSignMapper; - } - - @Override - public List> getVitalSignsByPatient(String patientId) { - // 严格按记录时间升序返回,保障前端折线绘制顺序正确 - return vitalSignMapper.selectByPatientIdOrderByTime(patientId); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void saveVitalSign(Map signData) { - vitalSignMapper.insertVitalSign(signData); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/AppointmentController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/AppointmentController.java deleted file mode 100644 index d5e05f25f..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/AppointmentController.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.openhis.web.outpatient.controller; - -import com.openhis.web.outpatient.service.AppointmentService; -import org.springframework.web.bind.annotation.*; - -import java.util.Map; - -/** - * 门诊预约相关接口 - * - * 新增:/confirm 接口用于预约签到缴费成功后状态流转(Bug #574) - */ -@RestController -@RequestMapping("/api/outpatient/appointment") -public class AppointmentController { - - private final AppointmentService appointmentService; - - public AppointmentController(AppointmentService appointmentService) { - this.appointmentService = appointmentService; - } - - @PostMapping("/book") - public Map book(@RequestParam Long slotId, @RequestParam Long orderId) { - appointmentService.bookSlot(slotId, orderId); - return Map.of("success", true); - } - - /** - * 预约签到缴费成功后调用 - */ - @PostMapping("/confirm") - public Map confirm(@RequestParam Long slotId) { - appointmentService.confirmPaymentAndTake(slotId); - return Map.of("success", true); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java deleted file mode 100644 index 8ac3f5a99..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.openhis.web.outpatient.controller; - -import com.openhis.web.outpatient.service.CheckRequestService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import java.util.List; -import java.util.Map; - -/** - * 检查申请接口 - * - * 修复 Bug #550: - * 1. 前端已改为手动控制勾选,后端需要确保一次只能提交同一检查项目的唯一记录。 - * 2. 防止重复提交导致明细耦合,新增校验逻辑。 - */ -@RestController -@RequestMapping("/outpatient/check-requests") -public class CheckRequestController { - - @Autowired - private CheckRequestService checkRequestService; - - @GetMapping - public List> list() { - return checkRequestService.listPendingRequests(); - } - - @PostMapping("/submit") - public void submit(@RequestBody List> selected) { - // 校验:同一检查项目只能提交一次,且项目与方法解耦 - checkRequestService.validateAndSubmit(selected); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/MedicalRecordController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/MedicalRecordController.java deleted file mode 100644 index 1d3bb5863..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/MedicalRecordController.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.web.outpatient.controller; - -import com.openhis.web.outpatient.service.MedicalRecordService; -import com.openhis.web.outpatient.vo.PendingMedicalRecordVO; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * 门诊待写病历接口 - * - * 修复 Bug #562:新增分页参数,默认 pageNum=1, pageSize=20,前端可自行调整。 - */ -@RestController -public class MedicalRecordController { - - @Autowired - private MedicalRecordService medicalRecordService; - - @GetMapping("/api/outpatient/medical-records/pending") - public Map listPendingMedicalRecords( - @RequestParam(value = "pageNum", defaultValue = "1") int pageNum, - @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) { - - List records = medicalRecordService.getPendingMedicalRecords(pageNum, pageSize); - int total = medicalRecordService.getPendingMedicalRecordCount(); - - Map result = new HashMap<>(); - result.put("data", records); - result.put("total", total); - result.put("pageNum", pageNum); - result.put("pageSize", pageSize); - return result; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/OutpatientMedicalRecordController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/OutpatientMedicalRecordController.java deleted file mode 100644 index b30e95268..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/OutpatientMedicalRecordController.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.openhis.web.outpatient.controller; - -import com.openhis.web.outpatient.service.OutpatientMedicalRecordService; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.Map; - -@RestController -@RequestMapping("/api/outpatient/medical-records") -public class OutpatientMedicalRecordController { - - private final OutpatientMedicalRecordService medicalRecordService; - - public OutpatientMedicalRecordController(OutpatientMedicalRecordService medicalRecordService) { - this.medicalRecordService = medicalRecordService; - } - - @GetMapping("/pending") - public ResponseEntity> getPendingRecords( - @RequestParam Long doctorId, - @RequestParam(defaultValue = "1") int pageNum, - @RequestParam(defaultValue = "20") int pageSize) { - return ResponseEntity.ok(medicalRecordService.getPendingMedicalRecords(doctorId, pageNum, pageSize)); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/RegistrationController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/RegistrationController.java deleted file mode 100644 index d03426f1c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/RegistrationController.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.openhis.web.outpatient.controller; - -import com.openhis.web.outpatient.service.RegistrationService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping("/outpatient/registration") -public class RegistrationController { - - @Autowired - private RegistrationService registrationService; - - /** - * 诊前退号接口 - * - * @param registrationId 挂号主键 ID - * @return 操作结果信息 - */ - @PostMapping("/refund") - public String refund(@RequestParam Long registrationId) { - registrationService.refundRegistration(registrationId); - return "退号成功"; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveDTO.java deleted file mode 100644 index 7eb8b8a94..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveDTO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.dto; -public class DiagnosisSaveDTO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveRequest.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveRequest.java deleted file mode 100644 index 678d4de4a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveRequest.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.dto; -public class DiagnosisSaveRequest {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveResponse.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveResponse.java deleted file mode 100644 index bcaf2c9b1..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveResponse.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.dto; -public class DiagnosisSaveResponse {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveResult.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveResult.java deleted file mode 100644 index 90272c148..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/DiagnosisSaveResult.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.dto; -public class DiagnosisSaveResult {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/InfectiousDiseaseReportDTO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/InfectiousDiseaseReportDTO.java deleted file mode 100644 index e430fbd54..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/InfectiousDiseaseReportDTO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.dto; -public class InfectiousDiseaseReportDTO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/OrderCreateParam.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/OrderCreateParam.java deleted file mode 100644 index fa503c33b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/dto/OrderCreateParam.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.dto; -public class OrderCreateParam {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/entity/Diagnosis.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/entity/Diagnosis.java deleted file mode 100644 index 7ff6b3d06..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/entity/Diagnosis.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.entity; -public class Diagnosis {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/entity/OrderMain.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/entity/OrderMain.java deleted file mode 100644 index fe31769da..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/entity/OrderMain.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.entity; -public class OrderMain {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentMapper.java deleted file mode 100644 index fb6f67cc7..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentMapper.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.openhis.web.outpatient.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; - -/** - * 预约(his_appointment)数据访问层 - * - * 新增查询对应排班槽ID的方法,配合 Bug #574 的状态同步。 - */ -@Mapper -public interface AppointmentMapper { - - /** - * 检查预约是否可以缴费(状态为未缴费且未取消) - * - * @param appointmentId 预约ID - * @return 可缴费记录数 - */ - @Select("SELECT COUNT(1) FROM his_appointment WHERE id = #{appointmentId} AND pay_status = 0 AND cancel_flag = 0") - Integer checkCanPay(@Param("appointmentId") Long appointmentId); - - /** - * 更新预约的缴费信息 - * - * @param appointmentId 预约ID - * @param payAmount 实际缴费金额 - * @return 受影响行数 - */ - @Update("UPDATE his_appointment SET pay_status = 1, pay_amount = #{payAmount}, pay_time = NOW() WHERE id = #{appointmentId}") - int updatePaymentInfo(@Param("appointmentId") Long appointmentId, @Param("payAmount") Double payAmount); - - /** - * 根据预约ID查询对应的排班槽ID - * - * @param appointmentId 预约ID - * @return slotId(可能为 null) - */ - @Select("SELECT schedule_slot_id FROM his_appointment WHERE id = #{appointmentId}") - Long selectSlotIdByAppointmentId(@Param("appointmentId") Long appointmentId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentSlotMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentSlotMapper.java deleted file mode 100644 index 7dedadb14..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentSlotMapper.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.openhis.web.outpatient.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.List; -import java.util.Map; - -/** - * 门诊号源预约 Mapper - * 修复 Bug #570:规范号源状态流转,移除“已锁定”状态,确保预约成功后状态正确落库为 2(已预约) - * 新增:状态流转至已取号(3) 的接口,解决预约签到缴费成功后状态未及时流转的问题(Bug #574) - */ -@Mapper -public interface AppointmentSlotMapper { - - /** - * 预约成功后更新号源状态 - * 修复点:status 直接置为 2(已预约),绑定 order_id,移除历史遗留的 status=4(已锁定) 逻辑 - */ - @Update("UPDATE adm_schedule_slot SET status = 2, order_id = #{orderId}, update_time = NOW() " + - "WHERE id = #{slotId} AND status = 1") - int updateSlotToBooked(@Param("slotId") Long slotId, @Param("orderId") Long orderId); - - /** - * 预约签到缴费成功后,将号源状态流转为已取号(3) - * - * @param slotId 号源主键 - * @return 受影响行数 - */ - @Update("UPDATE adm_schedule_slot SET status = 3, update_time = NOW() " + - "WHERE id = #{slotId} AND status = 2") - int updateSlotToTaken(@Param("slotId") Long slotId); - - /** - * 根据状态查询号源列表 - * 修复点:支持按 status=2 精确查询,兼容前端“已预约”筛选条件 - */ - @Select("") - List> selectSlotsByStatus(@Param("status") Integer status); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/CatalogMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/CatalogMapper.java deleted file mode 100644 index 423d59ed0..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/CatalogMapper.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -/** - * 诊疗目录(Catalog)相关数据库操作 Mapper - * - * 该 Mapper 仅提供获取默认计量单位的查询,用于医嘱录入时的单位兜底。 - */ -@Mapper -public interface CatalogMapper { - - /** - * 根据诊疗目录 ID 查询其默认的计量单位(total_unit)。 - * - * @param catalogId 诊疗目录主键 ID - * @return 配置的计量单位字符串,若未配置则返回 null - */ - @Select("SELECT total_unit FROM adm_catalog WHERE id = #{catalogId}") - String selectDefaultUnitByCatalogId(@Param("catalogId") Long catalogId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java deleted file mode 100644 index bf10e97d9..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.*; -import java.util.List; -import java.util.Map; - -/** - * 检查申请数据访问层 - * - * 修复 Bug #550: - * - 新增 selectExistingItemCodes 用于校验冲突。 - * - 新增 batchInsertRequests 实现一次性插入,避免明细耦合。 - */ -@Mapper -public interface CheckRequestMapper { - - @Select("SELECT id, item_code AS itemCode, item_name AS itemName, spec, dept_name AS deptName, " + - "apply_doctor AS applyDoctor, apply_time AS applyTime " + - "FROM outpatient_check_request " + - "WHERE status = 0") // 待处理状态 - List> selectPendingRequests(); - - @Select("") - List selectExistingItemCodes(@Param("itemCodes") List itemCodes); - - @Insert("") - int batchInsertRequests(@Param("list") List> list); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/DiagnosisMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/DiagnosisMapper.java deleted file mode 100644 index 499134c96..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/DiagnosisMapper.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.mapper; -public interface DiagnosisMapper {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/DiseaseCatalogMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/DiseaseCatalogMapper.java deleted file mode 100644 index 297774271..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/DiseaseCatalogMapper.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.mapper; -public interface DiseaseCatalogMapper {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/InfectiousReportMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/InfectiousReportMapper.java deleted file mode 100644 index aaab5c166..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/InfectiousReportMapper.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.mapper; -public interface InfectiousReportMapper {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalOrderMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalOrderMapper.java deleted file mode 100644 index 44c7982a2..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalOrderMapper.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import com.openhis.web.outpatient.vo.MedicalOrderVO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; -import java.util.List; - -/** - * 门诊医嘱数据访问层 - * - * 修复 Bug #561: - * 原查询未关联诊疗目录表或未正确映射 usage_unit 字段,导致前端总量单位显示为 null。 - * 现显式 LEFT JOIN 诊疗目录表,并将 c.usage_unit 映射为 total_unit 返回。 - */ -@Mapper -public interface MedicalOrderMapper { - - /** - * 根据患者ID查询医嘱列表(含手术/检查/药品等) - * - * @param patientId 患者ID - * @return 医嘱VO列表 - */ - @Select("") - List selectOrdersByPatientId(@Param("patientId") Long patientId); - - /** - * 插入新医嘱 - */ - @Select("INSERT INTO his_medical_order (patient_id, catalog_id, total_quantity, status, create_time) " + - "VALUES (#{patientId}, #{catalogId}, #{totalQuantity}, 0, NOW())") - int insertOrder(@Param("patientId") Long patientId, - @Param("catalogId") Long catalogId, - @Param("totalQuantity") Integer totalQuantity); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalRecordMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalRecordMapper.java deleted file mode 100644 index f0e5298e1..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalRecordMapper.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import com.openhis.web.outpatient.vo.PendingMedicalRecordVO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -import java.util.List; - -/** - * 门诊待写病历数据访问层 - * - * 修复 Bug #562: - * 原始查询一次性返回全部待写病历,数据量大时导致接口响应时间 > 2 秒。 - * 通过引入分页参数 (offset, limit) 并使用索引字段 (status, create_time) 进行过滤, - * 大幅降低单次查询的数据量,提升加载速度。 - */ -@Mapper -public interface MedicalRecordMapper { - - /** - * 分页查询待写病历 - * - * @param offset 起始行号(从 0 开始) - * @param limit 每页记录数 - * @return 待写病历列表 - */ - @Select("") - List selectPendingMedicalRecords(@Param("status") Integer status, - @Param("offset") int offset, - @Param("limit") int limit); - - /** - * 统计待写病历总数(用于前端分页) - * - * @param status 病历状态,默认 0(待写) - * @return 总记录数 - */ - @Select("SELECT COUNT(1) FROM his_outpatient_medical_record WHERE status = #{status}") - int countPendingMedicalRecords(@Param("status") Integer status); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMainMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMainMapper.java deleted file mode 100644 index 8ac26a362..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMainMapper.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.mapper; -public interface OrderMainMapper {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java deleted file mode 100644 index 8ca10ed03..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.*; -import java.util.List; -import java.util.Map; - -/** - * 预约订单数据访问层 - * - * 新增更新支付状态的方法,供 OrderService.handlePaymentSuccess 使用。 - */ -@Mapper -public interface OrderMapper { - - // 其他已有方法省略... - - /** - * 更新预约订单的支付状态 - * - * @param orderId 预约订单ID - * @param status 支付状态(0: 未支付, 1: 已支付) - * @return 受影响的行数 - */ - @Update("UPDATE outpatient_schedule_order SET payment_status = #{status} WHERE id = #{orderId}") - int updatePaymentStatus(@Param("orderId") Long orderId, @Param("status") Integer status); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OutpatientOrderMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OutpatientOrderMapper.java deleted file mode 100644 index 4d1e699f0..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OutpatientOrderMapper.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import com.openhis.web.outpatient.vo.OrderVO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -import java.util.List; - -/** - * 门诊医嘱数据访问层 - * 修复 Bug #561:关联诊疗目录表获取 usage_unit,解决总量单位显示 null 问题 - */ -@Mapper -public interface OutpatientOrderMapper { - - /** - * 根据患者ID查询医嘱列表 - * - * @param patientId 患者ID - * @return 医嘱VO列表 - */ - @Select("SELECT o.id, o.patient_id, o.catalog_id, o.total_quantity, " + - "c.usage_unit AS total_unit, c.name AS item_name " + - "FROM his_outpatient_order o " + - "LEFT JOIN his_medical_catalog c ON o.catalog_id = c.id " + - "WHERE o.patient_id = #{patientId} AND o.status = 0") - List selectOrdersByPatientId(@Param("patientId") Long patientId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/PatientProfileMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/PatientProfileMapper.java deleted file mode 100644 index 38cb34254..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/PatientProfileMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -import java.util.Map; - -/** - * 患者档案数据库操作 Mapper - */ -@Mapper -public interface PatientProfileMapper { - - /** - * Bug #572 Fix: 查询患者档案中的现住址与职业信息 - * 用于传染病报告卡初始化时自动填充 - * - * @param patientId 患者主键ID - * @return 包含 current_address 和 occupation 的 Map - */ - @Select("SELECT current_address, occupation FROM hisdev.patient_profile WHERE patient_id = #{patientId}") - Map selectAddressAndOccupationByPatientId(@Param("patientId") Long patientId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationCancelMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationCancelMapper.java deleted file mode 100644 index 7bc6a1570..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationCancelMapper.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.Insert; -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.math.BigDecimal; -import java.util.Map; - -/** - * 门诊退号数据访问层 - * 修复 Bug #506:修正退号流程中多表状态更新 SQL,对齐 PRD 定义 - */ -@Mapper -public interface RegistrationCancelMapper { - - /** - * 查询号源关联的排班池ID - */ - @Select("SELECT id, pool_id, status, order_id FROM adm_schedule_slot WHERE order_id = #{orderId} LIMIT 1") - Map selectSlotByOrderId(@Param("orderId") Long orderId); - - /** - * 更新订单主表状态 - * 修复点:status=0, pay_status=3, cancel_time=NOW(), cancel_reason='诊前退号' - */ - @Update("UPDATE order_main " + - "SET status = 0, " + - " pay_status = 3, " + - " cancel_time = NOW(), " + - " cancel_reason = '诊前退号' " + - "WHERE id = #{orderId}") - int updateOrderStatus(@Param("orderId") Long orderId); - - /** - * 回滚号源状态 - * 修复点:status=0(待约), order_id=NULL,释放号源供再次预约 - */ - @Update("UPDATE adm_schedule_slot " + - "SET status = 0, " + - " order_id = NULL " + - "WHERE order_id = #{orderId}") - int rollbackSlotStatus(@Param("orderId") Long orderId); - - /** - * 更新排班池版本与已约数 - * 修复点:version=version+1, booked_num=booked_num-1(修正此前版本中两者写反的问题) - */ - @Update("UPDATE adm_schedule_pool " + - "SET version = version + 1, " + - " booked_num = booked_num - 1 " + - "WHERE id = #{poolId}") - int updatePoolVersion(@Param("poolId") Long poolId); - - /** - * 插入退费日志 - * 修复点:order_id 严格取值于 order_main.id,确保后台业务数据可追溯关联 - */ - @Insert("INSERT INTO refund_log (order_id, refund_amount, refund_time, status) " + - "VALUES (#{orderId}, #{amount}, NOW(), 1)") - int insertRefundLog(@Param("orderId") Long orderId, @Param("amount") BigDecimal amount); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationMapper.java deleted file mode 100644 index df592d3b9..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationMapper.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Update; - -/** - * 门诊挂号数据访问层 - * - * 修复 Bug #506: - * 退号需严格遵循 PRD 定义同步更新多表状态。 - * 1. order_main: status=0(已取消), pay_status=3(已退费), cancel_time=当前时间, cancel_reason='诊前退号' - * 2. adm_schedule_slot: status=0(待约), order_id=NULL(释放号源) - * 3. adm_schedule_pool: version=version+1, booked_num=booked_num-1(修正此前版本与预约数搞反的问题) - * 4. refund_log: 正确关联 order_main.id - * 使用 PostgreSQL 原生 NOW() 确保 cancel_time 时分秒精准,避免旧版时间截取错误。 - * - * 新增: - * 预约挂号缴费成功后,需要将对应的排班槽状态更新为 “3”(已取号)。 - * 该方法在支付成功的业务流程中调用,确保状态及时流转。 - */ -@Mapper -public interface RegistrationMapper { - - /** - * 统一退号(诊前退号)SQL。 - * - * @param orderId 挂号订单主键 ID (order_main.id) - * @param poolId 排班池主键 ID (adm_schedule_pool.id) - * @return 受影响的行数 - */ - @Update({ - "" - }) - int cancelRegistration(@Param("orderId") Long orderId, @Param("poolId") Long poolId); - - /** - * 旧的单表状态更新(已废弃,仅为兼容历史代码)。 - * - * @param registrationId 挂号主键 ID - * @param status 新状态值 - * @return 受影响行数 - */ - @Update("UPDATE his_outpatient_registration SET status = #{status} WHERE id = #{registrationId}") - int updateStatus(@Param("registrationId") Long registrationId, @Param("status") Integer status); - - /** - * 预约挂号缴费成功后,更新对应排班槽状态为 “3”(已取号)。 - * - * @param orderId 挂号订单主键 ID (order_main.id) - * @return 受影响的行数 - */ - @Update("UPDATE adm_schedule_slot SET status = 3 WHERE order_id = #{orderId}") - int updateSlotStatusToTaken(@Param("orderId") Long orderId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/ReportCardMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/ReportCardMapper.java deleted file mode 100644 index 231c4528e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/ReportCardMapper.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.mapper; -public interface ReportCardMapper {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/ScheduleMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/ScheduleMapper.java deleted file mode 100644 index 05c3c35f0..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/ScheduleMapper.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.*; -import java.util.Map; - -/** - * 预约挂号排班槽数据访问层 - * - * 修复 Bug #574: - * 预约签到缴费成功后,数据库表 adm_schedule_slot.status 未及时流转为 “3”(已取号)。 - * 原因是支付成功后仅更新了订单表的状态,未同步更新对应的排班槽状态。 - * 新增 updateSlotStatusByOrderId 方法,在支付成功的业务流程中调用, - * 将对应的 adm_schedule_slot.status 更新为 3,确保前端能够正确获取已取号状态。 - */ -@Mapper -public interface ScheduleMapper { - - /** - * 根据预约订单ID查询对应的排班槽ID - * - * @param orderId 预约订单ID - * @return 排班槽ID - */ - @Select("SELECT slot_id FROM outpatient_schedule_order WHERE id = #{orderId}") - Long selectSlotIdByOrderId(@Param("orderId") Long orderId); - - /** - * 更新排班槽状态为已取号(status = 3) - * - * @param slotId 排班槽ID - * @return 受影响的行数 - */ - @Update("UPDATE adm_schedule_slot SET status = 3 WHERE id = #{slotId}") - int updateSlotStatus(@Param("slotId") Long slotId); - - /** - * 支付成功后调用,依据订单ID直接将对应排班槽状态置为已取号 - * - * @param orderId 预约订单ID - * @return 受影响的行数 - * - * 实现思路: - * 1. 通过 orderId 查询对应的 slot_id(使用 selectSlotIdByOrderId)。 - * 2. 若 slot_id 不为空,执行 updateSlotStatus 将 status 设置为 3。 - * 3. 返回更新结果,供业务层判断是否成功。 - * - * 该方法在业务层(如 OrderService.paymentSuccess)中调用,确保 - * 预约签到缴费成功后,adm_schedule_slot.status 能够及时流转为 “3”(已取号)。 - */ - default int updateSlotStatusByOrderId(@Param("orderId") Long orderId) { - Long slotId = selectSlotIdByOrderId(orderId); - if (slotId == null) { - return 0; - } - return updateSlotStatus(slotId); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/ScheduleSlotMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/ScheduleSlotMapper.java deleted file mode 100644 index e9560da85..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/ScheduleSlotMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Update; - -/** - * 排班槽(adm_schedule_slot)数据访问层 - * - * 新增方法用于更新槽状态,修复 Bug #574。 - */ -@Mapper -public interface ScheduleSlotMapper { - - /** - * 更新排班槽状态 - * - * @param slotId 槽ID - * @param status 新状态值(3 表示已取号) - * @return 受影响的行数 - */ - @Update("UPDATE adm_schedule_slot SET status = #{status} WHERE id = #{slotId}") - int updateSlotStatus(@Param("slotId") Long slotId, @Param("status") Integer status); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/TriageQueueMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/TriageQueueMapper.java deleted file mode 100644 index 754e5deb6..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/TriageQueueMapper.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.web.outpatient.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 #544: - * 1. 移除原 SQL 中隐式过滤 `status != '完诊'` 的条件,确保全流程状态可追溯; - * 2. 增加按分诊时间范围查询的参数支持,配合前端实现历史队列检索。 - */ -@Mapper -public interface TriageQueueMapper { - - /** - * 查询分诊排队队列列表 - * - * @param startDate 开始日期 (YYYY-MM-DD) - * @param endDate 结束日期 (YYYY-MM-DD) - * @return 队列记录列表 - */ - @Select("") - List> getQueueList(@Param("startDate") String startDate, @Param("endDate") String endDate); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/AppointmentService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/AppointmentService.java deleted file mode 100644 index 274aa6a07..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/AppointmentService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.outpatient.service; - -public interface AppointmentService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/AppointmentServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/AppointmentServiceImpl.java deleted file mode 100644 index bc172ce53..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/AppointmentServiceImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.openhis.web.outpatient.service; - -import com.openhis.web.outpatient.mapper.AppointmentSlotMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * 门诊预约服务实现 - * 修复 Bug #570:简化预约状态流转,确保事务内直接落库为“已预约”状态 - * 新增:预约签到缴费成功后状态流转为“已取号”(3) 的业务(Bug #574) - */ -@Service -public class AppointmentServiceImpl implements AppointmentService { - - private final AppointmentSlotMapper slotMapper; - - public AppointmentServiceImpl(AppointmentSlotMapper slotMapper) { - this.slotMapper = slotMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void bookSlot(Long slotId, Long orderId) { - if (slotId == null || orderId == null) { - throw new IllegalArgumentException("预约核心参数缺失:slotId, orderId 均不可为空"); - } - - // 修复 Bug #570:直接更新为已预约(2),不再经过中间态或错误状态 - int updated = slotMapper.updateSlotToBooked(slotId, orderId); - if (updated == 0) { - throw new RuntimeException("号源状态异常或已被他人预约,请刷新后重试"); - } - } - - /** - * 预约签到缴费成功后调用,完成状态流转至已取号(3) - * - * @param slotId 号源主键 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void confirmPaymentAndTake(Long slotId) { - if (slotId == null) { - throw new IllegalArgumentException("号源ID不能为空"); - } - int updated = slotMapper.updateSlotToTaken(slotId); - if (updated == 0) { - throw new RuntimeException("号源状态异常,可能未完成预约或已被其他操作修改"); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/CheckRequestService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/CheckRequestService.java deleted file mode 100644 index a051fe9a3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/CheckRequestService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.openhis.web.outpatient.service; - -import java.util.List; -import java.util.Map; - -public interface CheckRequestService { - List> listPendingRequests(); - void validateAndSubmit(List> selected); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/DiagnosisService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/DiagnosisService.java deleted file mode 100644 index 64e0e0112..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/DiagnosisService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.outpatient.service; - -public interface DiagnosisService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/DiagnosisServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/DiagnosisServiceImpl.java deleted file mode 100644 index e10d03aa4..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/DiagnosisServiceImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.openhis.web.outpatient.service; - -import com.openhis.web.outpatient.mapper.DiagnosisMapper; -import com.openhis.web.outpatient.mapper.DiseaseCatalogMapper; -import com.openhis.web.outpatient.mapper.InfectiousReportMapper; -import com.openhis.web.outpatient.dto.DiagnosisSaveRequest; -import com.openhis.web.outpatient.dto.DiagnosisSaveResponse; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * 门诊诊断服务实现 - * 修复 Bug #573:保存诊断时自动校验并返回需上报的传染病列表,触发前端弹窗 - */ -@Service -public class DiagnosisServiceImpl implements DiagnosisService { - - private final DiagnosisMapper diagnosisMapper; - private final DiseaseCatalogMapper diseaseCatalogMapper; - private final InfectiousReportMapper infectiousReportMapper; - - public DiagnosisServiceImpl(DiagnosisMapper diagnosisMapper, - DiseaseCatalogMapper diseaseCatalogMapper, - InfectiousReportMapper infectiousReportMapper) { - this.diagnosisMapper = diagnosisMapper; - this.diseaseCatalogMapper = diseaseCatalogMapper; - this.infectiousReportMapper = infectiousReportMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public DiagnosisSaveResponse saveDiagnosis(DiagnosisSaveRequest request) { - // 1. 持久化诊断数据 - diagnosisMapper.batchInsert(request.getDiagnosisList()); - - // 2. 修复 Bug #573:遍历本次保存的诊断,校验报卡配置与历史记录 - List> needReportList = new ArrayList<>(); - if (request.getDiagnosisList() != null) { - for (Map diag : request.getDiagnosisList()) { - Long diseaseId = (Long) diag.get("diseaseId"); - String diseaseName = (String) diag.get("diseaseName"); - - // 查询疾病目录是否配置了报卡类型 - String reportType = diseaseCatalogMapper.selectReportTypeByDiseaseId(diseaseId); - - if (reportType != null && !reportType.trim().isEmpty()) { - // 保留现系统规则:若已存在对应报卡记录,则跳过弹窗 - int existingCount = infectiousReportMapper.countByPatientAndDisease( - request.getPatientId(), request.getVisitId(), diseaseId); - - if (existingCount == 0) { - needReportList.add(Map.of( - "diseaseId", diseaseId, - "diseaseName", diseaseName, - "reportType", reportType - )); - } - } - } - } - - // 3. 返回保存结果及需报卡数据,供前端判断是否弹窗 - return new DiagnosisSaveResponse(true, "诊断已保存并按排序号排序", needReportList); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/InfectiousDiseaseReportService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/InfectiousDiseaseReportService.java deleted file mode 100644 index 86f9439cd..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/InfectiousDiseaseReportService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.outpatient.service; - -public interface InfectiousDiseaseReportService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/InfectiousDiseaseReportServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/InfectiousDiseaseReportServiceImpl.java deleted file mode 100644 index 5a312f44b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/InfectiousDiseaseReportServiceImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.openhis.web.outpatient.service; - -import com.openhis.web.outpatient.dto.InfectiousDiseaseReportDTO; -import com.openhis.web.outpatient.mapper.PatientProfileMapper; -import org.springframework.stereotype.Service; - -import java.util.Map; - -/** - * 传染病报告卡服务实现 - */ -@Service -public class InfectiousDiseaseReportServiceImpl implements InfectiousDiseaseReportService { - - private final PatientProfileMapper patientProfileMapper; - - public InfectiousDiseaseReportServiceImpl(PatientProfileMapper patientProfileMapper) { - this.patientProfileMapper = patientProfileMapper; - } - - /** - * Bug #572 Fix: 初始化传染病报告卡数据 - * 原逻辑未关联患者档案表,导致现住址与职业字段为空。 - * 现补充档案查询逻辑,自动映射至报卡 DTO。 - */ - @Override - public InfectiousDiseaseReportDTO initReportCard(Long patientId) { - if (patientId == null) { - throw new IllegalArgumentException("患者ID不能为空"); - } - - InfectiousDiseaseReportDTO report = new InfectiousDiseaseReportDTO(); - report.setPatientId(patientId); - - // 自动同步患者档案中的现住址与职业 - Map profile = patientProfileMapper.selectAddressAndOccupationByPatientId(patientId); - if (profile != null) { - report.setCurrentAddress(profile.get("current_address")); - report.setOccupation(profile.get("occupation")); - } - - return report; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/MedicalRecordService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/MedicalRecordService.java deleted file mode 100644 index 12d1768f9..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/MedicalRecordService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.outpatient.service; - -public interface MedicalRecordService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OrderMainService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OrderMainService.java deleted file mode 100644 index c21ec4566..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OrderMainService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.outpatient.service; - -public interface OrderMainService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OrderMainServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OrderMainServiceImpl.java deleted file mode 100644 index 186d00446..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OrderMainServiceImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.openhis.web.outpatient.service; - -import com.openhis.web.outpatient.dto.OrderCreateParam; -import com.openhis.web.outpatient.entity.OrderMain; -import com.openhis.web.outpatient.mapper.OrderMainMapper; -import com.openhis.web.outpatient.mapper.CatalogMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; - -/** - * 门诊医嘱主表业务实现 - */ -@Service -public class OrderMainServiceImpl implements OrderMainService { - - private final OrderMainMapper orderMainMapper; - private final CatalogMapper catalogMapper; // 新增:用于获取诊疗目录配置的默认计量单位 - - public OrderMainServiceImpl(OrderMainMapper orderMainMapper, - CatalogMapper catalogMapper) { - this.orderMainMapper = orderMainMapper; - this.catalogMapper = catalogMapper; - } - - /** - * 创建医嘱主记录 - * - * @param param 前端提交的医嘱创建参数 - * @return 是否创建成功 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public boolean createOrder(OrderCreateParam param) { - OrderMain order = new OrderMain(); - order.setPatientId(param.getPatientId()); - order.setDoctorId(param.getDoctorId()); - order.setDeptId(param.getDeptId()); - order.setCatalogId(param.getCatalogId()); - order.setQuantity(param.getQuantity()); - order.setCreateTime(LocalDateTime.now()); - - // ---------- 修复点 ---------- - // 之前在保存医嘱时直接使用前端传入的 totalUnit,若前端未传或传入 null, - // 页面会显示 “null”。这里改为在数据库层面兜底:如果前端未提供 totalUnit, - // 则从诊疗目录(catalog)表中读取配置的默认计量单位并填充。 - // 这样即使前端忘记传值,也能保证页面展示正确的单位。 - // ---------- - String totalUnit = param.getTotalUnit(); - if (totalUnit == null || totalUnit.trim().isEmpty()) { - // 通过 catalogId 查询诊疗目录的默认计量单位 - totalUnit = catalogMapper.selectDefaultUnitByCatalogId(param.getCatalogId()); - } - order.setTotalUnit(totalUnit); - - // 其余字段保持不变 - int affected = orderMainMapper.insert(order); - return affected == 1; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OrderService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OrderService.java deleted file mode 100644 index 2095a973d..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OrderService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.outpatient.service; - -public interface OrderService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OutpatientDiagnosisService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OutpatientDiagnosisService.java deleted file mode 100644 index 78e53a888..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OutpatientDiagnosisService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.outpatient.service; - -public interface OutpatientDiagnosisService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OutpatientDiagnosisServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OutpatientDiagnosisServiceImpl.java deleted file mode 100644 index 90b0c8d99..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OutpatientDiagnosisServiceImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.openhis.web.outpatient.service; - -import com.openhis.web.outpatient.dto.DiagnosisSaveDTO; -import com.openhis.web.outpatient.dto.DiagnosisSaveResult; -import com.openhis.web.outpatient.entity.Diagnosis; -import com.openhis.web.outpatient.mapper.DiagnosisMapper; -import com.openhis.web.outpatient.mapper.DiseaseCatalogMapper; -import com.openhis.web.outpatient.mapper.ReportCardMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -/** - * 门诊诊断服务实现 - * 负责门诊医生工作站的诊断录入、保存及关联业务触发 - */ -@Service -public class OutpatientDiagnosisServiceImpl implements OutpatientDiagnosisService { - - private final DiagnosisMapper diagnosisMapper; - private final DiseaseCatalogMapper diseaseCatalogMapper; - private final ReportCardMapper reportCardMapper; - - public OutpatientDiagnosisServiceImpl(DiagnosisMapper diagnosisMapper, - DiseaseCatalogMapper diseaseCatalogMapper, - ReportCardMapper reportCardMapper) { - this.diagnosisMapper = diagnosisMapper; - this.diseaseCatalogMapper = diseaseCatalogMapper; - this.reportCardMapper = reportCardMapper; - } - - /** - * Bug #573 Fix: 保存诊断并自动校验报卡类型 - * 逻辑: - * 1. 持久化诊断数据 - * 2. 遍历有效诊断,查询疾病目录配置的【报卡类型】 - * 3. 校验该患者/就诊次是否已存在对应报卡记录(防重复弹窗) - * 4. 将需上报的疾病信息返回前端,由前端触发弹窗 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public DiagnosisSaveResult saveDiagnoses(DiagnosisSaveDTO dto) { - // 1. 保存/更新诊断数据 - List savedDiagnoses = diagnosisMapper.batchInsertOrUpdate(dto.getDiagnoses()); - - // 2. 校验报卡类型并过滤已存在的报卡 - List pendingCards = new ArrayList<>(); - for (Diagnosis diag : savedDiagnoses) { - // 仅处理有效诊断 - if (diag.getIsValid() != null && diag.getIsValid()) { - // 查询疾病目录配置的报卡类型 - String reportType = diseaseCatalogMapper.selectReportCardTypeByDiseaseId(diag.getDiseaseId()); - - if (reportType != null && !reportType.trim().isEmpty()) { - // 保留现系统校验规则:若已存在对应报卡记录,则不重复触发 - boolean exists = reportCardMapper.existsByPatientAndDisease( - dto.getPatientId(), - dto.getVisitId(), - diag.getDiseaseId(), - reportType - ); - if (!exists) { - pendingCards.add(new DiagnosisSaveResult.PendingReportCard( - diag.getDiseaseId(), - diag.getDiseaseName(), - reportType - )); - } - } - } - } - - return new DiagnosisSaveResult(true, "诊断已保存并按排序号排序", pendingCards); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OutpatientMedicalRecordService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OutpatientMedicalRecordService.java deleted file mode 100644 index 4203d0745..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/OutpatientMedicalRecordService.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.openhis.web.outpatient.service; - -import java.util.Map; - -public interface OutpatientMedicalRecordService { - /** - * 分页获取待写病历数据 - */ - Map getPendingMedicalRecords(Long doctorId, int pageNum, int pageSize); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/RegistrationCancelService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/RegistrationCancelService.java deleted file mode 100644 index ecfd45167..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/RegistrationCancelService.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.openhis.web.outpatient.service; - -import java.math.BigDecimal; - -/** - * 门诊挂号退号业务接口 - * 修复 Bug #506:规范诊前退号后的多表状态变更逻辑 - */ -public interface RegistrationCancelService { - - /** - * 执行门诊诊前退号操作 - * - * @param orderId 挂号订单ID (order_main.id) - * @param refundAmount 退费金额 - */ - void cancelRegistration(Long orderId, BigDecimal refundAmount); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/RegistrationCancelServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/RegistrationCancelServiceImpl.java deleted file mode 100644 index 3420b22ae..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/RegistrationCancelServiceImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.openhis.web.outpatient.service; - -import com.openhis.web.outpatient.mapper.RegistrationCancelMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.math.BigDecimal; - -/** - * 门诊挂号退号服务实现 - * 修复 Bug #506:重构退号事务逻辑,确保多表状态原子性变更与 PRD 定义完全一致 - */ -@Service -public class RegistrationCancelServiceImpl implements RegistrationCancelService { - - private final RegistrationCancelMapper cancelMapper; - - public RegistrationCancelServiceImpl(RegistrationCancelMapper cancelMapper) { - this.cancelMapper = cancelMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void cancelRegistration(Long orderId, Long slotId, Long poolId, BigDecimal refundAmount, String operator) { - if (orderId == null || slotId == null || poolId == null) { - throw new IllegalArgumentException("退号核心参数缺失:orderId, slotId, poolId 均不可为空"); - } - - // 1. 更新订单主表:状态置为已取消(2),支付状态置为已退费(2),记录精准取消时间与标准原因 - cancelMapper.updateOrderStatus(orderId); - - // 2. 记录退费日志:强制关联 order_main.id,打通财务对账数据链 - cancelMapper.insertRefundLog(orderId, refundAmount, operator); - - // 3. 释放号源:状态回滚至待约(1),清空关联订单ID,允许号源重新进入预约池 - cancelMapper.rollbackSlotStatus(slotId); - - // 4. 更新号源池:已约数减1,乐观锁版本号加1,防止并发超卖并修正历史版本字段错位问题 - cancelMapper.updatePoolVersionAndBookedNum(poolId); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/RegistrationService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/RegistrationService.java deleted file mode 100644 index be4983aaf..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/RegistrationService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.outpatient.service; - -public interface RegistrationService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/TriageQueueService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/TriageQueueService.java deleted file mode 100644 index 365ef7304..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/TriageQueueService.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.service; -public interface TriageQueueService {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/AppointmentServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/AppointmentServiceImpl.java deleted file mode 100644 index 119bc77dd..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/AppointmentServiceImpl.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.AppointmentMapper; -import com.openhis.web.outpatient.mapper.OrderMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * 预约挂号业务实现 - * - * 修复 Bug #506: - * 门诊诊前退号后,涉及的多表状态未按 PRD 定义同步更新,导致前端显示异常。 - * 现在在取消预约的业务路径中统一处理: - * 1. 将订单状态置为 “已取消”(4)。 - * 2. 将对应的 adm_schedule_slot.status 设回 “1”(可预约)。 - * 3. 将对应的 adm_schedule_pool.booked_num 递减 1。 - * - * 同时保持原有支付成功后的状态同步逻辑不变。 - */ -@Service -public class AppointmentServiceImpl { - - @Autowired - private OrderMapper orderMapper; - - @Autowired - private AppointmentMapper appointmentMapper; - - /** - * 预约缴费成功后调用。 - * - * @param orderId 预约订单ID - * @param slotId 对应的排班时段ID - */ - @Transactional(rollbackFor = Exception.class) - public void handlePaymentSuccess(Long orderId, Long slotId) { - // 1. 更新订单支付状态为 “已缴费”(2) - int orderUpdated = orderMapper.updatePayStatus(orderId, 2); - if (orderUpdated != 1) { - throw new IllegalStateException("Failed to update payment status for orderId: " + orderId); - } - - // 2. 将排班时段状态更新为已取号(3) - int slotUpdated = appointmentMapper.updateSlotStatus(slotId, 3); - if (slotUpdated != 1) { - throw new IllegalStateException("Failed to update slot status for slotId: " + slotId); - } - - // 3. 累加排班池已预约人数(已在支付成功时递增) - // 此处假设 slot 与 pool 已经关联,业务层可自行获取 poolId 并调用 - // appointmentMapper.updateBookedNum(poolId, 1); - } - - /** - * 门诊诊前退号(取消预约)处理。 - * - * @param orderId 预约订单ID - * @param slotId 对应的排班时段ID - * @param poolId 对应的排班池ID(用于 booked_num 调整) - */ - @Transactional(rollbackFor = Exception.class) - public void cancelPreRegistration(Long orderId, Long slotId, Long poolId) { - // 1. 将订单状态更新为 “已取消”(4) - int orderUpdated = orderMapper.updateOrderStatus(orderId, 4); - if (orderUpdated != 1) { - throw new IllegalStateException("Failed to cancel orderId: " + orderId); - } - - // 2. 将排班时段状态恢复为 “可预约”(1) - int slotUpdated = appointmentMapper.updateSlotStatus(slotId, 1); - if (slotUpdated != 1) { - throw new IllegalStateException("Failed to reset slot status for slotId: " + slotId); - } - - // 3. 已预约人数递减 1,防止 booked_num 超出实际可用数 - int poolUpdated = appointmentMapper.updateBookedNum(poolId, -1); - if (poolUpdated != 1) { - throw new IllegalStateException("Failed to decrement booked_num for poolId: " + poolId); - } - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/CheckRequestServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/CheckRequestServiceImpl.java deleted file mode 100644 index 102ac7cde..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/CheckRequestServiceImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.CheckRequestMapper; -import com.openhis.web.outpatient.service.CheckRequestService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * 检查申请业务实现 - * - * 修复 Bug #550: - * - 在提交前校验同一检查项目(item_code)是否已存在未完成的申请,防止自动勾选冲突。 - * - 通过一次 INSERT 完成明细保存,避免前端明细与后端耦合。 - */ -@Service -public class CheckRequestServiceImpl implements CheckRequestService { - - @Autowired - private CheckRequestMapper checkRequestMapper; - - @Override - public List> listPendingRequests() { - return checkRequestMapper.selectPendingRequests(); - } - - /** - * 校验并提交检查申请 - * - * @param selected 前端选中的检查项目列表 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void validateAndSubmit(List> selected) { - if (selected == null || selected.isEmpty()) { - return; - } - - // 1. 检查前端是否传入了重复的 item_code - List duplicateCodes = selected.stream() - .collect(Collectors.groupingBy(item -> (String) item.get("itemCode"))) - .entrySet().stream() - .filter(e -> e.getValue().size() > 1) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - if (!duplicateCodes.isEmpty()) { - throw new IllegalArgumentException("同一检查项目不能重复选择:" + duplicateCodes); - } - - // 2. 检查数据库中是否已有未完成的相同项目 - List itemCodes = selected.stream() - .map(item -> (String) item.get("itemCode")) - .collect(Collectors.toList()); - - List existing = checkRequestMapper.selectExistingItemCodes(itemCodes); - if (!existing.isEmpty()) { - throw new IllegalArgumentException("以下项目已存在未完成的申请,请勿重复提交:" + existing); - } - - // 3. 保存申请(项目与方法解耦存储) - checkRequestMapper.batchInsertRequests(selected); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/MedicalRecordServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/MedicalRecordServiceImpl.java deleted file mode 100644 index c1032d17b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/MedicalRecordServiceImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.MedicalRecordMapper; -import com.openhis.web.outpatient.service.MedicalRecordService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import java.util.List; -import java.util.Map; - -/** - * 门诊病历业务实现 - * - * 修复 Bug #562:对接优化后的 Mapper,确保待写病历接口响应时间 < 2s。 - */ -@Service -public class MedicalRecordServiceImpl implements MedicalRecordService { - - @Autowired - private MedicalRecordMapper medicalRecordMapper; - - @Override - public List> getPendingRecords(Long doctorId) { - return medicalRecordMapper.selectPendingRecordsByDoctorId(doctorId); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/OrderServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/OrderServiceImpl.java deleted file mode 100644 index 58cb3c33d..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/OrderServiceImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.OrderMapper; -import com.openhis.web.outpatient.service.OrderService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * 门诊医嘱业务实现 - * - * 修复 Bug #506: - * 门诊诊前退号后,医嘱主表、支付状态以及取消时间等字段未按照 PRD - * 中的定义进行更新,导致状态值与生产环境不一致。 - * - * 解决方案: - * 1. 在退号业务中统一使用 OrderMapper 中新增的常量 - * {@link OrderMapper#ORDER_STATUS_CANCELLED}(值 0)和 - * {@link OrderMapper#ORDER_PAY_STATUS_REFUNDED}(值 3)。 - * 2. 调用新增的 {@link OrderMapper#updateOrderMainForCancellation(Long, int, int)} 方法, - * 该方法一次性完成 status、pay_status、cancel_time、cancel_reason - * 的更新,确保数据库状态与 PRD 完全一致。 - * - * 同时,新增对预约挂号缴费成功后排班号状态的更新,以修复 Bug #574。 - * - * 该实现依赖 OrderMapper 中已添加的常量和 SQL。 - */ -@Service -public class OrderServiceImpl implements OrderService { - - @Autowired - private OrderMapper orderMapper; - - /** - * 诊前退号(取消医嘱) - * - * @param orderId 医嘱主键 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void cancelOrderPre(Long orderId) { - // 使用统一常量更新医嘱状态 - orderMapper.updateOrderMainForCancellation( - orderId, - OrderMapper.ORDER_STATUS_CANCELLED, - OrderMapper.ORDER_PAY_STATUS_REFUNDED); - } - - /** - * 预约挂号缴费成功后调用,更新对应排班号状态为已取号(status=3)。 - * - * @param scheduleSlotId 对应排班号主键 - */ - @Transactional(rollbackFor = Exception.class) - public void afterAppointmentPaymentSuccess(Long scheduleSlotId) { - // 将排班号状态更新为已取号(3),修复 Bug #574 - orderMapper.updateScheduleSlotStatus( - scheduleSlotId, - OrderMapper.SLOT_STATUS_TAKEN); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/OutpatientMedicalRecordServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/OutpatientMedicalRecordServiceImpl.java deleted file mode 100644 index b17490a67..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/OutpatientMedicalRecordServiceImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.OrderMapper; -import com.openhis.web.outpatient.service.OutpatientMedicalRecordService; -import org.springframework.stereotype.Service; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Service -public class OutpatientMedicalRecordServiceImpl implements OutpatientMedicalRecordService { - - private final OrderMapper orderMapper; - - public OutpatientMedicalRecordServiceImpl(OrderMapper orderMapper) { - this.orderMapper = orderMapper; - } - - @Override - public Map getPendingMedicalRecords(Long doctorId, int pageNum, int pageSize) { - int offset = (pageNum - 1) * pageSize; - List> records = orderMapper.selectPendingMedicalRecords(doctorId, pageSize, offset); - int total = orderMapper.countPendingMedicalRecords(doctorId); - - Map result = new HashMap<>(); - result.put("records", records); - result.put("total", total); - result.put("pageNum", pageNum); - result.put("pageSize", pageSize); - return result; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationCancelServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationCancelServiceImpl.java deleted file mode 100644 index d2aea4ea5..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationCancelServiceImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.RegistrationCancelMapper; -import com.openhis.web.outpatient.service.RegistrationCancelService; -import com.openhis.web.inpatient.mapper.OrderMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.Map; - -/** - * 门诊挂号退号业务实现 - * 修复 Bug #506:确保退号后 order_main、adm_schedule_slot、adm_schedule_pool、refund_log 状态与 PRD 严格一致 - * 以及在退号后统一调用 {@link OrderMapper#updateOrderStatusToCancelled} 将医嘱状态置为 PRD 定义的 “CANCELLED”。 - */ -@Service -public class RegistrationCancelServiceImpl implements RegistrationCancelService { - - private final RegistrationCancelMapper cancelMapper; - private final OrderMapper orderMapper; - - public RegistrationCancelServiceImpl(RegistrationCancelMapper cancelMapper, - OrderMapper orderMapper) { - this.cancelMapper = cancelMapper; - this.orderMapper = orderMapper; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void cancelRegistration(Long orderId, BigDecimal refundAmount) { - if (orderId == null) { - throw new IllegalArgumentException("订单ID不能为空"); - } - - // 1. 更新 order_main 状态:status=0(已取消), pay_status=3(已退费), cancel_time=当前时间, cancel_reason='诊前退号' - int orderUpdated = cancelMapper.updateOrderStatus(orderId); - if (orderUpdated == 0) { - throw new RuntimeException("订单状态更新失败,请检查订单是否存在或已退号"); - } - - // 2. 将关联的医嘱状态更新为 PRD 定义的 “CANCELLED” - int orderStatusUpdated = orderMapper.updateOrderStatusToCancelled(orderId, OrderMapper.ORDER_STATUS_CANCELLED); - if (orderStatusUpdated == 0) { - // 若医嘱状态未更新,回滚事务并抛异常,保持数据一致性 - throw new RuntimeException("医嘱状态更新为 CANCELLED 失败,请检查医嘱是否存在或已被处理"); - } - - // 3. 回滚 adm_schedule_slot 状态:status=0(待约), order_id=NULL - int slotUpdated = cancelMapper.rollbackSlotStatus(orderId); - if (slotUpdated == 0) { - throw new RuntimeException("号源状态回滚失败"); - } - - // 4. 更新 adm_schedule_pool:version=version+1, booked_num=booked_num-1 - Map slotInfo = cancelMapper.selectSlotByOrderId(orderId); - if (slotInfo != null && slotInfo.get("pool_id") != null) { - Long poolId = Long.valueOf(slotInfo.get("pool_id").toString()); - int poolUpdated = cancelMapper.updatePoolVersion(poolId); - if (poolUpdated == 0) { - throw new RuntimeException("排班池版本与已约数更新失败"); - } - } - - // 5. 记录退款日志(如有需要,此处可调用相应的 RefundLogMapper) - // 省略实现细节,保持业务完整性 - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java deleted file mode 100644 index 636123031..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.OrderMapper; -import com.openhis.web.outpatient.mapper.RegistrationMapper; -import com.openhis.web.outpatient.service.RegistrationService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.Map; - -/** - * 门诊挂号业务实现 - * - * 修复说明 (Bug #506): - * 诊前退号后,原逻辑未同步更新 order_main、adm_schedule_slot、adm_schedule_pool 及 refund_log 表, - * 导致状态值与 PRD 定义不符、号源无法复用、退费日志断链。 - * 本次修复: - * 1. 在单一事务内串行执行多表更新,确保数据强一致性。 - * 2. 严格使用 PRD 定义的状态码与字段值(status=0, pay_status=3, cancel_reason='诊前退号')。 - * 3. 使用 NOW() 写入准确的取消时间,避免时分秒丢失。 - * 4. 号源池 version 累加 1,booked_num 扣减 1,slot 状态回滚至 0 并清空 order_id。 - * 5. refund_log 显式关联 order_main.id。 - * - * 新增说明 (Bug #574): - * 预约签到缴费成功后,需要将对应的号源 slot 状态更新为 “3”(已取)。 - * 为此在支付成功的业务路径中调用 `registrationMapper.updateSlotStatusToTaken`。 - */ -@Service -public class RegistrationServiceImpl implements RegistrationService { - - @Autowired - private RegistrationMapper registrationMapper; - - @Autowired - private OrderMapper orderMapper; - - /** - * 诊前退号 - * - * @param registrationId 挂号主键 - * @param operator 操作人姓名 - * @return true 表示退号成功 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public boolean cancelRegistrationBeforeVisit(Long registrationId, String operator) { - // 1. 查询挂号信息,确保处于可退号状态 - Map reg = registrationMapper.selectRegistrationById(registrationId); - if (reg == null) { - throw new IllegalArgumentException("挂号记录不存在"); - } - - String status = (String) reg.get("status"); - // PRD 中可退号状态一般为 “0”(已预约) 或 “1”(已支付) 等,这里假设 0 为可退 - if (!"0".equals(status) && !"1".equals(status)) { - throw new IllegalStateException("当前挂号状态不可退号"); - } - - Long orderId = (Long) reg.get("order_id"); - Long slotId = (Long) reg.get("slot_id"); - Long poolId = (Long) reg.get("pool_id"); - BigDecimal payAmount = (BigDecimal) reg.get("pay_amount"); - - // 2. 更新医嘱主表状态为已取消、已退费 - orderMapper.updateOrderMainForCancellation( - orderId, - OrderMapper.ORDER_STATUS_CANCELLED, - OrderMapper.ORDER_PAY_STATUS_REFUNDED, - "诊前退号" - ); - - // 3. 回滚号源 slot 为待约 (status=0) 并清空 order_id - registrationMapper.rollbackScheduleSlot(slotId); - - // 4. 更新号源池 version 与 booked_num - registrationMapper.updateSchedulePoolOnCancel(poolId); - - // 5. 插入退费日志,关联到 order_main - if (payAmount != null && payAmount.compareTo(BigDecimal.ZERO) > 0) { - registrationMapper.insertRefundLog(orderId, payAmount, operator); - } - - // 6. 最后更新挂号主表状态为已退号(status=0) - registrationMapper.updateRegistrationStatus(registrationId, "0", operator); - - return true; - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/TriageQueueServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/TriageQueueServiceImpl.java deleted file mode 100644 index 7223e96fd..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/TriageQueueServiceImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.TriageQueueMapper; -import com.openhis.web.outpatient.service.TriageQueueService; -import org.springframework.stereotype.Service; - -import java.time.LocalDate; -import java.util.List; -import java.util.Map; - -/** - * 智能分诊排队业务实现 - * - * 修复 Bug #544: - * 增加日期范围参数处理逻辑,若前端未传时间则默认查询当天数据,满足“默认当天时间”需求。 - */ -@Service -public class TriageQueueServiceImpl implements TriageQueueService { - - private final TriageQueueMapper queueMapper; - - public TriageQueueServiceImpl(TriageQueueMapper queueMapper) { - this.queueMapper = queueMapper; - } - - @Override - public List> getQueueList(String status, String startDate, String endDate) { - // 默认查询当天,支持历史范围覆盖 - String effectiveStart = (startDate == null || startDate.isBlank()) ? LocalDate.now().toString() : startDate; - String effectiveEnd = (endDate == null || endDate.isBlank()) ? LocalDate.now().toString() : endDate; - - return queueMapper.selectQueueList(status, effectiveStart, effectiveEnd); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/controller/TriageQueueController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/controller/TriageQueueController.java deleted file mode 100644 index 14418b3c3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/controller/TriageQueueController.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.openhis.web.outpatient.triage.controller; - -import com.openhis.web.outpatient.triage.service.TriageQueueService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; -import java.util.List; -import java.util.Map; - -/** - * 智能分诊排队控制器 - * - * 修复说明 (Bug #544): - * 暴露统一查询接口,接收状态与时间范围参数,支撑前端列表展示与历史查询。 - */ -@RestController -@RequestMapping("/api/outpatient/triage/queue") -public class TriageQueueController { - - @Autowired - private TriageQueueService queueService; - - @GetMapping("/list") - public List> getQueueList( - @RequestParam Long deptId, - @RequestParam(required = false) String status, - @RequestParam(required = false) String startDate, - @RequestParam(required = false) String endDate) { - return queueService.getQueueList(deptId, status, startDate, endDate); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/mapper/TriageQueueMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/mapper/TriageQueueMapper.java deleted file mode 100644 index a4550e059..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/mapper/TriageQueueMapper.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.openhis.web.outpatient.triage.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 #544): - * 1. 移除原 SQL 中硬编码的 status != 'COMPLETED' 过滤条件,改为动态参数控制。 - * 2. 新增 startDate/endDate 动态过滤,支持历史队列按时间范围检索。 - */ -@Mapper -public interface TriageQueueMapper { - - /** - * 查询分诊排队记录(支持状态筛选与时间范围) - * - * @param deptId 科室ID - * @param status 排队状态(为空则查询全部,含完诊) - * @param startDate 开始时间 - * @param endDate 结束时间 - * @return 队列记录列表 - */ - @Select("") - List> selectQueueRecords(@Param("deptId") Long deptId, - @Param("status") String status, - @Param("startDate") String startDate, - @Param("endDate") String endDate); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/service/TriageQueueService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/service/TriageQueueService.java deleted file mode 100644 index 0c5e7dab7..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/service/TriageQueueService.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.triage.service; -public interface TriageQueueService {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/service/impl/TriageQueueServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/service/impl/TriageQueueServiceImpl.java deleted file mode 100644 index a2c3daca6..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/triage/service/impl/TriageQueueServiceImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.openhis.web.outpatient.triage.service.impl; - -import com.openhis.web.outpatient.triage.mapper.TriageQueueMapper; -import com.openhis.web.outpatient.triage.service.TriageQueueService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Map; - -/** - * 智能分诊排队业务逻辑层 - * - * 修复说明 (Bug #544): - * 统一处理时间参数默认值,确保未传时间时自动回退至当天范围, - * 满足“历史队列查询默认当天时间”的需求。 - */ -@Service -public class TriageQueueServiceImpl implements TriageQueueService { - - @Autowired - private TriageQueueMapper queueMapper; - - @Override - public List> getQueueList(Long deptId, String status, String startDate, String endDate) { - // 默认查询当天数据 - String today = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE); - if (startDate == null || startDate.trim().isEmpty()) { - startDate = today + " 00:00:00"; - } - if (endDate == null || endDate.trim().isEmpty()) { - endDate = today + " 23:59:59"; - } - return queueMapper.selectQueueRecords(deptId, status, startDate, endDate); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/vo/MedicalOrderVO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/vo/MedicalOrderVO.java deleted file mode 100644 index 1689b0460..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/vo/MedicalOrderVO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.vo; -public class MedicalOrderVO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/vo/OrderVO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/vo/OrderVO.java deleted file mode 100644 index 24c391b7b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/vo/OrderVO.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.openhis.web.outpatient.vo; - -import lombok.Data; -import java.math.BigDecimal; - -/** - * 门诊医嘱视图对象 - * 修复 Bug #561:新增 totalUnit 字段映射诊疗目录配置的使用单位 - */ -@Data -public class OrderVO { - private Long id; - private Long patientId; - private Long catalogId; - private String itemName; - private BigDecimal totalQuantity; - private String totalUnit; // 对应 his_medical_catalog.usage_unit -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/vo/PendingMedicalRecordVO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/vo/PendingMedicalRecordVO.java deleted file mode 100644 index b4889af07..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/vo/PendingMedicalRecordVO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.outpatient.vo; -public class PendingMedicalRecordVO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/controller/DispensingController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/controller/DispensingController.java deleted file mode 100644 index 381c71c5e..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/controller/DispensingController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.openhis.web.pharmacy.controller; - -import com.openhis.web.pharmacy.service.DispensingService; -import org.springframework.web.bind.annotation.*; -import java.util.List; -import java.util.Map; - -/** - * 药房住院发退药接口 - * 修复 Bug #503:统一发药明细与汇总单的数据触发时机 - */ -@RestController -@RequestMapping("/api/pharmacy/dispensing") -public class DispensingController { - - private final DispensingService dispensingService; - - public DispensingController(DispensingService dispensingService) { - this.dispensingService = dispensingService; - } - - /** - * 获取发药明细单列表 - * @param mode 字典配置:病区护士执行提交药品模式 (1:需申请模式, 2:自动模式) - */ - @GetMapping("/detail") - public List> getDispensingDetailList(@RequestParam(required = false, defaultValue = "1") String mode) { - return dispensingService.getDispensingDetailList(mode); - } - - /** - * 获取发药汇总单列表 - */ - @GetMapping("/summary") - public List> getDispensingSummaryList() { - return dispensingService.getDispensingSummaryList(); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/entity/DispensingRecord.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/entity/DispensingRecord.java deleted file mode 100644 index cc22b8d89..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/entity/DispensingRecord.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.pharmacy.entity; -public class DispensingRecord {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/mapper/DispensingMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/mapper/DispensingMapper.java deleted file mode 100644 index 6e2916c3d..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/mapper/DispensingMapper.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.openhis.web.pharmacy.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; - -/** - * 发药数据 Mapper - */ -@Mapper -public interface DispensingMapper { - - /** - * 查询发药明细记录 - * 修复 Bug #503:通过 apply_status 统一控制明细单可见性,避免与汇总单状态脱节 - */ - @Select("SELECT id, patient_id, drug_code, drug_name, quantity, status, apply_status, create_time " + - "FROM drug_dispense_detail WHERE apply_status = #{status} ORDER BY create_time DESC") - List> selectDispensingDetails(@Param("status") String status); - - /** - * 查询发药汇总记录 - */ - @Select("SELECT id, ward_id, ward_name, total_items, total_quantity, status, create_time " + - "FROM drug_dispense_summary WHERE status = #{status} ORDER BY create_time DESC") - List> selectDispensingSummary(@Param("status") String status); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/mapper/DispensingRecordMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/mapper/DispensingRecordMapper.java deleted file mode 100644 index 1134d359c..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/mapper/DispensingRecordMapper.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.openhis.web.pharmacy.mapper; - -import com.openhis.web.pharmacy.entity.DispensingRecord; -import org.apache.ibatis.annotations.*; - -import java.util.List; - -/** - * 发药记录数据库操作 Mapper - * - * 修复 Bug #503: - * 1. 将汇总单更新逻辑改为 PostgreSQL UPSERT (INSERT ... ON CONFLICT), - * 解决原 UPDATE 语句在汇总记录不存在时无法创建,导致“明细有数据、汇总为空”的脱节问题。 - * 2. 确保明细插入与汇总生成在同一事务内原子执行。 - */ -@Mapper -public interface DispensingRecordMapper { - - @Insert("INSERT INTO his_pharmacy_dispensing_record " + - "(order_id, drug_id, dosage, quantity, dispense_time, created_by) " + - "VALUES (#{orderId}, #{drugId}, #{dosage}, #{quantity}, NOW(), #{createdBy})") - @Options(useGeneratedKeys = true, keyProperty = "id") - int insert(DispensingRecord record); - - @Select("SELECT * FROM his_pharmacy_dispensing_record WHERE order_id = #{orderId}") - List selectByOrderId(@Param("orderId") Long orderId); - - /** - * 修复 Bug #503:发药明细插入后,同步创建或更新发药汇总单。 - * 使用 ON CONFLICT 保证记录不存在时自动 INSERT,存在时累加数量与金额, - * 彻底消除明细与汇总触发时机不一致的业务隐患。 - */ - @Update({ - "" - }) - int upsertSummaryAfterDispense(@Param("orderId") Long orderId, - @Param("drugId") Long drugId, - @Param("quantity") Integer quantity, - @Param("amount") java.math.BigDecimal amount); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/mapper/InpatientDispensingMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/mapper/InpatientDispensingMapper.java deleted file mode 100644 index 5a9c8d5b1..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/mapper/InpatientDispensingMapper.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.openhis.web.pharmacy.mapper; - -import com.openhis.web.pharmacy.vo.DispensingDetailVO; -import com.openhis.web.pharmacy.vo.DispensingSummaryVO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -import java.util.List; - -/** - * 住院发药数据访问层 - * - * 修复 Bug #503:发药明细与发药汇总单数据触发时机不一致 - * 根因:明细单查询未校验“汇总申请状态”,导致护士仅执行医嘱(未提交汇总申请)时, - * 药房明细单提前暴露待发药记录,与汇总单状态脱节。 - * 修复方案:在明细单查询中引入动态条件,当系统配置为“需申请模式”时, - * 强制要求 `submit_status = 'SUBMITTED'`,确保明细与汇总单同步触发。 - */ -@Mapper -public interface InpatientDispensingMapper { - - /** - * 查询发药明细单 - * @param wardId 病区ID - * @param mode 系统字典配置:'需申请模式' 或 '自动模式' - */ - @Select("") - List selectDispensingDetails(@Param("wardId") Long wardId, @Param("mode") String mode); - - /** - * 查询发药汇总单 - * @param wardId 病区ID - */ - @Select("SELECT " + - " a.id, a.ward_id, a.drug_code, a.drug_name, a.spec, SUM(d.quantity) AS total_quantity, " + - " a.submit_status, a.create_time " + - "FROM his_dispensing_application a " + - "JOIN his_dispensing_detail d ON a.id = d.application_id " + - "WHERE a.ward_id = #{wardId} " + - " AND a.submit_status = 'SUBMITTED' " + - "GROUP BY a.id, a.ward_id, a.drug_code, a.drug_name, a.spec, a.submit_status, a.create_time " + - "ORDER BY a.create_time DESC") - List selectDispensingSummary(@Param("wardId") Long wardId); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/DispensingService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/DispensingService.java deleted file mode 100644 index 7ff8af0af..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/DispensingService.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.openhis.web.pharmacy.service; - -import java.util.List; -import java.util.Map; - -/** - * 发药业务接口 - */ -public interface DispensingService { - - /** - * 获取发药明细单列表 - * @param mode 提交模式 (1:需申请, 2:自动) - */ - List> getDispensingDetailList(String mode); - - /** - * 获取发药汇总单列表 - */ - List> getDispensingSummaryList(); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/DispensingServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/DispensingServiceImpl.java deleted file mode 100644 index 948006426..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/DispensingServiceImpl.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.openhis.web.pharmacy.service; - -import com.openhis.web.pharmacy.entity.DispensingRecord; -import com.openhis.web.pharmacy.mapper.DispensingRecordMapper; -import com.openhis.web.system.service.DictService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * 住院发退药服务实现 - */ -@Service -public class DispensingServiceImpl implements DispensingService { - - private final DispensingRecordMapper dispensingRecordMapper; - private final DictService dictService; - - public DispensingServiceImpl(DispensingRecordMapper dispensingRecordMapper, DictService dictService) { - this.dispensingRecordMapper = dispensingRecordMapper; - this.dictService = dictService; - } - - /** - * 护士执行医嘱 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void executeDrugOrder(Long orderId) { - DispensingRecord record = dispensingRecordMapper.selectById(orderId); - if (record == null) { - throw new IllegalArgumentException("发药记录不存在"); - } - - record.setNurseExecStatus("EXECUTED"); - record.setExecTime(LocalDateTime.now()); - - // Bug #503 Fix: 根据字典配置控制药房可见状态 - // 默认模式为 APPLY_REQUIRED (需申请模式),执行时不推送到药房队列 - String submitMode = dictService.getValue("ward_nurse_submit_mode", "APPLY_REQUIRED"); - if ("APPLY_REQUIRED".equals(submitMode)) { - record.setPharmacyApplyStatus(0); // 0-未申请,药房不可见 - } else { - record.setPharmacyApplyStatus(1); // 1-已申请,药房可见(自动模式) - } - - record.setUpdateTime(LocalDateTime.now()); - dispensingRecordMapper.updateById(record); - } - - /** - * 护士提交汇总发药申请 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void submitSummaryApplication(List orderIds) { - if (orderIds == null || orderIds.isEmpty()) { - throw new IllegalArgumentException("申请单号列表不能为空"); - } - - // Bug #503 Fix: 汇总申请触发时,统一将状态流转为“已申请”,确保明细与汇总同步可见 - dispensingRecordMapper.batchUpdateApplyStatus(orderIds, 1, LocalDateTime.now()); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/InpatientDispensingService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/InpatientDispensingService.java deleted file mode 100644 index 11d020f77..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/InpatientDispensingService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.openhis.web.pharmacy.service; - -public interface InpatientDispensingService { -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/impl/DispensingServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/impl/DispensingServiceImpl.java deleted file mode 100644 index 564c23a95..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/service/impl/DispensingServiceImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.openhis.web.pharmacy.service.impl; - -import com.openhis.web.pharmacy.mapper.DispensingMapper; -import com.openhis.web.pharmacy.service.DispensingService; -import com.openhis.web.system.service.SysConfigService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Map; - -/** - * 药房发药业务实现 - * - * 修复 Bug #503:统一发药明细单与发药汇总单的数据触发时机。 - * 根据字典配置 `WARD_NURSE_DRUG_SUBMIT_MODE` 动态过滤查询条件: - * - APPLY_REQUIRED (需申请模式):仅查询 application_status = 'APPLIED' 的记录,确保明细与汇总同步。 - * - AUTO (自动模式):查询 execution_status = 'EXECUTED' 的记录,执行即同步显示。 - */ -@Service -public class DispensingServiceImpl implements DispensingService { - - private final DispensingMapper dispensingMapper; - private final SysConfigService sysConfigService; - - // 字典配置 Key - private static final String CONFIG_KEY_SUBMIT_MODE = "WARD_NURSE_DRUG_SUBMIT_MODE"; - private static final String MODE_APPLY_REQUIRED = "APPLY_REQUIRED"; - private static final String MODE_AUTO = "AUTO"; - - public DispensingServiceImpl(DispensingMapper dispensingMapper, SysConfigService sysConfigService) { - this.dispensingMapper = dispensingMapper; - this.sysConfigService = sysConfigService; - } - - @Override - public List> queryDispensingDetails(Map queryParams) { - String mode = getSubmitMode(); - // 修复:明细单查询条件与汇总单保持一致,避免“明细先出、汇总后出”的脱节 - String statusCondition = MODE_APPLY_REQUIRED.equals(mode) ? "APPLIED" : "EXECUTED"; - queryParams.put("statusCondition", statusCondition); - return dispensingMapper.selectDispensingDetails(queryParams); - } - - @Override - public List> queryDispensingSummary(Map queryParams) { - String mode = getSubmitMode(); - // 汇总单原有逻辑已按 APPLIED 过滤,此处显式对齐,增强可读性与一致性 - String statusCondition = MODE_APPLY_REQUIRED.equals(mode) ? "APPLIED" : "EXECUTED"; - queryParams.put("statusCondition", statusCondition); - return dispensingMapper.selectDispensingSummary(queryParams); - } - - /** - * 获取病区护士执行提交药品模式 - * 默认返回需申请模式,保障业务安全 - */ - private String getSubmitMode() { - String mode = sysConfigService.getConfigValue(CONFIG_KEY_SUBMIT_MODE); - return (mode == null || mode.trim().isEmpty()) ? MODE_APPLY_REQUIRED : mode.trim(); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/vo/DispensingDetailVO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/vo/DispensingDetailVO.java deleted file mode 100644 index 9107407b3..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/vo/DispensingDetailVO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.pharmacy.vo; -public class DispensingDetailVO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/vo/DispensingSummaryVO.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/vo/DispensingSummaryVO.java deleted file mode 100644 index 364a2394a..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/pharmacy/vo/DispensingSummaryVO.java +++ /dev/null @@ -1,2 +0,0 @@ -package com.openhis.web.pharmacy.vo; -public class DispensingSummaryVO {} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/mapper/RequestFormManageAppMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/mapper/RequestFormManageAppMapper.java index 070b13b60..fd0b8da5d 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/mapper/RequestFormManageAppMapper.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/mapper/RequestFormManageAppMapper.java @@ -1,71 +1,75 @@ package com.openhis.web.regdoctorstation.mapper; -import com.openhis.web.doctorstation.dto.AdviceSaveParam; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.openhis.document.domain.RequestForm; +import com.openhis.web.regdoctorstation.dto.ActivityOrganizationConfigDto; +import com.openhis.web.regdoctorstation.dto.RequestFormDetailQueryDto; +import com.openhis.web.regdoctorstation.dto.RequestFormDto; +import com.openhis.web.regdoctorstation.dto.RequestFormPageDto; +import com.openhis.web.regdoctorstation.dto.RequestFormQueryDto; import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; -import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; -import java.time.LocalDateTime; import java.util.List; -import java.util.Map; /** - * 医嘱/检验申请相关数据库操作 Mapper + * 申请单管理 应用Mapper */ +@Repository public interface RequestFormManageAppMapper { - // 其他已有方法省略 - /** - * 查询医嘱当前状态 - * @param adviceId 医嘱ID - * @return 状态码,null 表示不存在 - */ - @Select("SELECT status FROM wor_advice WHERE id = #{adviceId}") - Integer selectAdviceStatusById(@Param("adviceId") Long adviceId); - - /** - * 更新医嘱状态 - * @param adviceId 医嘱ID - * @param status 新状态码 - * @return 受影响行数 - */ - @Update("UPDATE wor_advice SET status = #{status}, update_time = NOW() WHERE id = #{adviceId}") - int updateAdviceStatus(@Param("adviceId") Long adviceId, @Param("status") Integer status); - - /** - * 停嘱时更新状态并记录停嘱医生及停嘱时间 + * 查询申请单 * - * @param adviceId 医嘱ID - * @param status 新状态码(建议使用 5 表示已停嘱) - * @param doctorId 停嘱医生ID - * @param stopTime 停嘱时间 - * @return 受影响行数 + * @param encounterId 就诊id + * @param typeCode 申请单类型 + * @return 检查申请单 */ - @Update("UPDATE wor_advice " + - "SET status = #{status}, " + - " stop_doctor_id = #{doctorId}, " + - " stop_time = #{stopTime}, " + - " update_time = NOW() " + - "WHERE id = #{adviceId}") - int updateAdviceStatusAndStopInfo(@Param("adviceId") Long adviceId, - @Param("status") Integer status, - @Param("doctorId") Long doctorId, - @Param("stopTime") java.time.LocalDateTime stopTime); + List getRequestForm(@Param("encounterId") Long encounterId, + @Param("typeCode") String typeCode); /** - * Bug #587: 查询患者入院时间用于开始时间校验 - * @param encounterId 就诊ID - * @return 入院时间 + * 查询申请单(支持筛选) + * + * @param encounterId 就诊id + * @param typeCode 申请单类型 + * @param startDate 开始日期(可选,格式:yyyy-MM-dd) + * @param endDate 结束日期(可选,格式:yyyy-MM-dd) + * @param status 单据状态(可选) + * @param keyword 关键字(可选,申请单号/检查项目名称模糊匹配) + * @return 申请单列表 */ - @Select("SELECT admission_time FROM his_encounter WHERE id = #{encounterId}") - LocalDateTime selectAdmissionTimeByEncounterId(@Param("encounterId") Long encounterId); + List getRequestForm(@Param("encounterId") Long encounterId, + @Param("typeCode") String typeCode, + @Param("startDate") String startDate, + @Param("endDate") String endDate, + @Param("status") String status, + @Param("keyword") String keyword); /** - * Bug #572: 查询患者档案中的现住址与职业信息 - * @param patientId 患者ID - * @return 包含 currentAddress 和 occupation 的 Map + * 查询申请单详情 + * + * @param prescriptionNo 申请单处方号 + * @return 申请单详情 */ - @Select("SELECT current_address AS currentAddress, occupation FROM his_patient WHERE id = #{patientId}") - Map selectPatientProfileInfo(@Param("patientId") Long patientId); + List getRequestFormDetail(@Param("prescriptionNo") String prescriptionNo); + + /** + * 查询诊疗执行科室配置 + * + * @param activityCategoryCode 诊疗类型编码 + * @return 诊疗执行科室配置 + */ + List + getActivityOrganizationConfig(@Param("activityCategoryCode") String activityCategoryCode); + + /** + * 获取申请单分页数据 + * + * @param requestFormDto 申请单参数 + * @return 申请单分页列表 + */ + IPage getRequestFormPage( + @Param("requestFormDto") RequestFormDto requestFormDto,@Param("page") IPage page); } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/system/service/DictService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/system/service/DictService.java deleted file mode 100644 index 38f3b81c7..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/system/service/DictService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.openhis.web.system.service; - -public interface DictService { - String getDictLabel(String dictType, String dictValue); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/system/service/SysConfigService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/system/service/SysConfigService.java deleted file mode 100644 index 5ca2a159b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/system/service/SysConfigService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.openhis.web.system.service; - -public interface SysConfigService { - String getConfigValue(String key); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/controller/TriageQueueController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/controller/TriageQueueController.java deleted file mode 100644 index de95138d7..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/controller/TriageQueueController.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.openhis.web.triage.controller; - -import com.openhis.web.triage.service.TriageQueueService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; -import java.util.List; -import java.util.Map; - -/** - * 智能分诊排队控制器 - * 修复 Bug #544:开放 status、startTime、endTime 查询参数。 - */ -@RestController -@RequestMapping("/api/triage/queue") -public class TriageQueueController { - - @Autowired - private TriageQueueService triageQueueService; - - @GetMapping("/list") - public List> list(@RequestParam Long deptId, - @RequestParam(required = false) Integer status, - @RequestParam(required = false) String startTime, - @RequestParam(required = false) String endTime) { - return triageQueueService.getQueueList(deptId, status, startTime, endTime); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/mapper/TriageQueueMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/mapper/TriageQueueMapper.java deleted file mode 100644 index 76fdd3cc8..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/mapper/TriageQueueMapper.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.openhis.web.triage.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 #544:移除原 SQL 中硬编码过滤完诊状态的逻辑,增加时间范围动态查询支持。 - */ -@Mapper -public interface TriageQueueMapper { - - /** - * 查询排队队列列表 - * - * @param deptId 科室ID - * @param status 状态过滤(可选,传 null 则查询全部状态含完诊) - * @param startTime 开始时间(可选) - * @param endTime 结束时间(可选) - * @return 队列记录列表 - */ - @Select("") - List> selectQueueList(@Param("deptId") Long deptId, - @Param("status") Integer status, - @Param("startTime") String startTime, - @Param("endTime") String endTime); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/service/TriageQueueService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/service/TriageQueueService.java deleted file mode 100644 index 8134720ae..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/service/TriageQueueService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.openhis.web.triage.service; - -import com.github.pagehelper.PageInfo; -import com.openhis.application.domain.dto.TriageQueueQueryDTO; -import com.openhis.application.domain.entity.TriageQueueRecord; - -public interface TriageQueueService { - PageInfo getQueueList(TriageQueueQueryDTO query); -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/service/TriageQueueServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/service/TriageQueueServiceImpl.java deleted file mode 100644 index d6e8407df..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/service/TriageQueueServiceImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.openhis.web.triage.service; - -import com.openhis.web.triage.mapper.TriageQueueMapper; -import org.springframework.stereotype.Service; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Map; - -/** - * 智能分诊排队服务实现 - */ -@Service -public class TriageQueueServiceImpl implements TriageQueueService { - - private final TriageQueueMapper triageQueueMapper; - - public TriageQueueServiceImpl(TriageQueueMapper triageQueueMapper) { - this.triageQueueMapper = triageQueueMapper; - } - - /** - * Bug #544 Fix: 默认时间范围设为当天,支持历史查询 - */ - @Override - public List> getQueueRecords(Long deptId, Integer status, String startDate, String endDate) { - // 默认查询当天数据,满足 Expected Behavior 2 - String start = startDate != null ? startDate : LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + " 00:00:00"; - String end = endDate != null ? endDate : LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + " 23:59:59"; - return triageQueueMapper.selectQueueRecords(deptId, status, start, end); - } -} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/service/impl/TriageQueueServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/service/impl/TriageQueueServiceImpl.java deleted file mode 100644 index 50e7fdf5b..000000000 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/triage/service/impl/TriageQueueServiceImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.openhis.web.triage.service.impl; - -import com.openhis.web.triage.mapper.TriageQueueMapper; -import com.openhis.web.triage.service.TriageQueueService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Map; - -/** - * 智能分诊排队业务实现 - * - * 修复 Bug #544: - * 补充默认时间范围逻辑(默认当天 00:00:00 ~ 23:59:59), - * 确保前端未传参时仍返回当日完整队列(含完诊)。 - */ -@Service -public class TriageQueueServiceImpl implements TriageQueueService { - - @Autowired - private TriageQueueMapper queueMapper; - - @Override - public List> getQueueList(String deptCode, String status, String startDate, String endDate) { - // 默认查询当天数据,满足“默认当天时间”需求 - String start = (startDate != null && !startDate.isEmpty()) - ? startDate + " 00:00:00" - : LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + " 00:00:00"; - String end = (endDate != null && !endDate.isEmpty()) - ? endDate + " 23:59:59" - : LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + " 23:59:59"; - - return queueMapper.selectQueueList(deptCode, status, start, end); - } -} diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/CatalogItemMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/CatalogItemMapper.xml deleted file mode 100644 index e01e60f54..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/CatalogItemMapper.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/DispensingMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/DispensingMapper.xml deleted file mode 100644 index 29c77ef08..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/DispensingMapper.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/LabRequestMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/LabRequestMapper.xml deleted file mode 100644 index 26ce71892..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/LabRequestMapper.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - INSERT INTO his_lab_request (patient_id, status, symptom, sign, related_result, create_time, del_flag) - VALUES (#{patientId}, #{status}, #{symptom}, #{sign}, #{relatedResult}, NOW(), 0) - - - - UPDATE his_lab_request - SET symptom = #{symptom}, sign = #{sign}, related_result = #{relatedResult}, update_time = NOW() - WHERE id = #{id} AND del_flag = 0 - - - diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/MedicalRecordMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/MedicalRecordMapper.xml deleted file mode 100644 index 01845d2c9..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/MedicalRecordMapper.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/OrderDetailMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/OrderDetailMapper.xml deleted file mode 100644 index 0d5325326..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/OrderDetailMapper.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSERT INTO order_detail (order_id, catalog_item_id, single_dose, total_amount, total_price, frequency, usage) - VALUES (#{orderId}, #{catalogItemId}, #{singleDose}, #{totalAmount}, #{totalPrice}, #{frequency}, #{usage}) - - diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/QueueMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/QueueMapper.xml deleted file mode 100644 index 735b4e673..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/QueueMapper.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/SchedulePoolMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/SchedulePoolMapper.xml deleted file mode 100644 index 2f8f22c6a..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/SchedulePoolMapper.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - UPDATE adm_schedule_pool - SET booked_num = booked_num + 1 - WHERE id = #{poolId} - - - - - UPDATE adm_schedule_pool - SET booked_num = CASE WHEN booked_num > 0 THEN booked_num - 1 ELSE 0 END - WHERE id = #{poolId} - - - diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/TriageQueueMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/TriageQueueMapper.xml deleted file mode 100644 index 513bc012e..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/TriageQueueMapper.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/VitalSignMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/VitalSignMapper.xml deleted file mode 100644 index 884a663c4..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/VitalSignMapper.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - INSERT INTO hisdev.vital_sign_record ( - patient_id, record_time, temperature, pulse, heart_rate, - create_by, create_time, is_deleted - ) VALUES ( - #{patientId}, #{recordTime}, #{temperature}, #{pulse}, #{heartRate}, - #{createBy}, NOW(), 0 - ) - - diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/regdoctorstation/RequestFormManageAppMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/regdoctorstation/RequestFormManageAppMapper.xml index 85ad3633b..db9118d76 100755 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/regdoctorstation/RequestFormManageAppMapper.xml +++ b/openhis-server-new/openhis-application/src/main/resources/mapper/regdoctorstation/RequestFormManageAppMapper.xml @@ -4,19 +4,217 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + - - - UPDATE wor_advice - SET status = #{status}, - stop_doctor_id = #{doctorId}, - stop_time = #{stopTime}, - update_time = NOW() - WHERE id = #{adviceId} - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/triage/TriageQueueMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/triage/TriageQueueMapper.xml deleted file mode 100644 index 3bd6b5c22..000000000 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/triage/TriageQueueMapper.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - diff --git a/openhis-server-new/openhis-infrastructure/src/main/resources/mapper/OutpatientOrderMapper.xml b/openhis-server-new/openhis-infrastructure/src/main/resources/mapper/OutpatientOrderMapper.xml deleted file mode 100644 index f84575a02..000000000 --- a/openhis-server-new/openhis-infrastructure/src/main/resources/mapper/OutpatientOrderMapper.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/openhis-ui-vue3/package.json b/openhis-ui-vue3/package.json old mode 100644 new mode 100755 diff --git a/openhis-ui-vue3/src/api/inpatient/labRequest.js b/openhis-ui-vue3/src/api/inpatient/labRequest.js deleted file mode 100644 index f6539b6c7..000000000 --- a/openhis-ui-vue3/src/api/inpatient/labRequest.js +++ /dev/null @@ -1,19 +0,0 @@ -import request from '@/utils/request' - -export function getLabRequestListApi() { - return request({ - url: '/inpatient/lab-request/list', - method: 'get' - }) -} - -/** - * 撤回检验申请 (Bug #571) - * @param {Number} requestId - */ -export function revokeLabRequestApi(requestId) { - return request({ - url: `/inpatient/lab-request/revoke/${requestId}`, - method: 'post' - }) -} diff --git a/openhis-ui-vue3/src/api/inpatient/vitalSign.js b/openhis-ui-vue3/src/api/inpatient/vitalSign.js deleted file mode 100644 index d09a1780a..000000000 --- a/openhis-ui-vue3/src/api/inpatient/vitalSign.js +++ /dev/null @@ -1,14 +0,0 @@ -import request from '@/utils/request'; - -/** - * 获取住院体征(体温单)数据 - * @param {Object} params { registrationId } - * @returns {Promise} 返回体征记录列表,前端体温图表使用 - */ -export function getVitalSignsApi(params) { - return request({ - url: '/inpatient/vital-signs', - method: 'get', - params, - }); -} diff --git a/openhis-ui-vue3/src/api/outpatient.js b/openhis-ui-vue3/src/api/outpatient.js deleted file mode 100644 index ab2700e41..000000000 --- a/openhis-ui-vue3/src/api/outpatient.js +++ /dev/null @@ -1,29 +0,0 @@ -import request from '@/utils/request' - -/** - * 获取患者待写病历的医嘱列表(分页) - * @param {Number|String} patientId - * @param {Number} pageNum - * @param {Number} pageSize - */ -export function getPendingOrders(patientId, pageNum = 1, pageSize = 20) { - return request({ - url: '/api/orders/pending', - method: 'get', - params: { patientId, pageNum, pageSize } - }) -} - -/** - * 获取患者排队队列(包括完诊)列表(分页) - * @param {Number|String} patientId - * @param {Number} pageNum - * @param {Number} pageSize - */ -export function getQueueOrders(patientId, pageNum = 1, pageSize = 20) { - return request({ - url: '/api/orders/queue', - method: 'get', - params: { patientId, pageNum, pageSize } - }) -} diff --git a/openhis-ui-vue3/src/api/outpatient/medicalRecord.js b/openhis-ui-vue3/src/api/outpatient/medicalRecord.js deleted file mode 100644 index 6b465d1f5..000000000 --- a/openhis-ui-vue3/src/api/outpatient/medicalRecord.js +++ /dev/null @@ -1,13 +0,0 @@ -import request from '@/utils/request' - -/** - * 获取当前医生待写病历列表 - * @returns {Promise} - */ -export function getPendingMedicalRecords() { - return request({ - url: '/api/medical-record/pending', - method: 'get', - timeout: 5000 // 明确设置前端超时阈值,避免无限等待 - }) -} diff --git a/openhis-ui-vue3/src/api/triage.ts b/openhis-ui-vue3/src/api/triage.ts deleted file mode 100644 index 5fd724f38..000000000 --- a/openhis-ui-vue3/src/api/triage.ts +++ /dev/null @@ -1,24 +0,0 @@ -import request from '@/utils/request'; -import { PageResult } from '@/types'; - -/** - * 获取当前排队列表(包含已完诊)。 - */ -export const getCurrentQueue = (params: { pageNum: number; pageSize: number }) => { - return request>({ - url: '/api/orders/queue', - method: 'get', - params, - }); -}; - -/** - * 获取历史排队(仅已完诊)列表。 - */ -export const getHistoryQueue = (params: { pageNum: number; pageSize: number }) => { - return request>({ - url: '/api/orders/queue/history', - method: 'get', - params, - }); -}; diff --git a/openhis-ui-vue3/src/api/vitalSign.js b/openhis-ui-vue3/src/api/vitalSign.js deleted file mode 100644 index ff3ef404c..000000000 --- a/openhis-ui-vue3/src/api/vitalSign.js +++ /dev/null @@ -1,13 +0,0 @@ -import request from '@/utils/request'; - -/** - * 获取体温图表数据 - * @param {Number} patientId 患者ID - * @returns {Promise} 返回 { data: [{ id, temperature, recordTime }, ...] } - */ -export function fetchTemperatureChartData(patientId) { - return request({ - url: `/api/vitalSign/temperatureChart/${patientId}`, - method: 'get', - }); -} diff --git a/openhis-ui-vue3/src/api/vitalSign.ts b/openhis-ui-vue3/src/api/vitalSign.ts deleted file mode 100644 index 96525b5fa..000000000 --- a/openhis-ui-vue3/src/api/vitalSign.ts +++ /dev/null @@ -1,6 +0,0 @@ -import request from '@/utils/request'; -import type { VitalSignDto } from '@/types/vitalSign'; - -export const getTemperatureChartData = (patientId: number) => { - return request.get(`/api/vitalSign/temperatureChart/${patientId}`); -}; diff --git a/openhis-ui-vue3/src/types/vitalSign.d.ts b/openhis-ui-vue3/src/types/vitalSign.d.ts deleted file mode 100644 index 376880b41..000000000 --- a/openhis-ui-vue3/src/types/vitalSign.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface VitalSignDto { - patientId: number; - timeLabels: string[]; - temperaturePoints: number[]; - rawDataJson?: string; -} diff --git a/openhis-ui-vue3/src/views/billing/OutpatientDailySettlement.vue b/openhis-ui-vue3/src/views/billing/OutpatientDailySettlement.vue deleted file mode 100644 index 6be2cdd24..000000000 --- a/openhis-ui-vue3/src/views/billing/OutpatientDailySettlement.vue +++ /dev/null @@ -1,116 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/billing/outpatientcharge/OutpatientChargeReport.vue b/openhis-ui-vue3/src/views/billing/outpatientcharge/OutpatientChargeReport.vue deleted file mode 100644 index 0fa4a3031..000000000 --- a/openhis-ui-vue3/src/views/billing/outpatientcharge/OutpatientChargeReport.vue +++ /dev/null @@ -1,118 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/billing/outpatientsettlement/OutpatientDailySettlement.vue b/openhis-ui-vue3/src/views/billing/outpatientsettlement/OutpatientDailySettlement.vue deleted file mode 100644 index 2836edc93..000000000 --- a/openhis-ui-vue3/src/views/billing/outpatientsettlement/OutpatientDailySettlement.vue +++ /dev/null @@ -1,121 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/clinic/outpatient/examination/ExaminationApply.vue b/openhis-ui-vue3/src/views/clinic/outpatient/examination/ExaminationApply.vue deleted file mode 100644 index 8fe710f82..000000000 --- a/openhis-ui-vue3/src/views/clinic/outpatient/examination/ExaminationApply.vue +++ /dev/null @@ -1,164 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/clinic/outpatient/medicalrecord/PendingMedicalRecord.vue b/openhis-ui-vue3/src/views/clinic/outpatient/medicalrecord/PendingMedicalRecord.vue deleted file mode 100644 index 4b8ebb5b9..000000000 --- a/openhis-ui-vue3/src/views/clinic/outpatient/medicalrecord/PendingMedicalRecord.vue +++ /dev/null @@ -1,110 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/clinicmanagement/doctorstation/examination/ExaminationRequest.vue b/openhis-ui-vue3/src/views/clinicmanagement/doctorstation/examination/ExaminationRequest.vue deleted file mode 100644 index 69ee7741b..000000000 --- a/openhis-ui-vue3/src/views/clinicmanagement/doctorstation/examination/ExaminationRequest.vue +++ /dev/null @@ -1,193 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/doctorstation/outpatient/PendingMedicalRecord.vue b/openhis-ui-vue3/src/views/doctorstation/outpatient/PendingMedicalRecord.vue deleted file mode 100644 index d15ae32cd..000000000 --- a/openhis-ui-vue3/src/views/doctorstation/outpatient/PendingMedicalRecord.vue +++ /dev/null @@ -1,142 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/doctorstation/pending-medical-record/index.vue b/openhis-ui-vue3/src/views/doctorstation/pending-medical-record/index.vue deleted file mode 100644 index 728f34dd5..000000000 --- a/openhis-ui-vue3/src/views/doctorstation/pending-medical-record/index.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/InspectionApply.vue b/openhis-ui-vue3/src/views/inpatient/InspectionApply.vue deleted file mode 100644 index b9c934bd3..000000000 --- a/openhis-ui-vue3/src/views/inpatient/InspectionApply.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - diff --git a/openhis-ui-vue3/src/views/inpatient/LabRequest.vue b/openhis-ui-vue3/src/views/inpatient/LabRequest.vue deleted file mode 100644 index 8f1dac673..000000000 --- a/openhis-ui-vue3/src/views/inpatient/LabRequest.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/OrderList.vue b/openhis-ui-vue3/src/views/inpatient/OrderList.vue deleted file mode 100644 index 7c5ee9b4b..000000000 --- a/openhis-ui-vue3/src/views/inpatient/OrderList.vue +++ /dev/null @@ -1,48 +0,0 @@ - - - diff --git a/openhis-ui-vue3/src/views/inpatient/OrderVerification.vue b/openhis-ui-vue3/src/views/inpatient/OrderVerification.vue deleted file mode 100644 index 7b28acd01..000000000 --- a/openhis-ui-vue3/src/views/inpatient/OrderVerification.vue +++ /dev/null @@ -1,141 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/OrderVerify.vue b/openhis-ui-vue3/src/views/inpatient/OrderVerify.vue deleted file mode 100644 index c2ac8e21f..000000000 --- a/openhis-ui-vue3/src/views/inpatient/OrderVerify.vue +++ /dev/null @@ -1,128 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/SurgeryApplyHistory.vue b/openhis-ui-vue3/src/views/inpatient/SurgeryApplyHistory.vue deleted file mode 100644 index bb4d8620f..000000000 --- a/openhis-ui-vue3/src/views/inpatient/SurgeryApplyHistory.vue +++ /dev/null @@ -1,221 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/SurgeryRequest.vue b/openhis-ui-vue3/src/views/inpatient/SurgeryRequest.vue deleted file mode 100644 index e70aac1e4..000000000 --- a/openhis-ui-vue3/src/views/inpatient/SurgeryRequest.vue +++ /dev/null @@ -1,148 +0,0 @@ - - - diff --git a/openhis-ui-vue3/src/views/inpatient/TemperatureChart.vue b/openhis-ui-vue3/src/views/inpatient/TemperatureChart.vue deleted file mode 100644 index 9e85e37ff..000000000 --- a/openhis-ui-vue3/src/views/inpatient/TemperatureChart.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/VitalSignsChart.vue b/openhis-ui-vue3/src/views/inpatient/VitalSignsChart.vue deleted file mode 100644 index 40448a61a..000000000 --- a/openhis-ui-vue3/src/views/inpatient/VitalSignsChart.vue +++ /dev/null @@ -1,132 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/doctor/surgery/SurgeryApplyList.vue b/openhis-ui-vue3/src/views/inpatient/doctor/surgery/SurgeryApplyList.vue deleted file mode 100644 index ea2b156e2..000000000 --- a/openhis-ui-vue3/src/views/inpatient/doctor/surgery/SurgeryApplyList.vue +++ /dev/null @@ -1,145 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/doctorstation/components/AdviceForm.vue b/openhis-ui-vue3/src/views/inpatient/doctorstation/components/AdviceForm.vue deleted file mode 100644 index 8b1b38454..000000000 --- a/openhis-ui-vue3/src/views/inpatient/doctorstation/components/AdviceForm.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - diff --git a/openhis-ui-vue3/src/views/inpatient/doctorstation/components/DischargeMedPanel.vue b/openhis-ui-vue3/src/views/inpatient/doctorstation/components/DischargeMedPanel.vue deleted file mode 100644 index ccf20f532..000000000 --- a/openhis-ui-vue3/src/views/inpatient/doctorstation/components/DischargeMedPanel.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - diff --git a/openhis-ui-vue3/src/views/inpatient/doctorstation/components/SurgeryApplyHistory.vue b/openhis-ui-vue3/src/views/inpatient/doctorstation/components/SurgeryApplyHistory.vue deleted file mode 100644 index 51beed3b4..000000000 --- a/openhis-ui-vue3/src/views/inpatient/doctorstation/components/SurgeryApplyHistory.vue +++ /dev/null @@ -1,222 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/doctorstation/components/TextAdvicePanel.vue b/openhis-ui-vue3/src/views/inpatient/doctorstation/components/TextAdvicePanel.vue deleted file mode 100644 index e48d24312..000000000 --- a/openhis-ui-vue3/src/views/inpatient/doctorstation/components/TextAdvicePanel.vue +++ /dev/null @@ -1,119 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/drugDispenseReturn/index.vue b/openhis-ui-vue3/src/views/inpatient/drugDispenseReturn/index.vue deleted file mode 100644 index 981660e84..000000000 --- a/openhis-ui-vue3/src/views/inpatient/drugDispenseReturn/index.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/lab-request/LabRequestDialog.vue b/openhis-ui-vue3/src/views/inpatient/lab-request/LabRequestDialog.vue deleted file mode 100644 index 7d1f94141..000000000 --- a/openhis-ui-vue3/src/views/inpatient/lab-request/LabRequestDialog.vue +++ /dev/null @@ -1,102 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/lab-request/index.vue b/openhis-ui-vue3/src/views/inpatient/lab-request/index.vue deleted file mode 100644 index b6c25a478..000000000 --- a/openhis-ui-vue3/src/views/inpatient/lab-request/index.vue +++ /dev/null @@ -1,149 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/OrderVerification.vue b/openhis-ui-vue3/src/views/inpatient/nurse/OrderVerification.vue deleted file mode 100644 index e5ad59d00..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/OrderVerification.vue +++ /dev/null @@ -1,118 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/OrderVerify.vue b/openhis-ui-vue3/src/views/inpatient/nurse/OrderVerify.vue deleted file mode 100644 index 9e16a7750..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/OrderVerify.vue +++ /dev/null @@ -1,112 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/TemperatureChart.vue b/openhis-ui-vue3/src/views/inpatient/nurse/TemperatureChart.vue deleted file mode 100644 index cd267fb0d..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/TemperatureChart.vue +++ /dev/null @@ -1,72 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/TemperatureSheet.vue b/openhis-ui-vue3/src/views/inpatient/nurse/TemperatureSheet.vue deleted file mode 100644 index d23dcce02..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/TemperatureSheet.vue +++ /dev/null @@ -1,147 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/order-verification/index.vue b/openhis-ui-vue3/src/views/inpatient/nurse/order-verification/index.vue deleted file mode 100644 index cdba0a044..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/order-verification/index.vue +++ /dev/null @@ -1,71 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/order-verify/index.vue b/openhis-ui-vue3/src/views/inpatient/nurse/order-verify/index.vue deleted file mode 100644 index 7173c11e1..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/order-verify/index.vue +++ /dev/null @@ -1,116 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/orderVerify/index.vue b/openhis-ui-vue3/src/views/inpatient/nurse/orderVerify/index.vue deleted file mode 100644 index f43a71685..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/orderVerify/index.vue +++ /dev/null @@ -1,124 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/temperatureChart.vue b/openhis-ui-vue3/src/views/inpatient/nurse/temperatureChart.vue deleted file mode 100644 index 0613c85b5..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/temperatureChart.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/vitalsign/TemperatureChart.vue b/openhis-ui-vue3/src/views/inpatient/nurse/vitalsign/TemperatureChart.vue deleted file mode 100644 index f28266244..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/vitalsign/TemperatureChart.vue +++ /dev/null @@ -1,166 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatient/nurse/vitalsign/TemperatureSheet.vue b/openhis-ui-vue3/src/views/inpatient/nurse/vitalsign/TemperatureSheet.vue deleted file mode 100644 index ee02f4a0f..000000000 --- a/openhis-ui-vue3/src/views/inpatient/nurse/vitalsign/TemperatureSheet.vue +++ /dev/null @@ -1,154 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/inpatientdoctorstation/lab/LabRequest.vue b/openhis-ui-vue3/src/views/inpatientdoctorstation/lab/LabRequest.vue deleted file mode 100644 index 7c7f71146..000000000 --- a/openhis-ui-vue3/src/views/inpatientdoctorstation/lab/LabRequest.vue +++ /dev/null @@ -1,210 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/nurse/order-verification/index.vue b/openhis-ui-vue3/src/views/nurse/order-verification/index.vue deleted file mode 100644 index 33bb525af..000000000 --- a/openhis-ui-vue3/src/views/nurse/order-verification/index.vue +++ /dev/null @@ -1,119 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/nurse/order/OrderVerify.vue b/openhis-ui-vue3/src/views/nurse/order/OrderVerify.vue deleted file mode 100644 index bf6997dce..000000000 --- a/openhis-ui-vue3/src/views/nurse/order/OrderVerify.vue +++ /dev/null @@ -1,124 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/nurse/temperature-chart/index.vue b/openhis-ui-vue3/src/views/nurse/temperature-chart/index.vue deleted file mode 100644 index 16e06a46e..000000000 --- a/openhis-ui-vue3/src/views/nurse/temperature-chart/index.vue +++ /dev/null @@ -1,153 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/nursestation/order-verification/index.vue b/openhis-ui-vue3/src/views/nursestation/order-verification/index.vue deleted file mode 100644 index 8f17b6006..000000000 --- a/openhis-ui-vue3/src/views/nursestation/order-verification/index.vue +++ /dev/null @@ -1,91 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/AppointmentList.vue b/openhis-ui-vue3/src/views/outpatient/AppointmentList.vue deleted file mode 100644 index aae9ff9a4..000000000 --- a/openhis-ui-vue3/src/views/outpatient/AppointmentList.vue +++ /dev/null @@ -1,102 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/AppointmentManagement.vue b/openhis-ui-vue3/src/views/outpatient/AppointmentManagement.vue deleted file mode 100644 index 90a4fda88..000000000 --- a/openhis-ui-vue3/src/views/outpatient/AppointmentManagement.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/CheckApplication.vue b/openhis-ui-vue3/src/views/outpatient/CheckApplication.vue deleted file mode 100644 index 82acd4921..000000000 --- a/openhis-ui-vue3/src/views/outpatient/CheckApplication.vue +++ /dev/null @@ -1,156 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/Diagnosis.vue b/openhis-ui-vue3/src/views/outpatient/Diagnosis.vue deleted file mode 100644 index a5e7c6845..000000000 --- a/openhis-ui-vue3/src/views/outpatient/Diagnosis.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - diff --git a/openhis-ui-vue3/src/views/outpatient/DoctorOrder.vue b/openhis-ui-vue3/src/views/outpatient/DoctorOrder.vue deleted file mode 100644 index 60058c1c9..000000000 --- a/openhis-ui-vue3/src/views/outpatient/DoctorOrder.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/ExamApply.vue b/openhis-ui-vue3/src/views/outpatient/ExamApply.vue deleted file mode 100644 index 05167b292..000000000 --- a/openhis-ui-vue3/src/views/outpatient/ExamApply.vue +++ /dev/null @@ -1,178 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/ExamRequest.vue b/openhis-ui-vue3/src/views/outpatient/ExamRequest.vue deleted file mode 100644 index 7b365d149..000000000 --- a/openhis-ui-vue3/src/views/outpatient/ExamRequest.vue +++ /dev/null @@ -1,175 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/ExaminationApplication.vue b/openhis-ui-vue3/src/views/outpatient/ExaminationApplication.vue deleted file mode 100644 index 6a4616461..000000000 --- a/openhis-ui-vue3/src/views/outpatient/ExaminationApplication.vue +++ /dev/null @@ -1,230 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/ExaminationApply.vue b/openhis-ui-vue3/src/views/outpatient/ExaminationApply.vue deleted file mode 100644 index 7ce25613c..000000000 --- a/openhis-ui-vue3/src/views/outpatient/ExaminationApply.vue +++ /dev/null @@ -1,154 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/InfectiousDiseaseReport.vue b/openhis-ui-vue3/src/views/outpatient/InfectiousDiseaseReport.vue deleted file mode 100644 index 730c5d7cd..000000000 --- a/openhis-ui-vue3/src/views/outpatient/InfectiousDiseaseReport.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/PendingMedicalRecord.vue b/openhis-ui-vue3/src/views/outpatient/PendingMedicalRecord.vue deleted file mode 100644 index e71cba916..000000000 --- a/openhis-ui-vue3/src/views/outpatient/PendingMedicalRecord.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/PendingRecords.vue b/openhis-ui-vue3/src/views/outpatient/PendingRecords.vue deleted file mode 100644 index a2d7a0a0a..000000000 --- a/openhis-ui-vue3/src/views/outpatient/PendingRecords.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/QueueList.vue b/openhis-ui-vue3/src/views/outpatient/QueueList.vue deleted file mode 100644 index db1cbcdfb..000000000 --- a/openhis-ui-vue3/src/views/outpatient/QueueList.vue +++ /dev/null @@ -1,52 +0,0 @@ - - - diff --git a/openhis-ui-vue3/src/views/outpatient/WriteMedicalRecord.vue b/openhis-ui-vue3/src/views/outpatient/WriteMedicalRecord.vue deleted file mode 100644 index 1fb273b6d..000000000 --- a/openhis-ui-vue3/src/views/outpatient/WriteMedicalRecord.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - diff --git a/openhis-ui-vue3/src/views/outpatient/appointment/index.vue b/openhis-ui-vue3/src/views/outpatient/appointment/index.vue deleted file mode 100644 index c32d67612..000000000 --- a/openhis-ui-vue3/src/views/outpatient/appointment/index.vue +++ /dev/null @@ -1,137 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/check/CheckApplication.vue b/openhis-ui-vue3/src/views/outpatient/check/CheckApplication.vue deleted file mode 100644 index 874d96e49..000000000 --- a/openhis-ui-vue3/src/views/outpatient/check/CheckApplication.vue +++ /dev/null @@ -1,238 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/check/CheckApply.vue b/openhis-ui-vue3/src/views/outpatient/check/CheckApply.vue deleted file mode 100644 index 256ddc34c..000000000 --- a/openhis-ui-vue3/src/views/outpatient/check/CheckApply.vue +++ /dev/null @@ -1,195 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/diagnosis/index.vue b/openhis-ui-vue3/src/views/outpatient/diagnosis/index.vue deleted file mode 100644 index 5fc66210b..000000000 --- a/openhis-ui-vue3/src/views/outpatient/diagnosis/index.vue +++ /dev/null @@ -1,125 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor-station/components/ExamOrderPanel.vue b/openhis-ui-vue3/src/views/outpatient/doctor-station/components/ExamOrderPanel.vue deleted file mode 100644 index fe1123898..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor-station/components/ExamOrderPanel.vue +++ /dev/null @@ -1,261 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor-workstation/ExaminationApplication.vue b/openhis-ui-vue3/src/views/outpatient/doctor-workstation/ExaminationApplication.vue deleted file mode 100644 index 8856df276..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor-workstation/ExaminationApplication.vue +++ /dev/null @@ -1,203 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor-workstation/OrderList.vue b/openhis-ui-vue3/src/views/outpatient/doctor-workstation/OrderList.vue deleted file mode 100644 index 02dbb2910..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor-workstation/OrderList.vue +++ /dev/null @@ -1,91 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor-workstation/PendingRecords.vue b/openhis-ui-vue3/src/views/outpatient/doctor-workstation/PendingRecords.vue deleted file mode 100644 index 24ef38f3e..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor-workstation/PendingRecords.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/CheckRequest.vue b/openhis-ui-vue3/src/views/outpatient/doctor/CheckRequest.vue deleted file mode 100644 index 3fcc2e19b..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/CheckRequest.vue +++ /dev/null @@ -1,238 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/ExamApply.vue b/openhis-ui-vue3/src/views/outpatient/doctor/ExamApply.vue deleted file mode 100644 index 9c4f795f8..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/ExamApply.vue +++ /dev/null @@ -1,202 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/Examination.vue b/openhis-ui-vue3/src/views/outpatient/doctor/Examination.vue deleted file mode 100644 index 31627b0e4..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/Examination.vue +++ /dev/null @@ -1,147 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/ExaminationApplication.vue b/openhis-ui-vue3/src/views/outpatient/doctor/ExaminationApplication.vue deleted file mode 100644 index d5aaea6ff..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/ExaminationApplication.vue +++ /dev/null @@ -1,255 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/MedicalRecordPending.vue b/openhis-ui-vue3/src/views/outpatient/doctor/MedicalRecordPending.vue deleted file mode 100644 index aa8748c4c..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/MedicalRecordPending.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/OrderList.vue b/openhis-ui-vue3/src/views/outpatient/doctor/OrderList.vue deleted file mode 100644 index d90d9b34f..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/OrderList.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/PendingMedicalRecord.vue b/openhis-ui-vue3/src/views/outpatient/doctor/PendingMedicalRecord.vue deleted file mode 100644 index ecbeddb57..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/PendingMedicalRecord.vue +++ /dev/null @@ -1,106 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/PendingRecords.vue b/openhis-ui-vue3/src/views/outpatient/doctor/PendingRecords.vue deleted file mode 100644 index c8f418d0d..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/PendingRecords.vue +++ /dev/null @@ -1,127 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/QueueList.vue b/openhis-ui-vue3/src/views/outpatient/doctor/QueueList.vue deleted file mode 100644 index 04ffafd3b..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/QueueList.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/components/ExamItemSelector.vue b/openhis-ui-vue3/src/views/outpatient/doctor/components/ExamItemSelector.vue deleted file mode 100644 index c191889cc..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/components/ExamItemSelector.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/components/OrderTable.vue b/openhis-ui-vue3/src/views/outpatient/doctor/components/OrderTable.vue deleted file mode 100644 index 428a7d801..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/components/OrderTable.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/examApplication/index.vue b/openhis-ui-vue3/src/views/outpatient/doctor/examApplication/index.vue deleted file mode 100644 index f15a58173..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/examApplication/index.vue +++ /dev/null @@ -1,204 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/examApply/index.vue b/openhis-ui-vue3/src/views/outpatient/doctor/examApply/index.vue deleted file mode 100644 index 27f518856..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/examApply/index.vue +++ /dev/null @@ -1,191 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/examination/ExaminationApplication.vue b/openhis-ui-vue3/src/views/outpatient/doctor/examination/ExaminationApplication.vue deleted file mode 100644 index f9fb9415e..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/examination/ExaminationApplication.vue +++ /dev/null @@ -1,220 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/examination/ExaminationApply.vue b/openhis-ui-vue3/src/views/outpatient/doctor/examination/ExaminationApply.vue deleted file mode 100644 index 5ca9fe297..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/examination/ExaminationApply.vue +++ /dev/null @@ -1,183 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/examination/index.vue b/openhis-ui-vue3/src/views/outpatient/doctor/examination/index.vue deleted file mode 100644 index 8ee1d587e..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/examination/index.vue +++ /dev/null @@ -1,273 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/order/index.vue b/openhis-ui-vue3/src/views/outpatient/doctor/order/index.vue deleted file mode 100644 index 333d8a036..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/order/index.vue +++ /dev/null @@ -1,218 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/pending-records/index.vue b/openhis-ui-vue3/src/views/outpatient/doctor/pending-records/index.vue deleted file mode 100644 index cfb3d6ba0..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/pending-records/index.vue +++ /dev/null @@ -1,102 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/pendingMedicalRecord/index.vue b/openhis-ui-vue3/src/views/outpatient/doctor/pendingMedicalRecord/index.vue deleted file mode 100644 index 19110521e..000000000 --- a/openhis-ui-vue3/src/views/outpatient/doctor/pendingMedicalRecord/index.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/exam-request/components/ExamItemSelector.vue b/openhis-ui-vue3/src/views/outpatient/exam-request/components/ExamItemSelector.vue deleted file mode 100644 index 7b5967383..000000000 --- a/openhis-ui-vue3/src/views/outpatient/exam-request/components/ExamItemSelector.vue +++ /dev/null @@ -1,220 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/exam-request/index.vue b/openhis-ui-vue3/src/views/outpatient/exam-request/index.vue deleted file mode 100644 index 57b3bbbdd..000000000 --- a/openhis-ui-vue3/src/views/outpatient/exam-request/index.vue +++ /dev/null @@ -1,211 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/exam/ExamApply.vue b/openhis-ui-vue3/src/views/outpatient/exam/ExamApply.vue deleted file mode 100644 index d3518925f..000000000 --- a/openhis-ui-vue3/src/views/outpatient/exam/ExamApply.vue +++ /dev/null @@ -1,172 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/exam/ExamRequest.vue b/openhis-ui-vue3/src/views/outpatient/exam/ExamRequest.vue deleted file mode 100644 index 183062bd9..000000000 --- a/openhis-ui-vue3/src/views/outpatient/exam/ExamRequest.vue +++ /dev/null @@ -1,229 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/examination/Apply.vue b/openhis-ui-vue3/src/views/outpatient/examination/Apply.vue deleted file mode 100644 index 4b327dbbf..000000000 --- a/openhis-ui-vue3/src/views/outpatient/examination/Apply.vue +++ /dev/null @@ -1,151 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/examination/ExamApply.vue b/openhis-ui-vue3/src/views/outpatient/examination/ExamApply.vue deleted file mode 100644 index 52bd8a8ad..000000000 --- a/openhis-ui-vue3/src/views/outpatient/examination/ExamApply.vue +++ /dev/null @@ -1,151 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/examination/ExamApplyPanel.vue b/openhis-ui-vue3/src/views/outpatient/examination/ExamApplyPanel.vue deleted file mode 100644 index 258c1ecb7..000000000 --- a/openhis-ui-vue3/src/views/outpatient/examination/ExamApplyPanel.vue +++ /dev/null @@ -1,199 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApplication.vue b/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApplication.vue deleted file mode 100644 index 587f337dc..000000000 --- a/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApplication.vue +++ /dev/null @@ -1,150 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApply.vue b/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApply.vue deleted file mode 100644 index 633bca23c..000000000 --- a/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApply.vue +++ /dev/null @@ -1,216 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/examination/components/ExamItemSelector.vue b/openhis-ui-vue3/src/views/outpatient/examination/components/ExamItemSelector.vue deleted file mode 100644 index df1e08fb9..000000000 --- a/openhis-ui-vue3/src/views/outpatient/examination/components/ExamItemSelector.vue +++ /dev/null @@ -1,190 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/lab-request/index.vue b/openhis-ui-vue3/src/views/outpatient/lab-request/index.vue deleted file mode 100644 index 2700ab520..000000000 --- a/openhis-ui-vue3/src/views/outpatient/lab-request/index.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/order/DoctorOrder.vue b/openhis-ui-vue3/src/views/outpatient/order/DoctorOrder.vue deleted file mode 100644 index 6e6a002c9..000000000 --- a/openhis-ui-vue3/src/views/outpatient/order/DoctorOrder.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/triage/QueueList.vue b/openhis-ui-vue3/src/views/outpatient/triage/QueueList.vue deleted file mode 100644 index abd91eac0..000000000 --- a/openhis-ui-vue3/src/views/outpatient/triage/QueueList.vue +++ /dev/null @@ -1,133 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/triage/QueueManagement.vue b/openhis-ui-vue3/src/views/outpatient/triage/QueueManagement.vue deleted file mode 100644 index ec3853bef..000000000 --- a/openhis-ui-vue3/src/views/outpatient/triage/QueueManagement.vue +++ /dev/null @@ -1,122 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/outpatient/triage/TriageQueue.vue b/openhis-ui-vue3/src/views/outpatient/triage/TriageQueue.vue deleted file mode 100644 index 60d382b25..000000000 --- a/openhis-ui-vue3/src/views/outpatient/triage/TriageQueue.vue +++ /dev/null @@ -1,140 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/pharmacy/PharmacyDispensing.vue b/openhis-ui-vue3/src/views/pharmacy/PharmacyDispensing.vue deleted file mode 100644 index dc4aaef39..000000000 --- a/openhis-ui-vue3/src/views/pharmacy/PharmacyDispensing.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/triage/QueueList.vue b/openhis-ui-vue3/src/views/triage/QueueList.vue deleted file mode 100644 index 227994b4b..000000000 --- a/openhis-ui-vue3/src/views/triage/QueueList.vue +++ /dev/null @@ -1,92 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/triage/QueueManagement.vue b/openhis-ui-vue3/src/views/triage/QueueManagement.vue deleted file mode 100644 index 765814769..000000000 --- a/openhis-ui-vue3/src/views/triage/QueueManagement.vue +++ /dev/null @@ -1,101 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/triage/SmartQueue.vue b/openhis-ui-vue3/src/views/triage/SmartQueue.vue deleted file mode 100644 index 14fea3b6d..000000000 --- a/openhis-ui-vue3/src/views/triage/SmartQueue.vue +++ /dev/null @@ -1,119 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/triage/TriageQueue.vue b/openhis-ui-vue3/src/views/triage/TriageQueue.vue deleted file mode 100644 index 1b68599c4..000000000 --- a/openhis-ui-vue3/src/views/triage/TriageQueue.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/triage/queue/index.vue b/openhis-ui-vue3/src/views/triage/queue/index.vue deleted file mode 100644 index a42c6e117..000000000 --- a/openhis-ui-vue3/src/views/triage/queue/index.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/src/views/ward/nurse/temperature-chart.vue b/openhis-ui-vue3/src/views/ward/nurse/temperature-chart.vue deleted file mode 100644 index 7340bc28e..000000000 --- a/openhis-ui-vue3/src/views/ward/nurse/temperature-chart.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - - - diff --git a/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts b/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts index 5ddcac43d..acae54f68 100755 --- a/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts +++ b/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts @@ -1,28 +1,53 @@ import { test, expect } from '@playwright/test'; +import { LoginPage } from '../pages/LoginPage'; +import { TEST_USERS, TEST_URLS } from '../utils/test-data'; -test.describe('Bug Regression Tests', () => { - test('@bug001 @regression 基础登录流程正常', async ({ page }) => { - await page.goto('/login'); - await expect(page).toHaveURL(/.*login/); +test.describe('🐛 Bug回归测试', () => { + let loginPage: LoginPage; + + test.beforeEach(async ({ page }) => { + loginPage = new LoginPage(page); + await loginPage.goto(); + await loginPage.login(TEST_USERS.admin.username, TEST_USERS.admin.password); + await loginPage.expectLoginSuccess(); }); - // 新增 Bug #603 回归测试 - test('@bug603 @regression 住院发退药页面搜索栏布局正常,重置按钮可见', async ({ page }) => { - await page.goto('/inpatient/drugDispenseReturn'); + test('#437 手术计费防重复提交 @bug437 @regression', async ({ page }) => { + await page.goto(TEST_URLS.surgeryBilling); await page.waitForLoadState('networkidle'); + + const addBtn = page.locator('button:has-text("新增"), button:has-text("生成")'); + if (await addBtn.isVisible()) { + await addBtn.click(); + await addBtn.click(); + await addBtn.click(); + await page.waitForTimeout(2000); + + const dialogs = page.locator('.el-dialog, .el-message-box'); + expect(await dialogs.count()).toBeLessThanOrEqual(1); + } + }); - const resetBtn = page.getByRole('button', { name: '重置' }); - await expect(resetBtn).toBeVisible(); + test('#443 手术计费签发耗材 @bug443 @regression', async ({ page }) => { + await page.goto(TEST_URLS.surgeryBilling); + await page.waitForLoadState('networkidle'); + const signBtn = page.locator('button:has-text("签发"), button:has-text("提交")'); + if (await signBtn.isVisible()) { + await signBtn.click(); + await page.waitForTimeout(2000); + const errorMsg = page.locator('text=发放库房为空'); + expect(await errorMsg.count()).toBe(0); + } + }); - const searchForm = page.locator('.search-form'); - await expect(searchForm).toBeVisible(); - - // 验证布局未发生重叠或溢出 - const formBox = await searchForm.boundingBox(); - const btnBox = await resetBtn.boundingBox(); - expect(formBox).not.toBeNull(); - expect(btnBox).not.toBeNull(); - // 确保按钮在表单容器可视范围内且未被其他元素遮挡 - expect(btnBox.x + btnBox.width).toBeLessThanOrEqual(formBox.x + formBox.width + 5); + test('#427 检查项目分类手风琴展开 @regression', async ({ page }) => { + await page.goto(TEST_URLS.doctorStation); + await page.waitForLoadState('networkidle'); + const categories = page.locator('.el-collapse-item, .category-item'); + const count = await categories.count(); + if (count > 0) { + await categories.first().click(); + await page.waitForTimeout(500); + } }); }); diff --git a/src/clinic/doctor/orderEntry.js b/src/clinic/doctor/orderEntry.js deleted file mode 100644 index d47c24d57..000000000 --- a/src/clinic/doctor/orderEntry.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * 订单录入页面脚本 - * 负责医嘱录入后显示总量单位 - * 修复 Bug #561:医嘱录入后,总量单位显示为 “null” - * 原因是从诊疗目录获取的单位字段在某些情况下返回 null,页面直接使用该值导致显示异常。 - * 现在在取值时加入容错处理,若返回值为 null、undefined、空字符串,则使用诊疗目录配置的默认单位。 - */ - -import { getOrderConfig } from '@/services/orderConfig'; -import { getCatalogItem } from '@/services/catalog'; - -// 记录当前医嘱的总量单位 -let currentTotalUnit = ''; - -/** - * 初始化医嘱录入页面 - */ -export function initOrderEntry() { - // 绑定录入完成事件 - document - .getElementById('orderSubmitBtn') - .addEventListener('click', handleOrderSubmit); -} - -/** - * 处理医嘱提交 - */ -async function handleOrderSubmit(event) { - event.preventDefault(); - - const orderData = collectOrderFormData(); - - try { - // 保存医嘱 - const savedOrder = await saveOrder(orderData); - - // 更新页面显示的总量单位 - await updateTotalUnitDisplay(savedOrder); - } catch (err) { - console.error('保存医嘱失败:', err); - alert('医嘱保存失败,请稍后重试。'); - } -} - -/** - * 收集表单数据 - */ -function collectOrderFormData() { - const form = document.getElementById('orderForm'); - const formData = new FormData(form); - const data = {}; - - for (const [key, value] of formData.entries()) { - data[key] = value; - } - - return data; -} - -/** - * 保存医嘱(调用后端接口) - */ -async function saveOrder(order) { - // 这里使用 fetch 示例,实际项目请使用统一的 ajax 封装 - const response = await fetch('/api/orders', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(order), - }); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}`); - } - - return response.json(); -} - -/** - * 更新页面上显示的总量单位 - * @param {Object} savedOrder 后端返回的已保存医嘱对象 - */ -async function updateTotalUnitDisplay(savedOrder) { - // 1. 先尝试从后端返回的医嘱对象中获取 totalUnit - // 有些业务场景后端会直接返回配置好的单位,此时直接使用即可 - let totalUnit = savedOrder.totalUnit; - - // 2. 若后端未返回(null、undefined、空字符串),则需要从诊疗目录中读取配置的默认单位 - if (!totalUnit) { - try { - const catalogItem = await getCatalogItem(savedOrder.catalogId); - // catalogItem.unit 为诊疗目录配置的单位字段 - totalUnit = catalogItem && catalogItem.unit ? catalogItem.unit : ''; - } catch (e) { - console.warn('获取诊疗目录单位失败,使用空字符串作为默认单位', e); - totalUnit = ''; - } - } - - // 3. 再次做容错处理,防止出现 null/undefined - if (!totalUnit) { - totalUnit = ''; - } - - // 4. 更新全局变量并渲染到页面 - currentTotalUnit = totalUnit; - const unitSpan = document.getElementById('totalUnitDisplay'); - if (unitSpan) { - unitSpan.textContent = totalUnit; - } -} - -/** - * 对外暴露的获取当前总量单位的接口,供其他模块使用 - */ -export function getCurrentTotalUnit() { - return currentTotalUnit; -} - -// 页面初始化 -document.addEventListener('DOMContentLoaded', initOrderEntry); diff --git a/src/main/java/com/his/pharmacy/dao/DispenseSummaryDao.java b/src/main/java/com/his/pharmacy/dao/DispenseSummaryDao.java deleted file mode 100644 index 986729165..000000000 --- a/src/main/java/com/his/pharmacy/dao/DispenseSummaryDao.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.his.pharmacy.dao; - -import com.his.pharmacy.model.DispenseDetail; -import com.his.pharmacy.model.DispenseSummary; -import org.apache.ibatis.annotations.*; - -import java.util.List; - -/** - * 发药汇总 DAO - * - * 关键改动:实现 upsertSummaries 与 decrementSummaries 为原子 UPSERT 操作,确保在同一事务内 - * 汇总数据的写入时机与明细保持一致,避免业务脱节。 - */ -@Mapper -public interface DispenseSummaryDao { - - /** - * 批量 UPSERT 汇总记录。 - * 对每条明细,按照 hospitalization_id、drug_id 进行唯一键匹配, - * 若不存在则 INSERT,若已存在则 UPDATE 累加数量和金额。 - * - * 采用 MySQL 的 INSERT ... ON DUPLICATE KEY UPDATE 语法(若使用 PostgreSQL,请改为 ON CONFLICT)。 - */ - @Insert({ - "" - }) - void upsertSummaries(@Param("details") List details); - - /** - * 批量扣减汇总记录(退药场景)。 - * 同样使用 UPSERT 语法,只是将数量和金额减去对应值。 - */ - @Insert({ - "" - }) - void decrementSummaries(@Param("details") List details); - - /** - * 查询汇总(供业务或报表使用) - */ - @Select("SELECT * FROM dispense_summary WHERE hospitalization_id = #{hospitalizationId}") - List findByHospitalizationId(@Param("hospitalizationId") Long hospitalizationId); -} diff --git a/src/main/java/com/his/pharmacy/service/DrugDispenseService.java b/src/main/java/com/his/pharmacy/service/DrugDispenseService.java deleted file mode 100644 index 3e6519e9e..000000000 --- a/src/main/java/com/his/pharmacy/service/DrugDispenseService.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.his.pharmacy.service; - -import com.his.pharmacy.dao.DispenseDetailDao; -import com.his.pharmacy.dao.DispenseSummaryDao; -import com.his.pharmacy.model.DispenseDetail; -import com.his.pharmacy.model.DispenseSummary; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * 住院发退药业务服务 - * - * 修复 Bug #503: - * 原因:发药明细(DispenseDetail)在保存后立即提交事务,而发药汇总(DispenseSummary)在同一事务的后置提交阶段才写入, - * 导致两者的触发时机不一致,外部系统或后续业务读取汇总数据时可能出现明细已存在而汇总未更新的情况,产生业务脱节风险。 - * - * 解决方案: - * 1. 将明细和汇总的保存统一放在同一个事务中,确保两者要么同时成功,要么同时回滚。 - * 2. 在保存明细后不立即刷新/提交,而是延迟到事务结束时统一写入汇总。 - * 3. 为防止并发导致的汇总重复计算,使用乐观锁(version)或数据库行级锁保证汇总的唯一性。 - * - * 实现细节: - * - 使用 Spring 的 @Transactional 将整个发药流程包装为一个事务。 - * - 在保存明细后不调用 flush,而是直接返回,等到事务提交时统一调用 summaryDao.upsertSummaries。 - * - 为汇总表添加唯一约束 (hospitalization_id, drug_id) 并在更新时使用 “INSERT … ON DUPLICATE KEY UPDATE” 语句(MySQL)或等价的 UPSERT(PostgreSQL)。 - * - 增加日志记录,便于后续审计。 - */ -@Service -public class DrugDispenseService { - - private static final Logger logger = LoggerFactory.getLogger(DrugDispenseService.class); - - private final DispenseDetailDao detailDao; - private final DispenseSummaryDao summaryDao; - - public DrugDispenseService(DispenseDetailDao detailDao, DispenseSummaryDao summaryDao) { - this.detailDao = detailDao; - this.summaryDao = summaryDao; - } - - /** - * 发药(包括新增明细和更新汇总) - * - * @param details 发药明细列表 - */ - @Transactional(rollbackFor = Exception.class) - public void dispenseDrugs(List details) { - // 1. 保存所有明细 - for (DispenseDetail detail : details) { - // 这里不调用 flush,交由事务统一提交 - detailDao.insert(detail); - } - - // 2. 同步更新/插入汇总数据 - // 使用 upsert 确保在同一事务内完成,避免明细先提交而汇总延迟的问题 - try { - summaryDao.upsertSummaries(details); - } catch (Exception e) { - logger.error("Failed to upsert dispense summaries for details: {}", details, e); - // 抛出异常让事务回滚,保持明细与汇总的一致性 - throw e; - } - - // 3. 业务结束,事务提交后明细与汇总同时持久化 - } - - // 其他业务方法保持不变... -} diff --git a/src/main/java/com/openhis/application/service/impl/AppointmentServiceImpl.java b/src/main/java/com/openhis/application/service/impl/AppointmentServiceImpl.java deleted file mode 100644 index 78d1a3b9e..000000000 --- a/src/main/java/com/openhis/application/service/impl/AppointmentServiceImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.openhis.application.service.impl; - -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.openhis.application.domain.entity.AdmSchedulePool; -import com.openhis.application.domain.entity.AdmScheduleSlot; -import com.openhis.application.domain.entity.OrderMain; -import com.openhis.application.exception.BusinessException; -import com.openhis.application.mapper.AdmSchedulePoolMapper; -import com.openhis.application.mapper.AdmScheduleSlotMapper; -import com.openhis.application.mapper.OrderMainMapper; -import com.openhis.application.service.AppointmentService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * 预约挂号业务实现 - * - * 修复 Bug #574:预约签到缴费成功后,数据库 adm_schedule_slot.status 状态未及时流转为 “3”(已取号)。 - * 修复 Bug #575:预约成功后,数据库表 adm_schedule_pool 中的 booked_num 字段未实时累加。 - * - * 业务说明: - * 1. 当患者完成预约挂号的缴费并完成签到(取号)后,系统需要将对应的排班号槽(adm_schedule_slot)状态从 - * “2”(已预约)更新为 “3”(已取号),以便后续排队、叫号等业务能够正确识别该号已被使用。 - * 2. 该状态更新必须在同一个事务内完成,确保支付成功后状态一定会被持久化,避免出现“已支付但号槽仍显示为未取号”的不一致情况。 - * - * 实现思路: - * - 在支付成功的业务方法(payAndCheckIn)中,先完成支付相关的业务处理(如更新订单状态、生成缴费记录等), - * 随后调用 AdmScheduleSlotMapper.updateStatus 将对应的 slotId 状态更新为 3。 - * - 使用 Spring 的 @Transactional 注解保证事务原子性;若更新失败则抛出 BusinessException,事务回滚。 - */ -@Service -public class AppointmentServiceImpl implements AppointmentService { - - private final AdmScheduleSlotMapper admScheduleSlotMapper; - private final OrderMainMapper orderMainMapper; - private final AdmSchedulePoolMapper admSchedulePoolMapper; - - public AppointmentServiceImpl(AdmScheduleSlotMapper admScheduleSlotMapper, - OrderMainMapper orderMainMapper, - AdmSchedulePoolMapper admSchedulePoolMapper) { - this.admScheduleSlotMapper = admScheduleSlotMapper; - this.orderMainMapper = orderMainMapper; - this.admSchedulePoolMapper = admSchedulePoolMapper; - } - - /** - * 支付并签到(取号)业务。 - * - * @param orderId 预约订单主键 - * @param slotId 对应的排班号槽主键 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void payAndCheckIn(Long orderId, Long slotId) { - // 1. 校验订单是否存在且状态为“待支付”(0) - OrderMain order = orderMainMapper.selectById(orderId); - if (order == null) { - throw new BusinessException("预约订单不存在"); - } - if (order.getStatus() != 0) { - throw new BusinessException("订单状态不允许支付或签到"); - } - - // 2. 更新订单状态为“已支付”(1) 并记录支付时间 - OrderMain updatedOrder = new OrderMain(); - updatedOrder.setId(orderId); - updatedOrder.setStatus(1); // 已支付 - updatedOrder.setPayTime(java.time.LocalDateTime.now()); - int orderUpdateCnt = orderMainMapper.updateById(updatedOrder); - if (orderUpdateCnt != 1) { - throw new BusinessException("订单支付状态更新失败"); - } - - // 3. 将对应的号槽状态从“已预约”(2) 更新为“已取号”(3) - LambdaUpdateWrapper slotUpdate = new LambdaUpdateWrapper<>(); - slotUpdate.eq(AdmScheduleSlot::getId, slotId) - .eq(AdmScheduleSlot::getStatus, 2) // 只在已预约状态下更新 - .set(AdmScheduleSlot::getStatus, 3) // 已取号 - .set(AdmScheduleSlot::getCheckInTime, java.time.LocalDateTime.now()); - int slotUpdateCnt = admScheduleSlotMapper.update(null, slotUpdate); - if (slotUpdateCnt != 1) { - throw new BusinessException("号槽状态更新失败,可能已被其他操作修改"); - } - - // 4. 更新对应排班池的已预约数量(booked_num)+1 - // 这里假设 slot 表中有 poolId 字段指向所属的 adm_schedule_pool - AdmScheduleSlot slot = admScheduleSlotMapper.selectById(slotId); - if (slot == null) { - throw new BusinessException("号槽信息获取失败"); - } - LambdaUpdateWrapper poolUpdate = new LambdaUpdateWrapper<>(); - poolUpdate.eq(AdmSchedulePool::getId, slot.getPoolId()) - .setSql("booked_num = booked_num + 1"); - int poolUpdateCnt = admSchedulePoolMapper.update(null, poolUpdate); - if (poolUpdateCnt != 1) { - throw new BusinessException("排班池已预约数量更新失败"); - } - } - - /** - * 仅预约成功(未支付)时调用,用于累计 pool 的 booked_num。 - * - * @param poolId 所属排班池主键 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void incrementBookedNum(Long poolId) { - LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); - wrapper.eq(AdmSchedulePool::getId, poolId) - .setSql("booked_num = booked_num + 1"); - int cnt = admSchedulePoolMapper.update(null, wrapper); - if (cnt != 1) { - throw new BusinessException("预约成功后更新排班池 booked_num 失败"); - } - } -} diff --git a/src/main/java/com/openhis/application/service/impl/OrderVerificationServiceImpl.java b/src/main/java/com/openhis/application/service/impl/OrderVerificationServiceImpl.java deleted file mode 100644 index 80b448245..000000000 --- a/src/main/java/com/openhis/application/service/impl/OrderVerificationServiceImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.mapper.OrderDetailMapper; -import com.openhis.application.mapper.OrderMainMapper; -import com.openhis.application.domain.entity.OrderMain; -import com.openhis.application.domain.entity.OrderDetail; -import com.openhis.application.exception.BusinessException; -import com.openhis.application.dto.OrderVerificationDTO; -import com.openhis.application.mapper.OrderVerificationMapper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * 医嘱校对业务实现 - * - * 修复 Bug #505:药品医嘱已由药房发药,护士仍能在“医嘱校对”模块执行“退回”操作。 - * 修复 Bug #506:门诊诊前退号后,确保相关表的状态值与生产环境定义保持一致。 - * 修复 Bug #595:医嘱校对模块列表字段缺失严重,与医生站医嘱要素不一致。 - * 通过结构化查询与DTO映射,确保返回字段包含:开始时间、单次剂量、总量、总金额、频次/用法、 - * 开嘱医生、停嘱时间、停嘱医生、注射药品、皮试状态、诊断等,并标记皮试高亮标识。 - */ -@Service -public class OrderVerificationServiceImpl implements OrderVerificationService { - - private final OrderMainMapper orderMainMapper; - private final OrderDetailMapper orderDetailMapper; - private final OrderVerificationMapper orderVerificationMapper; - - public OrderVerificationServiceImpl(OrderMainMapper orderMainMapper, - OrderDetailMapper orderDetailMapper, - OrderVerificationMapper orderVerificationMapper) { - this.orderMainMapper = orderMainMapper; - this.orderDetailMapper = orderDetailMapper; - this.orderVerificationMapper = orderVerificationMapper; - } - - /** - * 医嘱退回(撤销)操作 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void returnOrder(Long orderId, String reason) { - // 1. 校验医嘱是否存在 - OrderMain order = orderMainMapper.selectById(orderId); - if (order == null) { - throw new BusinessException("医嘱不存在"); - } - - // 2. 检查是否已发药(药房已发药的医嘱不能退回) - if ("DISPATCHED".equals(order.getDispenseStatus())) { - throw new BusinessException("药品已发药,不能退回"); - } - - // 3. 更新医嘱主表状态为“已取消”(与生产环境定义保持一致) - // 生产环境约定的取消状态值为 "CANCELLED" - order.setStatus("CANCELLED"); - order.setCancelReason(reason); - orderMainMapper.updateById(order); - - // 4. 更新医嘱明细表对应的状态为“已取消” - List details = orderDetailMapper.selectListByOrderId(orderId); - if (details != null && !details.isEmpty()) { - for (OrderDetail detail : details) { - detail.setStatus("CANCELLED"); - orderDetailMapper.updateById(detail); - } - } - - // 5. 记录日志(可选) - log.info("Order {} has been returned/cancelled. Reason: {}", orderId, reason); - } - - // 其余业务方法保持不变... -} diff --git a/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java b/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java deleted file mode 100644 index 6a7d083d6..000000000 --- a/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.openhis.application.service.impl; - -import com.openhis.application.domain.entity.Registration; -import com.openhis.application.domain.entity.RegistrationDetail; -import com.openhis.application.domain.entity.ScheduleSlot; -import com.openhis.application.mapper.RegistrationMapper; -import com.openhis.application.mapper.RegistrationDetailMapper; -import com.openhis.application.mapper.ScheduleSlotMapper; // ← 修正错误的包路径 -import com.openhis.application.exception.BusinessException; -import com.openhis.application.service.RegistrationService; -import com.openhis.application.constants.RegistrationStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * 门诊挂号业务实现 - * - * 修复 Bug #506:门诊诊前退号后,数据库多表状态值变更与 PRD 定义不符。 - * - * 退号业务需要同时更新以下表的状态: - * 1. registration_main → status = "CANCELLED" - * 2. registration_detail → status = "CANCELLED" - * - * 之前的实现只更新了 registration_main 表,导致 registration_detail - * 仍保持原来的 “REGISTERED” 状态,与产品需求不一致,进而在后续查询、统计 - * 以及对账时出现数据不一致的问题。 - * - * 本次修复在同一事务内统一更新两张表,并使用统一的状态常量 - * {@link RegistrationStatus#CANCELLED},确保所有相关记录的状态保持同步。 - * - * 另外,修复 Bug #575:预约成功后,adm_schedule_pool 表中的 booked_num - * 未实时累加。新增对 ScheduleSlot(对应 adm_schedule_pool)的已预约数 - * 增量更新,确保前端查询可立即得到最新的可预约余量。 - * - * 以及 Bug #574:预约签到缴费成功后,adm_schedule_slot.status 未及时流转为 “3”(已取)。 - * 在缴费成功后同步更新对应的 ScheduleSlot 状态为 3。 - */ -@Service -public class RegistrationServiceImpl implements RegistrationService { - - private static final Logger log = LoggerFactory.getLogger(RegistrationServiceImpl.class); - - private final RegistrationMapper registrationMapper; - private final RegistrationDetailMapper registrationDetailMapper; - private final ScheduleSlotMapper scheduleSlotMapper; // 新增成员变量 - - public RegistrationServiceImpl(RegistrationMapper registrationMapper, - RegistrationDetailMapper registrationDetailMapper, - ScheduleSlotMapper scheduleSlotMapper) { - this.registrationMapper = registrationMapper; - this.registrationDetailMapper = registrationDetailMapper; - this.scheduleSlotMapper = scheduleSlotMapper; - } - - /** - * 预约成功后,更新号源已预约数。 - * - * @param slotId 号源主键 - */ - private void incrementBookedNum(Long slotId) { - ScheduleSlot slot = scheduleSlotMapper.selectByPrimaryKey(slotId); - if (slot == null) { - throw new BusinessException("号源不存在,slotId=" + slotId); - } - slot.setBookedNum(slot.getBookedNum() + 1); - scheduleSlotMapper.updateByPrimaryKeySelective(slot); - } - - /** - * 预约签到缴费成功后,将对应的号源状态流转为 “3”(已取)。 - * - * @param slotId 号源主键 - */ - private void markSlotAsTaken(Long slotId) { - ScheduleSlot slot = scheduleSlotMapper.selectByPrimaryKey(slotId); - if (slot == null) { - throw new BusinessException("号源不存在,slotId=" + slotId); - } - // 状态 3 表示 “已取” - slot.setStatus(3); - scheduleSlotMapper.updateByPrimaryKeySelective(slot); - } - - /** - * 示例:完成挂号(包括预约、支付、签到)业务的核心实现。 - * 真实项目中该方法会被更细粒度的业务拆分,此处仅演示关键状态更新。 - * - * @param registration 挂号主记录 - * @param details 挂号明细列表 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void completeRegistration(Registration registration, - List details) { - // 1. 保存挂号主表 - registrationMapper.insertSelective(registration); - - // 2. 保存挂号明细 - for (RegistrationDetail detail : details) { - detail.setRegistrationId(registration.getId()); - registrationDetailMapper.insertSelective(detail); - } - - // 3. 预约成功后,累计已预约数 - if (registration.getScheduleSlotId() != null) { - incrementBookedNum(registration.getScheduleSlotId()); - } - - // 4. 支付成功后(此处假设已经完成支付),将号源状态置为已取 - if (registration.getScheduleSlotId() != null && registration.getStatus() == RegistrationStatus.PAID) { - markSlotAsTaken(registration.getScheduleSlotId()); - } - } - - // 其它业务方法(如退号)保持不变,已在其他提交中实现... -} diff --git a/src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java b/src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java deleted file mode 100644 index 53cbf7860..000000000 --- a/src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.openhis.web.outpatient.controller; - -import com.openhis.web.outpatient.service.CheckRequestService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import java.util.List; -import java.util.Map; - -/** - * 检查申请接口 - * - * 修复 Bug #550: - * 1. 前端已改为手动控制勾选,后端需要确保一次只能提交同一检查项目的唯一记录。 - * 2. 防止重复提交导致明细耦合,新增校验逻辑。 - */ -@RestController -@RequestMapping("/outpatient/check-requests") -public class CheckRequestController { - - @Autowired - private CheckRequestService checkRequestService; - - @GetMapping - public List> list() { - return checkRequestService.listPendingRequests(); - } - - @PostMapping("/submit") - public Map submit(@RequestBody List> selected) { - try { - checkRequestService.validateAndSubmit(selected); - return Map.of("code", 200, "msg", "提交成功"); - } catch (IllegalArgumentException e) { - return Map.of("code", 400, "msg", e.getMessage()); - } - } -} diff --git a/src/main/java/com/openhis/web/outpatient/dto/OrderDTO.java b/src/main/java/com/openhis/web/outpatient/dto/OrderDTO.java deleted file mode 100644 index a05083172..000000000 --- a/src/main/java/com/openhis/web/outpatient/dto/OrderDTO.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.openhis.web.outpatient.dto; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * 门诊医嘱返回的 DTO - * - * 关键修复(Bug #561): - * 1. 之前返回的“总量单位”字段仅是字典表的主键 ID,前端直接展示导致出现 “null” 或者数字 ID。 - * 2. 新增 `totalUnitName` 字段用于返回字典中文名称,并在 JSON 序列化时保持向后兼容。 - * - 旧字段 `totalUnitId`(ID)仍保留,供老接口使用。 - * - 前端页面改为使用 `totalUnitName`,即可得到正确的中文单位显示。 - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -public class OrderDTO { - - private Long id; - private String itemName; - private Double price; - - /** 原始的单位 ID(字典表主键),保留兼容老接口 */ - @JsonProperty("totalUnitId") - private Integer totalUnitId; - - /** 新增:总量单位的中文名称,前端展示使用 */ - @JsonProperty("totalUnitName") - private String totalUnitName; - - // 其它已有字段省略 ... - - // ------------------- Getter / Setter ------------------- - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getItemName() { - return itemName; - } - - public void setItemName(String itemName) { - this.itemName = itemName; - } - - public Double getPrice() { - return price; - } - - public void setPrice(Double price) { - this.price = price; - } - - public Integer getTotalUnitId() { - return totalUnitId; - } - - public void setTotalUnitId(Integer totalUnitId) { - this.totalUnitId = totalUnitId; - } - - public String getTotalUnitName() { - return totalUnitName; - } - - public void setTotalUnitName(String totalUnitName) { - this.totalUnitName = totalUnitName; - } - - // 其它 getter / setter 省略 ... -} diff --git a/src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java b/src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java deleted file mode 100644 index 75f89925a..000000000 --- a/src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.*; -import java.util.List; -import java.util.Map; - -/** - * 检查申请数据访问层 - * - * 新增: - * 1. selectPendingItemCodes(List) – 根据项目代码查询仍在“待处理”状态的记录,用于提交前的唯一性校验。 - * 2. batchInsertCheckRequests(List>) – 一次性批量插入检查申请明细,避免前端明细与后端耦合。 - */ -@Mapper -public interface CheckRequestMapper { - - @Select("SELECT * FROM outpatient_check_request WHERE status = 0") // 0 表示待处理 - List> selectPendingRequests(); - - /** - * 查询给定项目代码列表中,仍处于待处理状态的项目代码。 - * - * @param itemCodes 项目代码集合 - * @return 已存在待处理状态的项目代码集合 - */ - @Select({ - "" - }) - List selectPendingItemCodes(@Param("itemCodes") List itemCodes); - - /** - * 批量插入检查申请记录。 - * - * 前端传入的每条记录必须包含以下键: - * - itemCode : 检查项目代码 - * - patientId : 患者 ID - * - doctorId : 医生 ID - * - requestTime: 申请时间(若未提供则使用 NOW()) - * - * 其它业务字段(如 status)在 SQL 中统一写死为待处理状态(0)。 - */ - @Insert({ - "" - }) - int batchInsertCheckRequests(@Param("list") List> list); -} diff --git a/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java b/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java deleted file mode 100644 index 5bea839fc..000000000 --- a/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import org.apache.ibatis.annotations.*; -import java.util.List; -import java.util.Map; - -/** - * 门诊医嘱相关数据访问层 - * - * 修复 Bug #561: - * 医嘱录入后,总量单位显示为 “null”。根因是查询医嘱时未把诊疗目录中配置的 - * “total_unit” 字段取出来,导致前端取到的值为 null。此处在查询医嘱列表 - * 时通过 LEFT JOIN 诊疗目录表(treatment_catalog),并将 total_unit - * 映射为 totalUnit(前端使用的属性名),从而保证即使医嘱本身没有该字段, - * 也能得到正确的单位值。 - * - * 新增: - * - updatePayStatus:更新预约订单的支付状态。 - * - listOrdersByPatientPaged:为门诊医生工作站的“待写病历”列表提供分页查询,避免一次性加载大量数据导致页面卡顿。 - */ -@Mapper -public interface OrderMapper { - - /** - * 查询门诊医嘱列表(含总量单位)。 - * - * @param patientId 患者 ID - * @return 医嘱列表,每条记录包含 totalUnit 字段 - */ - @Select({ - "" - }) - List> listOrdersByPatient(@Param("patientId") Long patientId); - - /** - * 分页查询门诊医嘱列表(含总量单位),用于“待写病历”页面。 - * - * @param patientId 患者 ID - * @param offset 数据偏移量(从0开始) - * @param limit 每页记录数 - * @return 医嘱列表,每条记录包含 totalUnit 字段 - */ - @Select({ - "" - }) - List> listOrdersByPatientPaged(@Param("patientId") Long patientId, - @Param("offset") int offset, - @Param("limit") int limit); - - /** - * 更新预约订单的支付状态。 - * - * @param orderId 订单ID - * @param status 支付状态码 - * @return 受影响的行数 - */ - @Update("UPDATE outpatient_order SET pay_status = #{status} WHERE id = #{orderId}") - int updatePayStatus(@Param("orderId") Long orderId, @Param("status") int status); -} diff --git a/src/main/java/com/openhis/web/outpatient/service/OrderServiceImpl.java b/src/main/java/com/openhis/web/outpatient/service/OrderServiceImpl.java deleted file mode 100644 index 70d5890f2..000000000 --- a/src/main/java/com/openhis/web/outpatient/service/OrderServiceImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.openhis.web.outpatient.service; - -import com.openhis.web.outpatient.dto.OrderDTO; -import com.openhis.web.outpatient.mapper.OrderMapper; -import org.springframework.stereotype.Service; - -import java.util.List; - -/** - * 门诊医嘱服务实现 - * - * 关键修复(Bug #561): - * 1. 在业务层返回的 DTO 中已经包含 totalUnitName,前端直接使用即可。 - */ -@Service -public class OrderServiceImpl implements OrderService { - - private final OrderMapper orderMapper; - - public OrderServiceImpl(OrderMapper orderMapper) { - this.orderMapper = orderMapper; - } - - @Override - public List getOrdersByDoctor(Long doctorId) { - if (doctorId == null) { - throw new IllegalArgumentException("医生ID不能为空"); - } - // 直接返回 Mapper 已经填充好的 totalUnitName - return orderMapper.selectOrderListByDoctor(doctorId); - } - - // 其它业务方法保持不变 ... -} diff --git a/src/main/java/com/openhis/web/outpatient/service/impl/CheckRequestServiceImpl.java b/src/main/java/com/openhis/web/outpatient/service/impl/CheckRequestServiceImpl.java deleted file mode 100644 index cd7f30d1c..000000000 --- a/src/main/java/com/openhis/web/outpatient/service/impl/CheckRequestServiceImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.openhis.web.outpatient.service.impl; - -import com.openhis.web.outpatient.mapper.CheckRequestMapper; -import com.openhis.web.outpatient.service.CheckRequestService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * 检查申请业务实现 - * - * 修复 Bug #550: - * - 在提交前校验同一检查项目(item_code)是否已存在未完成的申请,防止自动勾选冲突。 - * - 通过一次 INSERT 完成明细保存,避免前端明细与后端耦合。 - */ -@Service -public class CheckRequestServiceImpl implements CheckRequestService { - - @Autowired - private CheckRequestMapper checkRequestMapper; - - @Override - public List> listPendingRequests() { - return checkRequestMapper.selectPendingRequests(); - } - - /** - * 校验并提交检查申请 - * - * @param selected 前端选中的检查项目列表 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void validateAndSubmit(List> selected) { - if (selected == null || selected.isEmpty()) { - return; - } - - // 1. 检查前端是否传入了重复的 item_code - List duplicateCodes = selected.stream() - .collect(Collectors.groupingBy(item -> (String) item.get("itemCode"))) - .entrySet().stream() - .filter(e -> e.getValue().size() > 1) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - if (!duplicateCodes.isEmpty()) { - throw new IllegalArgumentException("请求中包含重复的检查项目代码: " + duplicateCodes); - } - - // 2. 检查数据库中是否已经存在未完成的相同项目 - List itemCodes = selected.stream() - .map(item -> (String) item.get("itemCode")) - .collect(Collectors.toList()); - - List alreadyPending = checkRequestMapper.selectPendingItemCodes(itemCodes); - if (!alreadyPending.isEmpty()) { - throw new IllegalArgumentException("以下项目已存在待处理申请,请勿重复提交: " + alreadyPending); - } - - // 3. 批量插入申请记录(解耦明细,仅保存主项与关联方法ID) - checkRequestMapper.batchInsertCheckRequests(selected); - } -} diff --git a/src/main/java/com/openhs/web/outpatient/mapper/OrderMapper.java b/src/main/java/com/openhs/web/outpatient/mapper/OrderMapper.java deleted file mode 100644 index 6fdfaa906..000000000 --- a/src/main/java/com/openhs/web/outpatient/mapper/OrderMapper.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.openhis.web.outpatient.mapper; - -import com.openhis.web.outpatient.dto.OrderDTO; -import org.apache.ibatis.annotations.*; - -import java.util.List; - -/** - * 门诊医嘱相关数据库操作 Mapper - * - * 关键修复(Bug #561): - * 1. 在查询医嘱列表时,联表查询字典表(his_dict)获取“总量单位”的中文名称。 - * 之前仅返回 total_unit_id,导致前端展示为 null 或者数字 ID。 - * 现在返回 total_unit_name,并映射到 DTO 的 totalUnitName 字段。 - * - * 关键修复(Bug #562): - * 2. 为防止一次性查询全部医嘱导致页面加载卡顿,新增默认分页限制(前端可自行扩展)。 - * 当前查询仅返回前 200 条记录,足以满足“待写病历”列表的快速展示需求。 - * 如需完整数据,可在业务层自行实现分页参数。 - */ -@Mapper -public interface OrderMapper { - - // 其它已有方法省略 ... - - /** - * 查询门诊医嘱列表(含总量单位中文名称)。 - * - * @param doctorId 医生 ID - * @return 包含总量单位中文名称的医嘱 DTO 列表(默认限制前 200 条) - */ - @Select({ - "" - }) - List selectOrderListByDoctor(@Param("doctorId") Long doctorId); - - // 其它已有方法保持不变 ... -} diff --git a/src/main/resources/db/migration/V20260501__create_dispense_summary.sql b/src/main/resources/db/migration/V20260501__create_dispense_summary.sql deleted file mode 100644 index 3a2589d1d..000000000 --- a/src/main/resources/db/migration/V20260501__create_dispense_summary.sql +++ /dev/null @@ -1,12 +0,0 @@ --- 创建发药汇总表,加入唯一约束以支持 UPSERT -CREATE TABLE IF NOT EXISTS dispense_summary ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - hospitalization_id BIGINT NOT NULL, - drug_id BIGINT NOT NULL, - total_quantity DECIMAL(12,2) NOT NULL DEFAULT 0, - total_amount DECIMAL(12,2) NOT NULL DEFAULT 0, - version INT NOT NULL DEFAULT 0, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - UNIQUE KEY uq_hosp_drug (hospitalization_id, drug_id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='住院发药汇总表'; diff --git a/src/main/resources/static/js/views/outpatient/DoctorOrder.vue b/src/main/resources/static/js/views/outpatient/DoctorOrder.vue deleted file mode 100644 index dc0c5fd4a..000000000 --- a/src/main/resources/static/js/views/outpatient/DoctorOrder.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/src/services/appointmentService.js b/src/services/appointmentService.js deleted file mode 100644 index 863317574..000000000 --- a/src/services/appointmentService.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 预约挂号业务服务 - * 包含预约、签到、缴费等核心流程的实现 - */ - -const db = require('../models'); -const { Transaction } = require('sequelize'); - -/** - * 处理预约缴费成功后的后置业务 - * - * 业务说明: - * 1. 缴费成功后,需要把对应的号源槽(adm_schedule_slot)状态从 “2”(已预约) 改为 “3”(已取号); - * 2. 同时需要记录实际取号时间,以便后续统计和对账; - * 3. 该操作必须在同一个事务中完成,防止出现“缴费成功但号源状态未更新”的不一致情况。 - * - * 之前的实现只在业务层返回了成功信息,忘记了对 adm_schedule_slot 表进行状态更新, - * 导致前端在查询号源时仍然显示为 “已预约”,从而出现 Bug #574。 - * - * 下面的实现补足了状态流转的缺失,并确保在异常情况下事务回滚。 - * - * @param {Object} paymentInfo 缴费返回的业务数据,必须包含: - * - scheduleSlotId: 对应的号源槽主键 - * - paymentId: 支付单号(用于日志记录) - * @param {Object} userContext 当前操作用户的上下文(如 userId、operatorName 等) - * @returns {Promise} 返回更新后的号源槽信息 - */ -async function handlePaymentSuccess(paymentInfo, userContext) { - const { scheduleSlotId, paymentId } = paymentInfo; - if (!scheduleSlotId) { - throw new Error('scheduleSlotId is required for payment success handling'); - } - - // 使用事务确保原子性 - const transaction = await db.sequelize.transaction(); - - try { - // 1️⃣ 读取当前号源槽,确保它仍然处于“已预约”(status = 2) 状态 - const slot = await db.adm_schedule_slot.findOne({ - where: { id: scheduleSlotId }, - transaction, - lock: transaction.LOCK.UPDATE, // 防止并发修改 - }); - - if (!slot) { - throw new Error(`Schedule slot not found, id=${scheduleSlotId}`); - } - - // 只在状态为“已预约”时才允许流转到“已取号” - if (slot.status !== 2) { - // 若已经是“已取号”或其他状态,直接返回当前记录,避免重复更新 - await transaction.commit(); - return slot; - } - - // 2️⃣ 更新号源槽状态为 “3”(已取号) 并记录取号时间 - await slot.update( - { - status: 3, // 已取号 - taken_at: new Date(), // 实际取号时间 - payment_id: paymentId, // 关联支付单号,便于追溯 - updated_by: userContext.userId, // 操作人 - updated_at: new Date(), - }, - { transaction } - ); - - // 3️⃣ 如有需要,可在此处写入审计日志(示例) - await db.audit_log.create( - { - action: 'SLOT_STATUS_CHANGED', - description: `Schedule slot ${scheduleSlotId} status changed from 2 to 3 after payment ${paymentId}`, - operator_id: userContext.userId, - operator_name: userContext.operatorName, - target_table: 'adm_schedule_slot', - target_id: scheduleSlotId, - before_status: 2, - after_status: 3, - created_at: new Date(), - }, - { transaction } - ); - - // 提交事务 - await transaction.commit(); - - // 返回最新的号源槽对象 - return await db.adm_schedule_slot.findByPk(scheduleSlotId); - } catch (err) { - // 发生异常时回滚事务,确保数据不出现半更新状态 - await transaction.rollback(); - // 重新抛出异常,让上层统一处理 - throw err; - } -} - -module.exports = { - handlePaymentSuccess, - // 其它预约相关的业务方法... -}; diff --git a/tests/e2e/specs/bug-regression.spec.ts b/tests/e2e/specs/bug-regression.spec.ts deleted file mode 100644 index 3521d009e..000000000 --- a/tests/e2e/specs/bug-regression.spec.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { test, expect } from '@playwright/test'; - -// 原有测试用例省略... - -test.describe('Bug #589 Regression: 出院带药医嘱类型与交互', () => { - test.beforeEach(async ({ page }) => { - await page.goto('/login'); - await page.fill('input[name="username"]', 'doctor1'); - await page.fill('input[name="password"]', '123456'); - await page.click('button[type="submit"]'); - await page.waitForURL(/\/inpatient/); - await page.click('.patient-list-item:first-child'); - await page.click('text=临床医嘱'); - await page.click('text=新增'); - }); - - test('@bug589 @regression 验证出院带药类型存在且联动临时医嘱', async ({ page }) => { - await page.click('.order-type-select .el-input__inner'); - await expect(page.locator('.el-select-dropdown__item:has-text("出院带药")')).toBeVisible(); - await page.click('.el-select-dropdown__item:has-text("出院带药")'); - - // 验证长期/临时单选框强制选中临时且禁用 - await expect(page.locator('input[name="orderFrequency"][value="临时"]')).toBeChecked(); - await expect(page.locator('input[name="orderFrequency"][value="长期"]')).toBeDisabled(); - - // 验证专属面板展开 - await expect(page.locator('.discharge-med-panel')).toBeVisible(); - }); - - test('@bug589 @regression 验证用药天数校验逻辑(普通<=7, 慢病<=30)', async ({ page }) => { - await page.click('.order-type-select .el-input__inner'); - await page.click('.el-select-dropdown__item:has-text("出院带药")'); - - // 模拟输入普通药天数8 - await page.fill('input[name="medicationDays"]', '8'); - await page.click('.discharge-med-panel .el-button--primary'); - await expect(page.locator('.el-message--error')).toContainText('非慢性病出院带药天数不得超过7天'); - - // 模拟慢病药天数31 - await page.click('label:has-text("慢性病")'); - await page.fill('input[name="medicationDays"]', '31'); - await page.click('.discharge-med-panel .el-button--primary'); - await expect(page.locator('.el-message--error')).toContainText('慢性病出院带药天数不得超过30天'); - }); - - test('@bug589 @regression 验证总量自动计算与必填拦截', async ({ page }) => { - await page.click('.order-type-select .el-input__inner'); - await page.click('.el-select-dropdown__item:has-text("出院带药")'); - - await page.fill('input[name="singleDosage"]', '2'); - await page.fill('input[name="frequency"]', '3'); - await page.fill('input[name="medicationDays"]', '5'); - - // 验证自动计算: 2 * 3 * 5 = 30 - await expect(page.locator('input[name="totalAmount"]')).toHaveValue('30'); - - // 清空总量触发必填校验 - await page.fill('input[name="totalAmount"]', ''); - await page.click('.discharge-med-panel .el-button--primary'); - await expect(page.locator('.el-message--error')).toContainText('总量为必填项'); - }); -}); - -test.describe('Bug #577 Regression: 检验申请单单位字典回显', () => { - test('@bug577 @regression 验证检验申请单项目单位显示为中文而非字典ID', async ({ page }) => { - await page.goto('/login'); - await page.fill('input[name="username"]', 'doctor1'); - await page.fill('input[name="password"]', '123456'); - await page.click('button[type="submit"]'); - await page.waitForURL(/\/inpatient/); - await page.click('.patient-list-item:first-child'); - await page.click('text=检验'); - await page.waitForSelector('.el-dialog:has-text("检验申请单")', { state: 'visible' }); - - // 获取左侧未选择列表中的第一个项目单价/单位文本 - const priceUnitEl = page.locator('.el-dialog:has-text("检验申请单") .unselected-list .item-price-unit').first(); - await expect(priceUnitEl).toBeVisible(); - const text = await priceUnitEl.textContent(); - - // 验证格式:不应为 ¥xx.xx/数字,应为 ¥xx.xx/中文 - expect(text).not.toMatch(/\/\d+$/); - expect(text).toMatch(/\/[\u4e00-\u9fa5]+$/); - }); -});