临床发血,保存数据,审核逻辑

This commit is contained in:
jiangs 2026-08-14 17:47:02 +08:00
parent 19ed34db34
commit 20aca19131
19 changed files with 224 additions and 18 deletions

View File

@ -62,4 +62,9 @@ public class BloodInterfaceTypeConstants {
* 作废配血单
*/
public static final String CANCEL_MATCH_BLOOD_TYPE = "CANCEL_MATCH_BLOOD_TYPE";
/**
* 临床发血审核
*/
public static final String BLOOD_OUT_AUDIT = "BLOOD_OUT_AUDIT";
}

View File

@ -15,4 +15,5 @@ public class BloodSysLogConstants {
public static final String LOG_TYPE_SEND_SAMPLE_INFO = "标本送检";
public static final String LOG_TYPE_CHECK_BLOOD_TYPE = "血型复核";
public static final String LOG_TYPE_MATCH_BLOOD = "交叉配血";
public static final String LOG_TYPE_BLOOD_OUT = "临床发血审核";
}

View File

@ -7,4 +7,5 @@ import java.util.List;
public interface XkOutDetailMapper {
List<XkOutDetail> queryListByBillNo(String billNo);
void insert(XkOutDetail xkOutDetail);
void deleteByBillNo(String billNo);
}

View File

@ -6,5 +6,6 @@ import org.apache.ibatis.annotations.Param;
public interface XkOutMainMapper {
XkOutMain queryOne(@Param("billNo") String billNo);
void insert(XkOutMain xkOutMain);
void update(XkOutMain xkOutMain);
}

View File

@ -1,6 +1,7 @@
package com.czblood.bus.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -15,10 +16,15 @@ public class XkOutDetail {
private String bill_no;
private Integer sid;
private String blood_no;
@ApiModelProperty("单价")
private BigDecimal price;
@ApiModelProperty("特殊处理")
private String special_deal;
@ApiModelProperty("是否有反应")
private String have_reaction;
@ApiModelProperty("完成标志")
private String finish_sign;
@ApiModelProperty("血液是否已接收")
private String accept_flag;
private String exp1;
private String exp2;

View File

@ -1,6 +1,7 @@
package com.czblood.bus.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -15,28 +16,50 @@ import java.util.Date;
public class XkOutMain {
private String bill_no;
private String hos_id;
@ApiModelProperty("出库日期")
private Date occur_date;
@ApiModelProperty("总金额")
private BigDecimal total_money;
@ApiModelProperty("取血人")
private String take_person;
@ApiModelProperty("发血经手人")
private String handle_person;
@ApiModelProperty("申请单号")
private String apply_no;
@ApiModelProperty("配血单号")
private String match_no;
@ApiModelProperty("患者姓名")
private String patient_name;
@ApiModelProperty("住院号")
private String beinhos_id;
@ApiModelProperty("科室ID")
private String dept_id;
@ApiModelProperty("血型复核单号")
private String check_no;
@ApiModelProperty("单据类别,程序默认C")
private String bill_sort;
@ApiModelProperty("通知取血时间")
private Date notify_time;
@ApiModelProperty("是否已经无偿报销")
private String is_free_account;
@ApiModelProperty("录入人")
private String input_person;
@ApiModelProperty("录入时间")
private Date input_date;
@ApiModelProperty("审核标志")
private String check_sign;
@ApiModelProperty("审核人")
private String check_person;
@ApiModelProperty("审核时间")
private Date check_date;
@ApiModelProperty("审批人")
private String audit_person;
@ApiModelProperty("备注")
private String remark;
private String exp1;
@ApiModelProperty("是否通知取血")
private String exp2;
@ApiModelProperty("最后修改时间")
private Date last_modified;
private String all_recycle_sign;
private String receive_person;

View File

@ -91,7 +91,7 @@ public class XkTransfuseApply {
private String remark;
@ApiModelProperty("预约入库标志(N=否、Y=是)")
private String is_plan;
@ApiModelProperty("单据类别(A,B,C,D,J)")
@ApiModelProperty("单据类别(A不需要配血,B,C,D,J)")
private String bill_sort;
@ApiModelProperty("是否有标本申请")
private String sample_sign;

View File

@ -0,0 +1,20 @@
package com.czblood.bus.pojo.inter;
import cn.hutool.json.JSONUtil;
import com.czblood.bus.constants.BloodInterfaceTypeConstants;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BloodOutAuditRequest implements BloodInterfaceType {
private final String method = BloodInterfaceTypeConstants.BLOOD_OUT_AUDIT;
private String billNo;
@Override
public String serializationJson() {
return JSONUtil.toJsonStr(this);
}
}

View File

@ -32,6 +32,9 @@
<if test="product_no != null">#{product_no},</if>
#{bill_no},#{sid} )
</insert>
<delete id="deleteByBillNo">
delete from xk_out_detail where bill_no = #{billNo}
</delete>
<select id="queryListByBillNo" resultType="com.czblood.bus.pojo.XkOutDetail">
select * from xk_out_detail where bill_no = #{billNo}
</select>

View File

@ -57,6 +57,36 @@
#{bill_no}, #{hos_id}, #{occur_date}
)
</insert>
<update id="update">
update xk_out_main set
<if test="total_money != null">total_money = #{total_money},</if>
<if test="take_person != null">take_person = #{take_person},</if>
<if test="handle_person != null">handle_person = #{handle_person},</if>
<if test="apply_no != null">apply_no = #{apply_no},</if>
<if test="match_no != null">match_no = #{match_no},</if>
<if test="patient_name != null">patient_name = #{patient_name},</if>
<if test="beinhos_id != null">beinhos_id = #{beinhos_id},</if>
<if test="dept_id != null">dept_id = #{dept_id},</if>
<if test="check_no != null">check_no = #{check_no},</if>
<if test="bill_sort != null">bill_sort = #{bill_sort},</if>
<if test="notify_time != null">notify_time = #{notify_time},</if>
<if test="is_free_account != null">is_free_account = #{is_free_account},</if>
<if test="input_person != null">input_person = #{input_person},</if>
<if test="input_date != null">input_date = #{input_date},</if>
<if test="check_sign != null">check_sign = #{check_sign},</if>
<if test="check_person != null">check_person = #{check_person},</if>
<if test="check_date != null">check_date = #{check_date},</if>
<if test="audit_person != null">audit_person = #{audit_person},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="exp1 != null">exp1 = #{exp1},</if>
<if test="exp2 != null">exp2 = #{exp2},</if>
<if test="last_modified != null">last_modified = #{last_modified},</if>
<if test="all_recycle_sign != null">all_recycle_sign = #{all_recycle_sign},</if>
<if test="receive_person != null">receive_person = #{receive_person},</if>
<if test="receive_id != null">receive_id = #{receive_id},</if>
bill_no = #{bill_no}
where bill_no = #{bill_no}
</update>
<select id="queryOne" resultType="com.czblood.bus.pojo.XkOutMain">
select * from xk_out_main where bill_no = #{billNo}

View File

@ -1,16 +1,17 @@
package com.czblood.busBloodbank.controller;
import com.czblood.bus.constants.BloodSysLogConstants;
import com.czblood.busBloodbank.pojo.VO.BloodOutAuditVO;
import com.czblood.busBloodbank.pojo.VO.BloodOutInfoVO;
import com.czblood.busBloodbank.service.BloodOutService;
import com.czblood.common.annotation.Log;
import com.czblood.common.core.controller.BaseController;
import com.czblood.common.core.domain.Result;
import com.czblood.common.enums.BusinessType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -41,11 +42,19 @@ public class BloodOutController extends BaseController {
return bloodOutService.getBloodInfoOut(bloodNo, productNo, applyNo);
}
@Log(title = BloodSysLogConstants.LOG_TYPE_BLOOD_OUT, businessType = BusinessType.INSERT)
@ApiOperation("保存数据")
@PostMapping("/saveData")
public Result saveData(BloodOutInfoVO bloodOutInfoVO){
public Result saveData(@RequestBody BloodOutInfoVO bloodOutInfoVO){
bloodOutInfoVO.setUserId(getUsername());
return bloodOutService.saveData(bloodOutInfoVO);
}
@ApiOperation("临床发血审核")
@PostMapping("/bloodOutAudit")
public Result bloodOutAudit(@RequestBody BloodOutAuditVO bloodOutAuditVO){
bloodOutAuditVO.setUserId(getUsername());
return bloodOutService.bloodOutAudit(bloodOutAuditVO);
}
}

View File

@ -3,8 +3,10 @@ package com.czblood.busBloodbank.mapper;
import com.czblood.bus.pojo.XkBackoutDetail;
import com.czblood.bus.pojo.XkDiscardMain;
import com.czblood.bus.pojo.XkMatchMain;
import com.czblood.bus.pojo.XkSampleInfo;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ -17,5 +19,7 @@ public interface BloodOutMapper {
List<XkDiscardMain> queryDiscardCount(@Param("bloodNo") String bloodNo, @Param("productNo") String productNo);
List<Map<String,Object>> queryMatchBloodInfo(@Param("bloodNo") String bloodNo, @Param("productNo") String productNo, @Param("applyNo") String applyNo);
XkMatchMain queryXkMatchMain(String applyNo);
String queryMaxCheckNo(String applyNo);
Date querySampleMaxPickDate(String applyNo);
}

View File

@ -6,6 +6,8 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ -17,4 +19,5 @@ public class BloodOutInfoDTO {
private String check_method;
@ApiModelProperty("配血结果")
private String result;
private BigDecimal price;
}

View File

@ -0,0 +1,14 @@
package com.czblood.busBloodbank.pojo.VO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BloodOutAuditVO {
private String billNo;
private String applyNo;
private String userId;
}

View File

@ -2,6 +2,7 @@ package com.czblood.busBloodbank.pojo.VO;
import com.czblood.bus.pojo.XkOutDetail;
import com.czblood.bus.pojo.XkOutMain;
import com.czblood.bus.pojo.XkPatientInfo;
import com.czblood.bus.pojo.XkTransfuseApply;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -16,5 +17,6 @@ public class BloodOutInfoVO {
private XkOutMain xkOutMain;
private List<XkOutDetail> xkOutDetailList;
private XkTransfuseApply xkTransfuseApply;
private XkPatientInfo xkPatientInfo;
private String userId;
}

View File

@ -1,5 +1,6 @@
package com.czblood.busBloodbank.service;
import com.czblood.busBloodbank.pojo.VO.BloodOutAuditVO;
import com.czblood.busBloodbank.pojo.VO.BloodOutInfoVO;
import com.czblood.common.core.domain.Result;
@ -8,4 +9,5 @@ public interface BloodOutService {
Result queryWaitInfo();
Result getBloodInfoOut(String bloodNo, String productNo,String applyNo);
Result saveData(BloodOutInfoVO bloodOutInfoVO);
Result bloodOutAudit(BloodOutAuditVO bloodOutAuditVO);
}

View File

@ -1,5 +1,6 @@
package com.czblood.busBloodbank.service.impl;
import cn.hutool.core.date.DateUtil;
import com.czblood.bus.mapper.*;
import com.czblood.bus.pojo.*;
import com.czblood.bus.pojo.xtwh.XkBloodBreed;
@ -7,8 +8,10 @@ import com.czblood.bus.utils.BloodBankUtil;
import com.czblood.busBloodbank.mapper.BloodOutMapper;
import com.czblood.busBloodbank.pojo.DTO.BloodOutDTO;
import com.czblood.busBloodbank.pojo.DTO.BloodOutInfoDTO;
import com.czblood.busBloodbank.pojo.VO.BloodOutAuditVO;
import com.czblood.busBloodbank.pojo.VO.BloodOutInfoVO;
import com.czblood.busBloodbank.service.BloodOutService;
import com.czblood.busBloodbank.utils.BloodOutUtil;
import com.czblood.busBloodbank.utils.MatchBloodUtil;
import com.czblood.common.core.domain.Result;
import org.springframework.stereotype.Service;
@ -38,7 +41,9 @@ public class BloodOutServiceImpl implements BloodOutService {
@Resource
XkOutMainMapper xkOutMainMapper;
@Resource
XkMatchMainMapper xkMatchMainMapper;
XkInstorageDetailMapper xkInstorageDetailMapper;
@Resource
BloodOutUtil bloodOutUtil;
@ -92,6 +97,10 @@ public class BloodOutServiceImpl implements BloodOutService {
// }
result = matchBloodUtil.checkBloodExistOut(bloodNo, productNo, applyNo);
if(!result.getCode().equals("0")) return result;
List<XkInstorageDetail> xkInstorageDetailList = xkInstorageDetailMapper.queryByBloodNo(bloodNo, productNo);
if(!xkInstorageDetailList.isEmpty()){
bloodOutInfoDTO.setPrice(xkInstorageDetailList.get(0).getPrice());
}
//返回数据
bloodOutInfoDTO.setXkBloodInfo(xkBloodInfo);
return new Result("0","操作成功",bloodOutInfoDTO);
@ -114,15 +123,33 @@ public class BloodOutServiceImpl implements BloodOutService {
matchNo = BloodBankUtil.isBank(xkMatchMain.getBill_no());
checkNo = BloodBankUtil.isBank(xkMatchMain.getCheck_no());
}
xkOutMain.setMatch_no(matchNo);
xkOutMain.setCheck_no(checkNo);
xkOutMain.setExp2("Y"); //通知取血护士
xkOutMain.setNotify_time(currentTimeDate);
XkTransfuseApply xkTransfuseApply = xkTransfuseApplyMapper.queryOne(applyNo);
if(xkTransfuseApply == null) return new Result("-1","没有获取到申请单信息,请检查!");
String newBillNo = "";
if(!bModify){
//如果上面没有取到,可能是不需要进行交叉配血的申请单,直接从血型复核当中取checkNo
if(checkNo.equals("")) checkNo = BloodBankUtil.isBank(bloodOutMapper.queryMaxCheckNo(applyNo));
xkOutMain.setMatch_no(matchNo);
xkOutMain.setCheck_no(checkNo);
xkOutMain.setExp2("Y"); //通知取血护士
xkOutMain.setNotify_time(currentTimeDate);
xkOutMain.setBill_sort("C"); //程序默认C 了 。。。
xkOutMain.setIs_free_account("N");
xkOutMain.setAll_recycle_sign("N");
//新增
String newBillNo = bloodBankUtil.produceBillNo("FXD");
newBillNo = bloodBankUtil.produceBillNo("FXD");
xkOutMain.setBill_no(newBillNo);
for (XkOutDetail xkOutDetail : xkOutDetailList) {
xkOutDetail.setBill_no(newBillNo);
}
//只修改血型
XkTransfuseApply xkTransfuseApply1 = bloodOutInfoVO.getXkTransfuseApply();
XkTransfuseApply xkTransfuseApplyTemp = new XkTransfuseApply();
xkTransfuseApplyTemp.setBill_no(xkTransfuseApply1.getBill_no());
xkTransfuseApplyTemp.setAbo_type(xkTransfuseApply1.getAbo_type());
xkTransfuseApplyTemp.setRh_type(xkTransfuseApply1.getRh_type());
bloodOutInfoVO.setXkTransfuseApply(xkTransfuseApplyTemp);
bloodOutUtil.saveBloodOutInfo(bloodOutInfoVO);
}else{
//修改
@ -131,9 +158,24 @@ public class BloodOutServiceImpl implements BloodOutService {
XkOutMain xkOutMainDB = xkOutMainMapper.queryOne(billNo);
String checkSign = xkOutMainDB.getCheck_sign();
if(checkSign.equals("Y")) return new Result("-1","该单据已经通过审核,不能作修改!");
bloodOutUtil.updateBloodOutInfo(bloodOutInfoVO);
}
return null;
return new Result("0","保存成功!",newBillNo);
}
@Override
public Result bloodOutAudit(BloodOutAuditVO bloodOutAuditVO) {
String billNo = bloodOutAuditVO.getBillNo();
String applyNo = bloodOutAuditVO.getApplyNo();
Result result = bloodBankUtil.checkOperatorModify("LCFX", bloodOutAuditVO.getBillNo(), false, bloodOutAuditVO.getUserId());
if(!result.getCode().equals("0")) return result;
XkOutMain xkOutMainDB = xkOutMainMapper.queryOne(billNo);
String checkSign = xkOutMainDB.getCheck_sign();
if(checkSign.equals("Y")) return new Result("-1","该单据已经通过审核,不能作修改!");
Result result1 = checkSampleValid(applyNo);
if(!result1.getCode().equals("0")) return result1;
//TODO 后面还有逻辑
return new Result("0","审核成功");
}
@ -251,4 +293,16 @@ public class BloodOutServiceImpl implements BloodOutService {
}
return new Result("0","检验通过!");
}
public Result checkSampleValid(String applyNo){
Date maxPickDate = bloodOutMapper.querySampleMaxPickDate(applyNo);
//标本采集时间与发血的时间间隔,当标本采集时间与发血时间的间隔大于本参数时进行相应的操作,参数值为正数,天数
String overstepDay = bloodBankUtil.getParameterValue("overstep_day");
Date pickDate = DateUtil.offsetDay(maxPickDate, Integer.parseInt(overstepDay));
Date currentTimeDate = bloodBankUtil.getCurrentTimeDate();
if(pickDate.compareTo(currentTimeDate) <= 0){
return new Result("-1","标本时间已经超过了设定的有效天数,不可以继续操作!");
}
return new Result("0","操作成功");
}
}

View File

@ -2,9 +2,11 @@ package com.czblood.busBloodbank.utils;
import com.czblood.bus.mapper.XkOutDetailMapper;
import com.czblood.bus.mapper.XkOutMainMapper;
import com.czblood.bus.mapper.XkPatientInfoMapper;
import com.czblood.bus.mapper.XkTransfuseApplyMapper;
import com.czblood.bus.pojo.XkOutDetail;
import com.czblood.bus.pojo.XkOutMain;
import com.czblood.bus.pojo.XkPatientInfo;
import com.czblood.bus.pojo.XkTransfuseApply;
import com.czblood.busBloodbank.pojo.VO.BloodOutInfoVO;
import org.springframework.stereotype.Component;
@ -22,19 +24,39 @@ public class BloodOutUtil {
private XkOutMainMapper xkOutMainMapper;
@Resource
private XkTransfuseApplyMapper xkTransfuseApplyMapper;
@Resource
XkPatientInfoMapper xkPatientInfoMapper;
@Transactional(rollbackFor = Exception.class)
public void saveBloodOutInfo(BloodOutInfoVO bloodOutInfoVO) {
XkOutMain xkOutMain = bloodOutInfoVO.getXkOutMain();
List<XkOutDetail> xkOutDetailList = bloodOutInfoVO.getXkOutDetailList();
XkTransfuseApply xkTransfuseApply = bloodOutInfoVO.getXkTransfuseApply();
XkPatientInfo xkPatientInfo = bloodOutInfoVO.getXkPatientInfo();
xkOutMainMapper.insert(xkOutMain);
for (XkOutDetail xkOutDetail : xkOutDetailList) {
xkOutDetailMapper.insert(xkOutDetail);
}
if(xkTransfuseApply != null){
xkTransfuseApplyMapper.insert(xkTransfuseApply);
if(xkTransfuseApply != null) xkTransfuseApplyMapper.update(xkTransfuseApply);
if(xkPatientInfo != null) xkPatientInfoMapper.updateXkPatientInfo(xkPatientInfo);
}
@Transactional(rollbackFor = Exception.class)
public void updateBloodOutInfo(BloodOutInfoVO bloodOutInfoVO){
XkOutMain xkOutMain = bloodOutInfoVO.getXkOutMain();
List<XkOutDetail> xkOutDetailList = bloodOutInfoVO.getXkOutDetailList();
XkTransfuseApply xkTransfuseApply = bloodOutInfoVO.getXkTransfuseApply();
XkPatientInfo xkPatientInfo = bloodOutInfoVO.getXkPatientInfo();
if(!xkOutDetailList.isEmpty()){
String billNo = xkOutDetailList.get(0).getBill_no();
xkOutDetailMapper.deleteByBillNo(billNo);
for (XkOutDetail xkOutDetail : xkOutDetailList) {
xkOutDetailMapper.insert(xkOutDetail);
}
}
xkOutMainMapper.update(xkOutMain);
if(xkTransfuseApply != null) xkTransfuseApplyMapper.update(xkTransfuseApply);
if(xkPatientInfo != null) xkPatientInfoMapper.updateXkPatientInfo(xkPatientInfo);
}

View File

@ -158,4 +158,10 @@
<select id="queryXkMatchMain" resultType="com.czblood.bus.pojo.XkMatchMain">
SELECT * FROM xk_match_main Where apply_no = #{applyNo} AND bill_status ='A'
</select>
<select id="queryMaxCheckNo" resultType="java.lang.String">
select top 1 bill_no from xk_check_bloodtype where apply_no = #{applyNo} order by test_date
</select>
<select id="querySampleMaxPickDate" resultType="java.util.Date">
SELECT Max(Pick_Date) FROM xk_sample_info Where Relate_Applyno = #{applyNo}
</select>
</mapper>