需求-78-增加门诊医生开立检验申请单的开立与删除功能以及页面的调整。

This commit is contained in:
wangjian963
2026-02-28 14:59:21 +08:00
parent 35bc735ecc
commit a05b3a8d3c
21 changed files with 2308 additions and 377 deletions

View File

@@ -0,0 +1,22 @@
package com.openhis.web.doctorstation.appservice;
import com.core.common.core.domain.R;
import com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto;
/**
* 门诊医生站-检验服务接口
*/
public interface IDoctorStationInspectionLabApplyService {
R<?> saveInspectionLabApply(DoctorStationLabApplyDto doctorStationLabApplyDto);
Object getInspectionApplyByApplyNo(String applyNo);
Object getInspectionApplyListPage(Integer pageNo, Integer pageSize, Long encounterId);
/**
* 删除检验申请单(同时删除关联的门诊医嘱)
* @param applyNo 申请单号
* @return 删除结果
*/
R<?> deleteInspectionLabApply(String applyNo);
}

View File

@@ -0,0 +1,526 @@
package com.openhis.web.doctorstation.appservice.impl;
import com.core.common.core.domain.R;
import com.core.common.utils.SecurityUtils;
import com.openhis.administration.service.IAccountService;
import com.openhis.administration.domain.Account;
import com.openhis.lab.domain.InspectionLabApply;
import com.openhis.lab.domain.InspectionLabApplyItem;
import com.openhis.lab.domain.BarCode;
import com.openhis.lab.service.IInspectionLabApplyItemService;
import com.openhis.lab.service.IInspectionLabApplyService;
import com.openhis.lab.service.IInspectionLabBarCodeService;
import com.openhis.workflow.domain.ServiceRequest;
import com.openhis.workflow.service.IServiceRequestService;
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
import com.openhis.web.doctorstation.appservice.IDoctorStationInspectionLabApplyService;
import com.openhis.web.doctorstation.dto.AdviceSaveDto;
import com.openhis.web.doctorstation.dto.AdviceSaveParam;
import com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto;
import com.openhis.web.doctorstation.mapper.DoctorStationLabApplyMapper;
import com.openhis.administration.service.IOrganizationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.openhis.web.doctorstation.dto.DoctorStationLabApplyItemDto;
import com.openhis.workflow.service.IActivityDefinitionService;
import com.openhis.administration.domain.Organization;
import com.openhis.workflow.domain.ActivityDefinition;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 根据检验申请单开单信息系统自动插入门诊医嘱表(与检验申请主表申请单号进行关联),
* 当检验申请单表删除(作废)时门诊医嘱表也随之删除(作废),为后续门诊收费业务数据闭环
*/
@Slf4j
@Service
public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectionLabApplyService {
@Autowired
private IInspectionLabApplyService inspectionLabApplyService;
@Autowired
private IInspectionLabApplyItemService inspectionLabApplyItemService;
@Autowired
private IInspectionLabBarCodeService inspectionLabBarCodeService;
@Autowired
private DoctorStationLabApplyMapper doctorStationLabApplyMapper;
@Autowired
private IDoctorStationAdviceAppService iDoctorStationAdviceAppService;
@Autowired
private IActivityDefinitionService activityDefinitionService;
@Autowired
private IOrganizationService organizationService;
@Autowired
private IAccountService accountService;
@Autowired
private IServiceRequestService serviceRequestService;
/**
* 保存检验申请单信息
* @param doctorStationLabApplyDto
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<?> saveInspectionLabApply(DoctorStationLabApplyDto doctorStationLabApplyDto) {
/**
* 保存检验申请单信息逻辑
* 保存检验申请单信息同时根据检验申请单检验项目数据保存检验申请单明细信息
*/
log.debug("保存检验申请单信息:{}", doctorStationLabApplyDto);
log.debug("保存申请单明细信息:{}",doctorStationLabApplyDto.getLabApplyItemList());
//获取当前登陆用户 ID
String userId = String.valueOf(SecurityUtils.getLoginUser().getUserId());
InspectionLabApply inspectionLabApply = new InspectionLabApply();
//将 dto 数据复制到 InspectionLabApply 对象中
BeanUtils.copyProperties(doctorStationLabApplyDto, inspectionLabApply);
//设置租户 ID
inspectionLabApply.setTenantId(SecurityUtils.getLoginUser().getTenantId());
//获取当前登陆用户名称
inspectionLabApply.setCreateBy(SecurityUtils.getLoginUser().getUsername());
inspectionLabApply.setOperatorId(userId);
inspectionLabApply.setCreateTime(new Date());
inspectionLabApply.setDeleteFlag("0");
log.debug("保存检验申请单信息:{}", inspectionLabApply);
inspectionLabApplyService.saveOrUpdate(inspectionLabApply);
//遍历 doctorStationLabApplyDto.getLabApplyItemList()
int index = 0;
for (DoctorStationLabApplyItemDto doctorStationLabApplyItemDto : doctorStationLabApplyDto.getLabApplyItemList()) {
//将 dto 数据复制到 InspectionLabApplyItem 对象中
InspectionLabApplyItem inspectionLabApplyItem = new InspectionLabApplyItem();
BeanUtils.copyProperties(doctorStationLabApplyItemDto, inspectionLabApplyItem);
//设置从表申请单明细的申请单号
inspectionLabApplyItem.setApplyNo(doctorStationLabApplyDto.getApplyNo());
//检验科代码,取值于检验申请单
inspectionLabApplyItem.setPerformDeptCode(doctorStationLabApplyDto.getApplyDeptCode());
//同主表状态,可单独回写
inspectionLabApplyItem.setItemStatus(doctorStationLabApplyDto.getApplyStatus());
// 设置项目序号 (打印顺序),按照遍历序号进行排序
inspectionLabApplyItem.setItemSeq((long) (index + 1));
index++;
inspectionLabApplyItem.setDeleteFlag("0");
log.debug("保存申请单明细信息:{}", inspectionLabApplyItem);
inspectionLabApplyItemService.saveOrUpdate(inspectionLabApplyItem);
//创建条码对象
BarCode barCode = new BarCode();
barCode.setApplyNo(doctorStationLabApplyDto.getApplyNo());
//将 doctorStationLabApplyDto 的 Long 类型的 PatientId 转换为 String 类型
String patientId = String.valueOf(doctorStationLabApplyDto.getPatientId());
barCode.setPatientId(patientId);
//设置申请单明细 ID此处暂时设置为 null
barCode.setItemId(inspectionLabApplyItem.getItemId());
barCode.setTenantId(SecurityUtils.getLoginUser().getTenantId());
barCode.setCreateBy(SecurityUtils.getLoginUser().getUsername());
barCode.setCreateTime(new Date());
barCode.setDeleteFlag("0");
log.debug("插入条码数据前barCode:{}",barCode);
inspectionLabBarCodeService.saveOrUpdate(barCode);
}
/**
* 业务逻辑说明:
* 1. 当医生开具检验申请单时,系统需自动在门诊医嘱表中创建对应的医嘱记录
* 2. 检验申请单与门诊医嘱通过申请单号建立关联关系
*/
// 创建门诊医嘱保存参数
AdviceSaveParam adviceSaveParam = new AdviceSaveParam();
// 患者挂号对应的科室 id
adviceSaveParam.setOrganizationId(doctorStationLabApplyDto.getApplyOrganizationId());
// 准备医嘱保存列表
List<AdviceSaveDto> adviceSaveList = new ArrayList<>();
// 遍历检验申请单明细,为每个检验项目创建对应的门诊医嘱记录
for (DoctorStationLabApplyItemDto labApplyItemDto : doctorStationLabApplyDto.getLabApplyItemList()) {
// 1. 根据检验项目名称查询诊疗定义(检验项目)
String itemName = labApplyItemDto.getItemName();
Long activityDefinitionId = activityDefinitionService.getAppointActivityDefinitionId(itemName);
// log.debug("检验项目:{} 对应的诊疗定义 ID: {}", itemName, activityDefinitionId);
if (activityDefinitionId == null) {
// log.error("未找到检验项目对应的诊疗定义:{}", itemName);
throw new RuntimeException("未找到检验项目 '" + itemName + "' 对应的诊疗定义");
}
// 2. 获取诊疗定义详情
ActivityDefinition activityDefinition = activityDefinitionService.getById(activityDefinitionId);
if (activityDefinition == null) {
// log.error("诊疗定义不存在ID: {}", activityDefinitionId);
throw new RuntimeException("诊疗定义不存在");
}
// 3. 根据执行科室代码获取科室 IDpositionId
Long positionId = null;
String performDeptCode = labApplyItemDto.getPerformDeptCode();
if (performDeptCode != null && !performDeptCode.trim().isEmpty()) {
// 查询科室信息
Organization organization = organizationService.getOne(
new QueryWrapper<Organization>()
.eq("bus_no", performDeptCode)
.eq("delete_flag", "0")
);
if (organization != null) {
positionId = organization.getId();
} else {
log.warn("未找到执行科室代码对应的科室:{}", performDeptCode);
}
}
// 4. 创建医嘱保存对象
AdviceSaveDto adviceSaveDto = new AdviceSaveDto();
// 设置医嘱操作类型
adviceSaveDto.setDbOpType("1"); // 1:新增
// 设置医嘱类型
adviceSaveDto.setAdviceType(3); // 3:项目(检验项目)
// 设置检验项目相关信息
// 医嘱定义 ID诊疗定义 ID
adviceSaveDto.setAdviceDefinitionId(activityDefinitionId);
// 费用定价主表 ID对应 adm_charge_item 表的 definition_id 字段)
adviceSaveDto.setDefinitionId(activityDefinitionId);
// 医嘱名称
adviceSaveDto.setAdviceName(itemName);
// 医嘱详细分类
adviceSaveDto.setCategoryCode(activityDefinition.getCategoryCode());
// 活动 ID诊疗定义 ID
adviceSaveDto.setActivityId(activityDefinitionId);
// 医嘱定义对应表名
adviceSaveDto.setAdviceTableName("wor_activity_definition");
// 执行科室 ID
adviceSaveDto.setPositionId(positionId);
// 设置患者和就诊信息
// 患者 ID
adviceSaveDto.setPatientId(doctorStationLabApplyDto.getPatientId());
// 就诊 ID
adviceSaveDto.setEncounterId(doctorStationLabApplyDto.getEncounterId());
// 开方医生 ID - AdviceSaveDto 构造函数已设置,这里可覆盖
adviceSaveDto.setPractitionerId(SecurityUtils.getUserId());
// 开方科室 ID - AdviceSaveDto 构造函数已设置,这里可覆盖
adviceSaveDto.setFounderOrgId(SecurityUtils.getDeptId());
// 账户 ID - 获取就诊的账户(多级回退策略)
// log.debug("获取就诊 id 的参数:{}", doctorStationLabApplyDto.getEncounterId());
Long accountId = accountService.getSelfPayAccount(doctorStationLabApplyDto.getEncounterId());
if (accountId == null) {
// log.warn("未找到就诊 ID {} 对应的自费账户,尝试获取医保账户", doctorStationLabApplyDto.getEncounterId());
accountId = accountService.getMedicalInsuranceAccount(doctorStationLabApplyDto.getEncounterId());
}
if (accountId == null) {
// log.warn("未找到就诊 ID {} 对应的医保账户,尝试获取任何账户", doctorStationLabApplyDto.getEncounterId());
List<Account> accountList = accountService.getAccountListByEncounter(doctorStationLabApplyDto.getEncounterId());
if (accountList != null && !accountList.isEmpty()) {
accountId = accountList.get(0).getId();
// log.info("使用就诊 ID {} 的第一个账户ID: {}", doctorStationLabApplyDto.getEncounterId(), accountId);
}
}
if (accountId == null) {
// log.error("就诊 ID {} 没有任何关联的账户", doctorStationLabApplyDto.getEncounterId());
throw new RuntimeException("未找到就诊对应的账户,请确认患者已完成挂号并拥有有效的账户");
}
adviceSaveDto.setAccountId(accountId);
// 将申请单号作为业务关联标识(请求内容 json
adviceSaveDto.setContentJson("{\"applyNo\":\"" + doctorStationLabApplyDto.getApplyNo() + "\"}");
// 设置其他必要字段
// 请求数量
adviceSaveDto.setQuantity(labApplyItemDto.getItemQty() != null ? labApplyItemDto.getItemQty() : java.math.BigDecimal.ONE);
// 请求单位编码(使用诊疗定义的使用单位)
adviceSaveDto.setUnitCode(activityDefinition.getPermittedUnitCode());
// 单价
adviceSaveDto.setUnitPrice(labApplyItemDto.getItemPrice());
// 总价
adviceSaveDto.setTotalPrice(labApplyItemDto.getItemAmount());
// 请求状态
adviceSaveDto.setStatusEnum(1);
// 请求类型
adviceSaveDto.setCategoryEnum(1);
// 设置治疗类型(临时医嘱)
adviceSaveDto.setTherapyEnum(1); // 1:临时医嘱
// 添加到医嘱列表
adviceSaveList.add(adviceSaveDto);
}
// 设置医嘱保存参数的医嘱列表
adviceSaveParam.setAdviceSaveList(adviceSaveList);
// 调用门诊医嘱保存接口,创建关联的医嘱记录
try {
iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, "1"); // "1"表示保存操作
// log.info("成功创建与检验申请单 [{}] 关联的门诊医嘱记录", doctorStationLabApplyDto.getApplyNo());
} catch (Exception e) {
// log.error("创建与检验申请单 [{}] 关联的门诊医嘱记录失败:{}", doctorStationLabApplyDto.getApplyNo(), e.getMessage(), e);
throw new RuntimeException("创建关联医嘱记录失败", e);
}
return R.ok();
}
/**
* 根据申请单号查询检验申请单
*
* @param applyNo
* @return
*/
@Override
public Object getInspectionApplyByApplyNo(String applyNo) {
return doctorStationLabApplyMapper.getInspectionApplyByApplyNo(applyNo);
}
/**
* 根据就诊 ID 查询检验申请单列表(分页)
* @param pageNo 页码
* @param pageSize 每页数量
* @param encounterId 就诊 ID
* @return 检验申请单列表分页信息
*/
@Override
public Map<String, Object> getInspectionApplyListPage(Integer pageNo, Integer pageSize, Long encounterId) {
// 使用 PageHelper 进行分页查询
PageHelper.startPage(pageNo, pageSize);
// 查询检验申请单列表
log.debug("查询申请单数据前");
List<InspectionLabApply> list = doctorStationLabApplyMapper.getInspectionApplyListPage(encounterId);
log.debug("查询申请单数据后");
// 使用 PageInfo 包装查询结果
PageInfo<InspectionLabApply> pageInfo = new PageInfo<>(list);
// 构建返回结果
Map<String, Object> result = new HashMap<>();
result.put("records", pageInfo.getList());
result.put("total", pageInfo.getTotal());
log.debug("查询检验申请单列表,分页信息:{}", result);
return result;
}
/**
* 删除(作废)检验申请单(同时删除(作废)关联的门诊医嘱(诊疗),检验申请单明细和条码数据)
* @param applyNo 申请单号
* @return 删除结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<?> deleteInspectionLabApply(String applyNo) {
log.debug("删除检验申请单 [{}]", applyNo);
try {
// 1. 根据申请单号查询检验申请单信息
InspectionLabApply inspectionLabApply = inspectionLabApplyService.getOne(
new QueryWrapper<InspectionLabApply>().eq("apply_no", applyNo)
);
if (inspectionLabApply == null) {
log.warn("未找到申请单号为 [{}] 的检验申请单", applyNo);
return R.fail("未找到对应的检验申请单");
}
// 2. 删除关联的门诊医嘱
deleteAssociatedAdvice(applyNo);
// 3. 删除检验申请单明细
deleteInspectionLabApplyItems(applyNo);
// 4. 删除条码数据
deleteBarCodeData(applyNo);
// 5. 删除检验申请单主表数据,并设置更新人和更新时间
String currentUsername = SecurityUtils.getUsername();
Date currentTime = new Date();
boolean deleteResult = inspectionLabApplyService.update(
new LambdaUpdateWrapper<InspectionLabApply>()
.set(InspectionLabApply::getDeleteFlag, "1")
.set(InspectionLabApply::getUpdateBy, currentUsername)
.set(InspectionLabApply::getUpdateTime, currentTime)
.eq(InspectionLabApply::getApplyNo, applyNo)
);
if (deleteResult) {
log.debug("成功删除申请单号为 [{}] 的检验申请单及相关数据,更新人:{},更新时间:{}",
applyNo, currentUsername, currentTime);
return R.ok("删除成功");
} else {
log.error("删除申请单号为 [{}] 的检验申请单失败", applyNo);
// 手动抛出异常,确保事务回滚
throw new RuntimeException("删除检验申请单失败,申请单号:" + applyNo);
}
} catch (Exception e) {
log.error("删除检验申请单 [{}] 时发生异常,事务将回滚", applyNo, e);
// 重新抛出异常,确保事务回滚
throw new RuntimeException("删除检验申请单过程中发生异常:" + e.getMessage(), e);
}
}
/**
* 删除关联的门诊医嘱
* @param applyNo 申请单号
*/
private void deleteAssociatedAdvice(String applyNo) {
try {
// 1. 根据申请单号查询关联的医嘱信息获取正确的requestId
List<Long> requestIds = getAdviceRequestIdsByApplyNo(applyNo);
log.debug("申请单号 [{}] 关联的医嘱信息:{}", applyNo, requestIds);
if (requestIds.isEmpty()) {
log.debug("申请单号 [{}] 没有关联的医嘱记录,无需删除", applyNo);
return;
}
// 2. 直接更新医嘱的删除状态为1逻辑删除并设置更新人和更新时间
String currentUsername = SecurityUtils.getUsername();
Date currentTime = new Date();
boolean updateResult = serviceRequestService.update(
new LambdaUpdateWrapper<ServiceRequest>()
.set(ServiceRequest::getDeleteFlag, "1")
.set(ServiceRequest::getUpdateBy, currentUsername)
.set(ServiceRequest::getUpdateTime, currentTime)
.in(ServiceRequest::getId, requestIds)
);
if (updateResult) {
log.debug("成功将申请单号 [{}] 关联的 {} 条门诊医嘱的删除状态更新为1更新人{},更新时间:{}",
applyNo, requestIds.size(), currentUsername, currentTime);
} else {
log.warn("更新申请单号 [{}] 关联的门诊医嘱删除状态失败", applyNo);
}
} catch (Exception e) {
log.error("删除申请单号 [{}] 关联的门诊医嘱时发生异常", applyNo, e);
// 不抛出异常,继续执行其他删除操作
}
}
/**
* 根据申请单号查询关联的医嘱请求ID列表
* @param applyNo 申请单号
* @return 医嘱请求ID列表
*/
private List<Long> getAdviceRequestIdsByApplyNo(String applyNo) {
try {
// 根据申请单号查询关联的医嘱信息
// 医嘱表(wor_service_request)中的contentJson字段存储了申请单号
// contentJson格式{"applyNo":"20260228094429944868"}
// 使用MyBatis Plus查询通过contentJson字段模糊匹配申请单号
List<ServiceRequest> serviceRequests =
serviceRequestService.list(
new QueryWrapper<ServiceRequest>()
.like("content_json", applyNo)
.eq("delete_flag", "0")
);
if (serviceRequests == null || serviceRequests.isEmpty()) {
log.debug("申请单号 [{}] 没有关联的医嘱记录", applyNo);
return new ArrayList<>();
}
// 提取所有的医嘱请求ID
List<Long> requestIds = serviceRequests.stream()
.map(ServiceRequest::getId)
.collect(java.util.stream.Collectors.toList());
log.debug("查询到申请单号 [{}] 关联的 {} 条医嘱记录requestId列表{}",
applyNo, requestIds.size(), requestIds);
return requestIds;
} catch (Exception e) {
log.error("查询申请单号 [{}] 关联的医嘱请求ID时发生异常", applyNo, e);
return new ArrayList<>();
}
}
/**
* 删除检验申请单明细
* @param applyNo 申请单号
*/
private void deleteInspectionLabApplyItems(String applyNo) {
try {
// 根据申请单号删除明细数据,并设置更新人和更新时间
String currentUsername = SecurityUtils.getUsername();
Date currentTime = new Date();
boolean deleteResult = inspectionLabApplyItemService.update(
new LambdaUpdateWrapper<InspectionLabApplyItem>()
.set(InspectionLabApplyItem::getDeleteFlag, "1")
.set(InspectionLabApplyItem::getUpdateBy, currentUsername)
.set(InspectionLabApplyItem::getUpdateTime, currentTime)
.eq(InspectionLabApplyItem::getApplyNo, applyNo)
);
if (deleteResult) {
log.debug("成功删除申请单号 [{}] 的检验申请单明细,更新人:{},更新时间:{}",
applyNo, currentUsername, currentTime);
} else {
log.warn("删除申请单号 [{}] 的检验申请单明细失败", applyNo);
}
} catch (Exception e) {
log.error("删除申请单号 [{}] 的检验申请单明细时发生异常", applyNo, e);
// 不抛出异常,继续执行其他删除操作
}
}
/**
* 删除条码数据
* @param applyNo 申请单号
*/
private void deleteBarCodeData(String applyNo) {
try {
// 根据申请单号删除条码数据,并设置更新人和更新时间
String currentUsername = SecurityUtils.getUsername();
Date currentTime = new Date();
boolean deleteResult = inspectionLabBarCodeService.update(
new LambdaUpdateWrapper<BarCode>()
.set(BarCode::getDeleteFlag, "1")
.set(BarCode::getUpdateBy, currentUsername)
.set(BarCode::getUpdateTime, currentTime)
.eq(BarCode::getApplyNo, applyNo)
);
if (deleteResult) {
log.debug("成功删除申请单号 [{}] 的条码数据,更新人:{},更新时间:{}",
applyNo, currentUsername, currentTime);
} else {
log.warn("删除申请单号 [{}] 的条码数据失败", applyNo);
}
} catch (Exception e) {
log.error("删除申请单号 [{}] 的条码数据时发生异常", applyNo, e);
// 不抛出异常,继续执行其他删除操作
}
}
}

View File

@@ -0,0 +1,65 @@
package com.openhis.web.doctorstation.controller;
import com.core.common.core.domain.R;
import com.openhis.web.doctorstation.appservice.IDoctorStationInspectionLabApplyService;
import com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import org.springframework.validation.annotation.Validated;
/**
* 门诊医生站-检验控制器
*/
@RestController
@Slf4j
@RequestMapping("/doctor-station/inspection")
@Validated
public class DoctorStationInspectionLabApplyController {
@Autowired
private IDoctorStationInspectionLabApplyService iDoctorStationInspectionLabApplyService;
/**
* 保存检验申请单信息
*/
@PostMapping(value = "/application")
public R<?> saveInspectionApply(@Valid @RequestBody DoctorStationLabApplyDto doctorStationLabApplyDto){
log.debug("保存检验申请单信息:{}", doctorStationLabApplyDto);
return R.ok(iDoctorStationInspectionLabApplyService.saveInspectionLabApply(doctorStationLabApplyDto));
}
/**
* 根据申请单号查询检验申请单信息
*/
@GetMapping(value = "/apply-no")
public R<?> getInspectionApplyByApplyNo(@RequestParam String applyNo){
log.debug("根据申请单号查询检验申请单信息:{}", applyNo);
return R.ok(iDoctorStationInspectionLabApplyService.getInspectionApplyByApplyNo(applyNo));
}
/**
* 分页查询检验申请单
* @param pageNo 页码(默认 1
* @param pageSize 每页数量(默认 10
* @param encounterId 就诊 ID可选用于筛选特定就诊记录
* @return 分页数据
*/
@GetMapping(value = "/get-applyList")
public R<?> getInspectionApplyListPage(@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(value = "encounterId", required = false) Long encounterId){
log.debug("分页查询检验申请单pageNo={}, pageSize={}, encounterId={}", pageNo, pageSize, encounterId);
return R.ok(iDoctorStationInspectionLabApplyService.getInspectionApplyListPage(pageNo, pageSize, encounterId));
}
/**
* 删除检验申请单(同时删除关联的门诊医嘱)
* @param applyNo 申请单号
* @return 删除结果
*/
@DeleteMapping(value = "/apply/{applyNo}")
public R<?> deleteInspectionApply(@PathVariable String applyNo){
log.debug("删除检验申请单:{}", applyNo);
return R.ok(iDoctorStationInspectionLabApplyService.deleteInspectionLabApply(applyNo));
}
}

View File

@@ -0,0 +1,151 @@
package com.openhis.web.doctorstation.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 检验申请单DTO
*/
@Data
@Accessors(chain = true)
public class DoctorStationLabApplyDto {
/**
* 申请单编号
*/
@Size(max = 32, message = "申请单编号长度不能超过32个字符")
private String applyNo;
/**
* 患者就诊科室id
*/
private Long applyOrganizationId;
/**
* 患者主索引
*/
private Long patientId;
/**
* 患者姓名
*/
@Size(max = 50, message = "患者姓名长度不能超过50个字符")
private String patientName;
/**
* 就诊卡号
*/
private String medicalrecordNumber;
/*
* 费用性质
*/
@Size(max = 20, message = "费用性质长度不能超过20个字符")
private String natureofCost;
/**
* 门诊就诊流水号
*/
private String visitNo;
/**
* 开单科室编码
*/
@Size(max = 20, message = "开单科室编码长度不能超过20个字符")
private String applyDeptCode;
/**
* 申请科室名称
*/
@Size(max = 100, message = "申请科室名称长度不能超过100个字符")
private String applyDepartment;
/**
* 开单医生工号
*/
private String applyDocCode;
/**
* 申请医生名称
*/
@Size(max = 50, message = "申请医生名称长度不能超过50个字符")
private String applyDocName;
/**
* 申请时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date applyTime;
/**
* 临床诊断
*/
private String clinicDiag;
/**
* 临床印象
*/
private String clinicDesc;
/**
* 禁忌症
*/
private String contraindication;
/**
* 病史摘要
*/
private String medicalHistorySummary;
/**
* 检验目的
*/
private String purposeofInspection;
/**
* 体格检查
*/
private String physicalExamination;
/**
* 检验项目
*/
private String inspectionItem;
/**
* 标本类型代码
*/
private String specimenTypeCode;
/**
* 标本名称
*/
@Size(max = 100, message = "标本名称长度不能超过100个字符")
private String specimenName;
/**
* 申请单优先级代码
*/
@Size(max = 4, message = "申请单优先级代码长度不能超过4个字符")
private String priorityCode;
/**
* 申请单状态
*/
private Long applyStatus;
/**
* 备注
*/
private String applyRemark;
/**
* 创建时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 操作员工号
*/
private String operatorId;
/**
* 就诊id
*/
private Long encounterId;
/**
* 检验项目数据列表
*/
private List<DoctorStationLabApplyItemDto> labApplyItemList;
/**
* 金额
*/
private BigDecimal itemAmount;
/**
* 项目名称
*/
private String itemName;
}

View File

@@ -0,0 +1,70 @@
package com.openhis.web.doctorstation.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.math.BigDecimal;
/**
* 检验申请单明细表
*/
@Data
@Accessors(chain = true)
public class DoctorStationLabApplyItemDto {
/**
* 申请单号
*/
@Size(max = 32, message = "申请单号长度不能超过32个字符")
private String applyNo;
/**
* 项目序号
*/
@NotNull(message = "项目序号不能为空")
private Long itemSeq;
/**
* 项目代码
*/
// @NotBlank(message = "项目代码不能为空")
@Size(max = 30, message = "项目代码长度不能超过30个字符")
private String itemCode;
/**
* 项目名称
*/
@NotBlank(message = "项目名称不能为空")
@Size(max = 100, message = "项目名称长度不能超过100个字符")
private String itemName;
/**
* 国家平台项目代码
*/
@Size(max = 30, message = "国家平台项目代码长度不能超过30个字符")
private String nationalItemCode;
/**
* 执行科室代码
*/
// @NotBlank(message = "执行科室代码不能为空")
@Size(max = 20, message = "执行科室代码长度不能超过20个字符")
private String performDeptCode;
/**
* 单价
*/
@NotNull(message = "单价不能为空")
private BigDecimal itemPrice;
/**
* 数量
*/
@NotNull(message = "数量不能为空")
private BigDecimal itemQty;
/**
* 金额
*/
@NotNull(message = "金额不能为空")
private BigDecimal itemAmount;
/**
* 行状态
*/
@NotNull(message = "行状态不能为空")
private Long itemStatus;
}

View File

@@ -0,0 +1,22 @@
package com.openhis.web.doctorstation.mapper;
import com.openhis.lab.domain.InspectionLabApply;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 门诊医生站 - 检验申请单 Mapper
*/
@Repository
public interface DoctorStationLabApplyMapper {
Object getInspectionApplyByApplyNo(String applyNo);
/**
* 分页查询检验申请单列表
* @param encounterId 就诊 ID
* @return 检验申请单列表
*/
List<InspectionLabApply> getInspectionApplyListPage(@Param("encounterId") Long encounterId);
}

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.openhis.web.doctorstation.mapper.DoctorStationLabApplyMapper">
<!-- 根据申请单号查询检验申请单 -->
<select id="getInspectionApplyByApplyNo" resultType="com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto">
SELECT apply_no AS applyNo
FROM lab_apply
WHERE apply_no = #{applyNo}
AND delete_flag = '0'
</select>
<!-- 分页查询检验申请单列表根据就诊ID查询按申请时间降序
encounterId: 就诊ID作为查询条件查出患者idpatient_id再以患者id对申请单进行查询
对申请单表(lab_apply)、申请单明细表(lab_apply_item)和就诊表(adm_encounter)进行联合查询(申请单号,检验项目,申请医生,申请单优先级码,申请单状态,金额)-->
<select id="getInspectionApplyListPage" resultType="com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto">
SELECT t1.apply_no AS applyNo,
t1.inspection_item AS inspectionItem,
t1.apply_doc_name AS applyDocName,
t1.priority_code AS priorityCode,
t2.item_name AS itemName,
t1.apply_status AS applyStatus,
t2.item_amount AS itemAmount
FROM lab_apply AS t1
INNER JOIN adm_encounter AS t3 ON t1.patient_id::bigint = t3.patient_id
LEFT JOIN lab_apply_item AS t2
ON t1.apply_no = t2.apply_no
WHERE t1.delete_flag = '0'
AND t3.id = #{encounterId}
ORDER BY t1.apply_time DESC
</select>
</mapper>

View File

@@ -0,0 +1,67 @@
package com.openhis.lab.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.core.common.core.domain.HisBaseEntity;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 条码/标本流转表
*
* @author system
* @date 2026-01-27
*/
@Data
@TableName("lab_barcode")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class BarCode extends HisBaseEntity {
/**
* 主键
* 条码号
*/
@TableId(type = IdType.NONE)
private String barcode;
/**
* 检验申请单号
*/
private String applyNo;
/**
* 明细ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long itemId;
/**
* 患者id
*/
private String patientId;
/**
* 采样时间
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Date collectTime;
/**
* 采样人
*/
private String collectionEmp;
/**
* 送检时间
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Date sendTime;
/**
* 签收时间
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Date receiveTime;
/**
* 退检时间
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Date backFlag;
}

View File

@@ -0,0 +1,126 @@
package com.openhis.lab.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.core.common.core.domain.HisBaseEntity;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 检验申请单定义Entity实体
*
* @author system
* @Date 2026-01-27
*/
@Data
@TableName("lab_apply")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class InspectionLabApply extends HisBaseEntity {
/**
* 主键ID,申请单编号
*/
@TableId(type = IdType.NONE)
private String applyNo;
/**
* 患者主索引
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long patientId;
/**
* 患者姓名
*/
private String patientName;
/**
* 就诊卡号
*/
private String medicalrecordNumber;
/*
* 费用性质
*/
private String natureofCost;
/**
* 门诊就诊流水号
*/
private String visitNo;
/**
* 开单科室编码
*/
private String applyDeptCode;
/**
* 申请科室名称
*/
private String applyDepartment;
/**
* 开单医生工号
*/
private String applyDocCode;
/**
* 申请医生名称
*/
private String applyDocName;
/**
* 申请时间
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Date applyTime;
/**
* 临床诊断
*/
private String clinicDiag;
/**
* 临床印象
*/
private String clinicDesc;
/**
* 禁忌症
*/
private String contraindication;
/**
* 病史摘要
*/
private String medicalHistorySummary;
/**
* 检验目的
*/
private String purposeofInspection;
/**
* 体格检查
*/
private String physicalExamination;
/**
* 检验项目
*/
private String inspectionItem;
/**
* 标本类型代码
*/
private String specimenTypeCode;
/**
* 标本名称
*/
private String specimenName;
/**
* 申请单优先级代码
*/
private String priorityCode;
/**
* 申请单状态
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long applyStatus;
/**
* 备注
*/
private String applyRemark;
/**
* 操作员工号
*/
private String operatorId;
}

View File

@@ -0,0 +1,77 @@
package com.openhis.lab.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.core.common.core.domain.HisBaseEntity;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* 检验申请单明细表
*
* @author system
* @date 2026-01-27
*/
@Data
@TableName("lab_apply_item")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class InspectionLabApplyItem extends HisBaseEntity {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Long itemId;
/**
* 申请单号
*/
private String applyNo;
/**
* 项目序号
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long itemSeq;
/**
* 项目代码
*/
private String itemCode;
/**
* 项目名称
*/
private String itemName;
/**
* 国家平台项目代码
*/
private String nationalItemCode;
/**
* 执行科室代码
*/
private String performDeptCode;
/**
* 单价
*/
@JsonSerialize(using = ToStringSerializer.class)
private BigDecimal itemPrice;
/**
* 数量
*/
@JsonSerialize(using = ToStringSerializer.class)
private BigDecimal itemQty;
/**
* 金额
*/
@JsonSerialize(using = ToStringSerializer.class)
private BigDecimal itemAmount;
/**
* 行状态
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long itemStatus;
}

View File

@@ -0,0 +1,9 @@
package com.openhis.lab.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.openhis.lab.domain.InspectionLabApplyItem;
import org.springframework.stereotype.Repository;
@Repository
public interface InspectionLabApplyItemMapper extends BaseMapper<InspectionLabApplyItem> {
}

View File

@@ -0,0 +1,15 @@
package com.openhis.lab.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.openhis.lab.domain.InspectionLabApply;
import org.springframework.stereotype.Repository;
/**
* 检验申请单Mapper接口
*
* @author system
* @date 2026-01-27
*/
@Repository
public interface InspectionLabApplyMapper extends BaseMapper<InspectionLabApply> {
}

View File

@@ -0,0 +1,15 @@
package com.openhis.lab.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.openhis.lab.domain.BarCode;
import org.springframework.stereotype.Repository;
/**
* 条码Mapper接口
*
* @author system
* @date 2026-01-27
*/
@Repository
public interface InspectionLabBarCodeMapper extends BaseMapper<BarCode> {
}

View File

@@ -0,0 +1,12 @@
package com.openhis.lab.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.openhis.lab.domain.InspectionLabApplyItem;
/**
* 检验申请单明细表
* @author system
* @date 2026-01-27
*/
public interface IInspectionLabApplyItemService extends IService<InspectionLabApplyItem> {
}

View File

@@ -0,0 +1,13 @@
package com.openhis.lab.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.openhis.lab.domain.InspectionLabApply;
/**
* 检验申请单Service接口
*
* @author system
* @date 2026-01-27
*/
public interface IInspectionLabApplyService extends IService<InspectionLabApply> {
}

View File

@@ -0,0 +1,13 @@
package com.openhis.lab.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.openhis.lab.domain.BarCode;
/**
* 检验申请单条码Service接口
*
* @author system
* @date 2026-01-27
*/
public interface IInspectionLabBarCodeService extends IService<BarCode> {
}

View File

@@ -0,0 +1,13 @@
package com.openhis.lab.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.openhis.lab.domain.InspectionLabApplyItem;
import com.openhis.lab.mapper.InspectionLabApplyItemMapper;
import com.openhis.lab.service.IInspectionLabApplyItemService;
import org.springframework.stereotype.Service;
@Service
public class InspectionLabApplyItemServiceImpl extends ServiceImpl<InspectionLabApplyItemMapper, InspectionLabApplyItem>
implements IInspectionLabApplyItemService
{
}

View File

@@ -0,0 +1,12 @@
package com.openhis.lab.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.openhis.lab.domain.InspectionLabApply;
import com.openhis.lab.mapper.InspectionLabApplyMapper;
import com.openhis.lab.service.IInspectionLabApplyService;
import org.springframework.stereotype.Service;
@Service
public class InspectionLabApplyServiceImpl extends ServiceImpl<InspectionLabApplyMapper, InspectionLabApply>
implements IInspectionLabApplyService{
}

View File

@@ -0,0 +1,19 @@
package com.openhis.lab.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.openhis.lab.domain.BarCode;
import com.openhis.lab.mapper.InspectionLabBarCodeMapper;
import com.openhis.lab.service.IInspectionLabBarCodeService;
import org.springframework.stereotype.Service;
/**
* 检验申请单条码Service业务层处理
*
* @author system
* @date 2026-01-27
*/
@Service
public class InspectionLabBarCodeServiceImpl extends ServiceImpl<InspectionLabBarCodeMapper, BarCode>
implements IInspectionLabBarCodeService {
}