Fix Bug #550: fallback修复
This commit is contained in:
@@ -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<Map<String, Object>> list() {
|
||||
return checkRequestService.listPendingRequests();
|
||||
}
|
||||
|
||||
@PostMapping("/submit")
|
||||
public void submit(@RequestBody List<Map<String, Object>> selected) {
|
||||
// 校验:同一检查项目只能提交一次,且项目与方法解耦
|
||||
checkRequestService.validateAndSubmit(selected);
|
||||
}
|
||||
}
|
||||
@@ -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<String>) – 根据项目代码查询仍在“待处理”状态的记录,用于提交前的唯一性校验。
|
||||
* 2. batchInsertCheckRequests(List<Map<String,Object>>) – 一次性批量插入检查申请明细,避免前端明细与后端耦合。
|
||||
*/
|
||||
@Mapper
|
||||
public interface CheckRequestMapper {
|
||||
|
||||
@Select("SELECT * FROM outpatient_check_request WHERE status = 0") // 0 表示待处理
|
||||
List<Map<String, Object>> selectPendingRequests();
|
||||
|
||||
/**
|
||||
* 查询给定项目代码列表中,仍处于待处理状态的项目代码。
|
||||
*
|
||||
* @param itemCodes 项目代码集合
|
||||
* @return 已存在待处理状态的项目代码集合
|
||||
*/
|
||||
@Select({
|
||||
"<script>",
|
||||
"SELECT DISTINCT item_code FROM outpatient_check_request",
|
||||
"WHERE status = 0",
|
||||
"AND item_code IN",
|
||||
"<foreach item='code' collection='itemCodes' open='(' separator=',' close=')'>",
|
||||
"#{code}",
|
||||
"</foreach>",
|
||||
"</script>"
|
||||
})
|
||||
List<String> selectPendingItemCodes(@Param("itemCodes") List<String> itemCodes);
|
||||
|
||||
/**
|
||||
* 批量插入检查申请记录。
|
||||
*
|
||||
* 前端传入的每条记录必须包含以下键:
|
||||
* - itemCode : 检查项目代码
|
||||
* - patientId : 患者 ID
|
||||
* - doctorId : 医生 ID
|
||||
* - requestTime: 申请时间(若未提供则使用 NOW())
|
||||
*
|
||||
* 其它业务字段(如 status)在 SQL 中统一写死为待处理状态(0)。
|
||||
*/
|
||||
@Insert({
|
||||
"<script>",
|
||||
"INSERT INTO outpatient_check_request (item_code, patient_id, doctor_id, request_time, status)",
|
||||
"VALUES",
|
||||
"<foreach collection='list' item='item' separator=','>",
|
||||
"(",
|
||||
"#{item.itemCode},",
|
||||
"#{item.patientId},",
|
||||
"#{item.doctorId},",
|
||||
"<choose>",
|
||||
" <when test='item.requestTime != null'>#{item.requestTime}</when>",
|
||||
" <otherwise>NOW()</otherwise>",
|
||||
"</choose>,",
|
||||
"0", // 待处理状态
|
||||
")",
|
||||
"</foreach>",
|
||||
"</script>"
|
||||
})
|
||||
int batchInsertCheckRequests(@Param("list") List<Map<String, Object>> list);
|
||||
}
|
||||
@@ -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<Map<String, Object>> listPendingRequests() {
|
||||
return checkRequestMapper.selectPendingRequests();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并提交检查申请
|
||||
*
|
||||
* @param selected 前端选中的检查项目列表
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void validateAndSubmit(List<Map<String, Object>> selected) {
|
||||
if (selected == null || selected.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 前端是否传入了重复的 item_code
|
||||
List<String> 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<String> itemCodes = selected.stream()
|
||||
.map(item -> (String) item.get("itemCode"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<String> alreadyPending = checkRequestMapper.selectPendingItemCodes(itemCodes);
|
||||
if (!alreadyPending.isEmpty()) {
|
||||
throw new IllegalArgumentException("以下检查项目已存在未完成的申请,不能重复提交: " + alreadyPending);
|
||||
}
|
||||
|
||||
// 3. 批量插入检查申请明细(一次 INSERT 完成)
|
||||
// 前端只需要提供 itemCode、patientId、doctorId 等必要字段,其他字段在数据库层统一填充
|
||||
checkRequestMapper.batchInsertCheckRequests(selected);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user