From 5056c8747e90f390b0ff2850754f960ee071150a Mon Sep 17 00:00:00 2001 From: zhaoyun Date: Wed, 27 May 2026 02:05:34 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#550:=20fallback=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CheckRequestController.java | 34 ++++++++++ .../outpatient/mapper/CheckRequestMapper.java | 68 +++++++++++++++++++ .../service/impl/CheckRequestServiceImpl.java | 68 +++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java create mode 100644 src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java create mode 100644 src/main/java/com/openhis/web/outpatient/service/impl/CheckRequestServiceImpl.java diff --git a/src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java b/src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java new file mode 100644 index 000000000..8ac3f5a99 --- /dev/null +++ b/src/main/java/com/openhis/web/outpatient/controller/CheckRequestController.java @@ -0,0 +1,34 @@ +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/src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java b/src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java new file mode 100644 index 000000000..fb45654cc --- /dev/null +++ b/src/main/java/com/openhis/web/outpatient/mapper/CheckRequestMapper.java @@ -0,0 +1,68 @@ +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/service/impl/CheckRequestServiceImpl.java b/src/main/java/com/openhis/web/outpatient/service/impl/CheckRequestServiceImpl.java new file mode 100644 index 000000000..5f18d6b89 --- /dev/null +++ b/src/main/java/com/openhis/web/outpatient/service/impl/CheckRequestServiceImpl.java @@ -0,0 +1,68 @@ +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. 批量插入检查申请明细(一次 INSERT 完成) + // 前端只需要提供 itemCode、patientId、doctorId 等必要字段,其他字段在数据库层统一填充 + checkRequestMapper.batchInsertCheckRequests(selected); + } +}