package thyyxxk.webserver.service.zhuyuanyisheng; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.ListUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import thyyxxk.webserver.config.exception.BizException; import thyyxxk.webserver.config.exception.ExceptionEnum; import thyyxxk.webserver.constants.Capacity; import thyyxxk.webserver.constants.sidicts.ChargeStatus; import thyyxxk.webserver.dao.his.inpatient.XiangMuLuRuDao; import thyyxxk.webserver.dao.his.zhuyuanyisheng.YiZhuLuRuDao; import thyyxxk.webserver.entity.ResultVo; import thyyxxk.webserver.entity.RoleCode; import thyyxxk.webserver.entity.datamodify.GetDropdownBox; import thyyxxk.webserver.entity.datamodify.YzActOrder; import thyyxxk.webserver.entity.datamodify.ZyDetailCharge; import thyyxxk.webserver.entity.inpatient.patient.Overview; import thyyxxk.webserver.entity.inpatient.patient.Patient; import thyyxxk.webserver.entity.login.UserInfo; import thyyxxk.webserver.entity.zhuyuanyisheng.DoctorSOrderFee; import thyyxxk.webserver.entity.zhuyuanyisheng.ZyOrderZk; import thyyxxk.webserver.entity.zhuyuanyisheng.yizhuluru.*; import thyyxxk.webserver.service.PublicServer; import thyyxxk.webserver.service.externalhttp.DrgWebServices; import thyyxxk.webserver.service.heliyongyao.RationalUseServer; import thyyxxk.webserver.service.redislike.RedisLikeService; import thyyxxk.webserver.utils.*; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; /** *

* 描述: 医嘱录入 *

* * @author xc * @date 2022-01-04 16:59 */ @Service @Slf4j public class YiZhuLuRuServer { private final YiZhuLuRuDao dao; private final PublicServer publicServer; private final RedisLikeService redisLikeService; private final XiangMuLuRuDao xiangMuLuRuDao; private final RationalUseServer rationalUseServer; private final DrgWebServices drgWebServices; /** * 转科的医嘱编码 */ private final String ZK_CODE = "06286"; private final String ONCE = "ONCE"; private final String ITEM = "00"; private final String SMALL_PACKAGE = "01"; private final String BIG_PACKAGE = "99"; public YiZhuLuRuServer(YiZhuLuRuDao dao, PublicServer publicServer, RedisLikeService redisLikeService, XiangMuLuRuDao xiangMuLuRuDao, RationalUseServer rationalUseServer, DrgWebServices drgWebServices) { this.dao = dao; this.publicServer = publicServer; this.redisLikeService = redisLikeService; this.xiangMuLuRuDao = xiangMuLuRuDao; this.rationalUseServer = rationalUseServer; this.drgWebServices = drgWebServices; } public ResultVo getOrderNo() { return ResultVoUtil.success(BigDecimal.valueOf(publicServer.getActOrderNo()).stripTrailingZeros().toPlainString()); } public ResultVo> getMyPatient() { return ResultVoUtil.success(dao.getMyPatient(TokenUtil.getTokenUserId())); } /** * 获取医嘱的名称 这里为什么不用 医嘱的code和医嘱号呢,是因为药品编码和项目编码有些一样而医嘱号,又每次只能查询一个 * * @param inpatientNo 住院号 * @param admissTimes 住院次数 * @param orderName 前端搜索的医嘱名称 * @return 返回医嘱名称去重了 */ public ResultVo> huoQuYiZhuMingCheng(String inpatientNo, Integer admissTimes, String orderName) { return ResultVoUtil.success(dao.huoQuYiZhuMingZi(inpatientNo, admissTimes, StringUtil.isContainChinese(orderName))); } /** * 获取患者个人的频率 * * @param patNo 住院号 * @param times 住院次数 * @return 返回自己的医嘱频率 */ @Deprecated public ResultVo> huoQuGeRenPinLv(String patNo, Integer times) { return ResultVoUtil.success(dao.huoQuGeRenPinLv(patNo, times)); } /** * 获取医嘱的数据 * 可以根据,医嘱时间区间,执行频率,医嘱名 * * @param param 查询条件 * @return 返回分页数据,同时做了树状图,这样会有一个问题,那就是开了套餐的数据查询不出来 */ public ResultVo> huoQuYiZhuShuJu(YiZhuFeiYongChaXunTiaoJian param) { QueryWrapper qw = new QueryWrapper<>(); qw.eq("a.inpatient_no", param.getPatNo()).eq("a.admiss_times", param.getTimes()); // qw.orderByDesc("a.act_order_no"); qw.orderByAsc("a.order_time"); List yiZhuList = dao.huoQuYiZhuShuJu(qw); // 还有那些没有被匹配的子级医嘱 Map wuFuJiYiZhu = yiZhuList.stream().collect(Collectors.toMap(XinZhenYzActOrder::getActOrderNo, a -> a, (k1, k2) -> k1)); if (ListUtil.isBlank(yiZhuList)) { return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST); } // 做成树状图 Map map = new HashMap<>(); List tree = new ArrayList<>(); for (XinZhenYzActOrder item : yiZhuList) { if (item.getParentNo() == null) { tree.add(item); wuFuJiYiZhu.remove(item.getActOrderNo()); } map.put(item.getActOrderNo(), item); EntityStringTrim.beanAttributeValueTrim(item); if ("00".equals(item.getSerial())) { item.setGroupNoName("项目"); item.setSerialName("项目"); } else { if ("01".equals(item.getSerial())) { item.setSerialName("小包装"); } else if ("99".equals(item.getSerial())) { item.setSerialName("大包装"); } } } for (XinZhenYzActOrder item : yiZhuList) { XinZhenYzActOrder actOrder = map.get(item.getParentNo()); if (actOrder != null) { wuFuJiYiZhu.remove(item.getActOrderNo()); if (actOrder.getChildren() == null) { actOrder.setChildren(new ArrayList<>()); actOrder.setOrderGroup("┌"); } item.setOrderGroup("丨"); actOrder.getChildren().add(item); } } if (!wuFuJiYiZhu.isEmpty()) { tree.addAll(wuFuJiYiZhu.values()); } // 删除前后空格 EntityStringTrim.beanAttributeValueTrimList(tree); List list = new ArrayList<>(); for (XinZhenYzActOrder zy : tree) { list.add(zy); if (ListUtil.notBlank(zy.getChildren())) { zy.getChildren().get(zy.getChildren().size() - 1).setOrderGroup("└"); list.addAll(zy.getChildren()); zy.setChildren(null); } } return ResultVoUtil.success(list); } /** * 获取搜索的项目信息,如药品和项目 * * @param code 拼音首字母,中文,编码来进行搜索 * @return 返回项目信息 */ public ResultVo> huoQuXiangMu(String code) { code = StringUtil.isContainChinese(code); // 药品 List list = dao.yiZhuYaoPing(code, publicServer.getGroupNo()); // 项目 list.addAll(dao.yiZhuXiangMu(code)); // 模板 list.addAll(dao.composeOrders(code, redisLikeService.getUserInfoByToken().getDeptCode())); EntityStringTrim.beanAttributeValueTrimList(list); return ResultVoUtil.success(list); } /** * 获取父医嘱 * * @param patNo 住院号 * @param times 次数 * @return */ public ResultVo> getParentOrders(String patNo, String times) { return ResultVoUtil.success(dao.getParentOrders(patNo, times)); } /** * 确认医嘱 , 这个是最新的正确的 * * @param param 数据 * @return 返回提示 */ public ResultVo> confirmOrders(XinZhenYiZhu param) { QueryWrapper qw = new QueryWrapper<>(); qw.eq("a.inpatient_no", param.getInpatientNo()) .eq("a.admiss_times", param.getAdmissTimes()) .eq("a.status_flag", "1") .eq("a.enter_oper", TokenUtil.getTokenUserId()) // 排除出院带药的医嘱 .ne("a.self_buy", "4"); param.setList(dao.huoQuYiZhuShuJu(qw)); List yiZhuList = param.getList(); if (ListUtil.isBlank(yiZhuList)) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有需要确认的医嘱."); } // 药品 code Set yaoPingCode = new HashSet<>(); // 项目的 code Set xiangMuCode = new HashSet<>(); for (XinZhenYzActOrder item : yiZhuList) { if (ITEM.equals(item.getSerial())) { xiangMuCode.add(item.getOrderCode()); } else { yaoPingCode.add(item.getOrderCode().trim() + item.getSerial().trim()); } } // 合理用药校验 Map> rationalUseOfMedicine = rationalUseServer.jiaoYan(param); String userCode = TokenUtil.getTokenUserId(); // 获取医生开药品的权限 Integer doctorLevel = dao.huoQuYiShenDengJi(userCode); XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes()); Map drug = getDrugInformation(yaoPingCode, huanZheXinXi.getSmallDept()); Map> project = getProjectInformation(xiangMuCode); // 是否可以确认 boolean isThereAnyErrorMessage = false; Map map = new HashMap<>(); List confirmOrderInformation = new ArrayList<>(); Date excludeOrders = null; BigDecimal orderNo = null; for (XinZhenYzActOrder item : yiZhuList) { if (ITEM.equals(item.getSerial())) { Integer paiChiYiZhu = dao.shiFouPaiChiYiZhu(item.getOrderCode()); if (excludeOrders != null) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "一次性不能确认多条全排斥医嘱。"); } if (paiChiYiZhu != null && paiChiYiZhu.equals(1)) { excludeOrders = item.getStartTime(); orderNo = item.getActOrderNo(); } } confirmOrderInformation.add(item.getActOrderNo()); Map errorMessageMap = checkData(item, drug, project, huanZheXinXi, doctorLevel); String key = item.getId(); if (rationalUseOfMedicine.containsKey(key)) { List temp = (List) errorMessageMap.get("error"); if (temp == null) { errorMessageMap.put("error", rationalUseOfMedicine.get(key)); } else { temp.addAll(rationalUseOfMedicine.get(key)); } } log.info("错误信息:{}", JSON.toJSONString(errorMessageMap)); if (!errorMessageMap.isEmpty()) { if (!isThereAnyErrorMessage && errorMessageMap.containsKey("error")) { isThereAnyErrorMessage = true; } errorMessageMap.put("data", item); map.put(item.getId(), errorMessageMap); } } if (isThereAnyErrorMessage) { return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请修改错误的医嘱", map); } if (excludeOrders != null) { int count = dao.thereAreUnexecutedOrders(param.getInpatientNo(), param.getAdmissTimes(), orderNo); if (count > 0) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "有未确认和未执行的长期医嘱,无法确认全排斥医嘱,请先确认其他医嘱。"); } dao.stopOrder(param.getInpatientNo(), param.getAdmissTimes(), excludeOrders, userCode, orderNo); } for (BigDecimal decimal : confirmOrderInformation) { dao.confirmOrders(decimal, userCode, new Date()); } try { JSONObject jsonDrg = new JSONObject(); jsonDrg.put("visit_id", Collections.singletonList(huanZheXinXi.getInpatientNo() + "_" + huanZheXinXi.getAdmissTimes())); jsonDrg.put("scene_type", 1); drgWebServices.etlClient(jsonDrg); } catch (Exception e) { e.printStackTrace(); } log.info("确认的医嘱:{}", JSON.toJSONString(yiZhuList)); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION); } private void dischargeMedicineList(Map> map, XinZhenYiZhu huanZheXinXi) { if (dao.obtainTheNumberOfDischargedDrugs(huanZheXinXi.getInpatientNo(), huanZheXinXi.getAdmissTimes()) > 4) { throw new BizException(ExceptionEnum.LOGICAL_ERROR, "出院带药医嘱不得超过 4 种,且不得超过 15 天。"); } String userCode = TokenUtil.getTokenUserId(); // 根据不同的药房,生成不同的单子. for (Map.Entry> entry : map.entrySet()) { Integer pageNo = publicServer.getTheDrugListNo(); dao.summarySheetOfDrugs(pageNo, huanZheXinXi, userCode, entry.getKey()); dao.insertDetailedMedicineList(pageNo, huanZheXinXi, userCode, entry.getKey(), entry.getValue()); } } /** * 录入单条医嘱 新的 下面的保存医嘱的都无效了 * * @param param 参数 * @return 错误信息和提示 */ public ResultVo> enterOrders(XinZhenYiZhu param) { XinZhenYzActOrder oldOrderNo = dao.getActOrderNoOne(param.getActOrderNo()); if (oldOrderNo != null) { if (!"1".equals(oldOrderNo.getStatusFlag().trim())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该医嘱不是录入状态无法保存."); } if (!oldOrderNo.getInpatientNo().trim().equals(param.getInpatientNo())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "两次医嘱的."); } } String userCode = TokenUtil.getTokenUserId(); // 获取医生开药品的权限 Integer doctorLevel = dao.huoQuYiShenDengJi(userCode); XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes()); XinZhenYzActOrder data = param.getData(); // 设置 药房 data.setGroupNo(param.getGroupNo()); if (ITEM.equals(data.getSerial().trim())) { data.setGroupNo("00"); } if (data.getParentNo() != null) { data.setSupplyCode("044"); } // 药品的 code Set yaoPingCode = new HashSet<>(); // 项目的 code Set xiangMuCode = new HashSet<>(); if (ITEM.equals(data.getSerial())) { xiangMuCode.add(data.getOrderCode()); } else { yaoPingCode.add(data.getOrderCode().trim() + data.getSerial().trim()); } Map drug = getDrugInformation(yaoPingCode, huanZheXinXi.getSmallDept()); Map> project = getProjectInformation(xiangMuCode); Map errorMessageMap = checkData(data, drug, project, huanZheXinXi, doctorLevel); if (data.getParentNo() != null) { XinZhenYzActOrder parentOrder = dao.getActOrderNoOne(data.getParentNo().stripTrailingZeros().toPlainString()); if (parentOrder != null) { data.setFrequCode(parentOrder.getFrequCode()); } } // 删除抗菌药物信息 dao.deleteAntimicrobialInformation(param.getActOrderNo()); // 先删除转科在插入 dao.deleteTransferOrder(param.getActOrderNo()); if (errorMessageMap.isEmpty()) { if (ZK_CODE.equals(data.getOrderCode())) { ZyOrderZk transferData = new ZyOrderZk(); transferData .setActOrderNo(param.getActOrderNo()) .setNewDept(data.getZkDeptCode()) .setNewWard(data.getZkWardCode()) .setOldWard(huanZheXinXi.getDeptCode()) .setOldDept(huanZheXinXi.getSmallDept()); dao.insertDoctorSOrder(transferData); } // 判断是不是抗菌药物 XinZhenYzActOrder kssItem = drug.get(data.getOrderCode().trim() + data.getSerial().trim()); if (kssItem != null && kssItem.getKjywFlag() != null && kssItem.getKjywFlag() == 1) { YzActRecordKss kss = new YzActRecordKss(); kss.setActOrderNo(data.getActOrderNo()); kss.setChargeCode(data.getOrderCode()); kss.setYyfs(data.getYyfs()); kss.setSsqk(data.getSsqk()); kss.setYysj(data.getYysj()); dao.insertAntimicrobialInformation(param.getActOrderNo(), kss, userCode, param.getInpatientNo(), param.getAdmissTimes()); } } dao.deleteOrderNo(param.getActOrderNo(), param.getInpatientNo(), param.getAdmissTimes()); dao.insertEntryOrder(huanZheXinXi, param.getData(), userCode); if (!errorMessageMap.isEmpty()) { Map map = new HashMap<>(); errorMessageMap.put("data", data); map.put(param.getActOrderNo(), errorMessageMap); if (errorMessageMap.containsKey("error")) { return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请修改有错误的医嘱。", map); } } return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "添加成功."); } /** * 把医嘱模板中的数据插入到 患者的医嘱表中 * * @param param 参数 * @return */ public ResultVo insertTemplateOrder(XinZhenYiZhu param) { if (StringUtil.isBlank(param.getInpatientNo())) { return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请先选择患者."); } Map fatherAndSonDoctorSAdvice = new HashMap<>(param.getList().size()); param.getList().forEach(item -> { fatherAndSonDoctorSAdvice.put(item.getId(), item); item.setActOrderNo(BigDecimal.valueOf(publicServer.getActOrderNo())); }); XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes()); String userCode = TokenUtil.getTokenUserId(); param.getList().forEach(item -> { String key = item.getParentNo() != null ? item.getParentNo().stripTrailingZeros().toPlainString() : ""; item.setGroupNo(param.getGroupNo()); if (StringUtil.notBlank(key)) { if (fatherAndSonDoctorSAdvice.containsKey(key)) { item.setParentNo(fatherAndSonDoctorSAdvice.get(key).getActOrderNo()); } } dao.insertEntryOrder(huanZheXinXi, item, userCode); }); return ResultVoUtil.success(); } /** * 删除单条医嘱 * * @param orderNo 医嘱号 * @return 提示 */ public ResultVo toDeleteAnOrder(String orderNo) { XinZhenYzActOrder oldData = dao.getActOrderNoOne(orderNo); String message = judgeWhetherItCanBeDeleted(oldData); if (StringUtil.notBlank(message)) { return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, message); } dao.toDeleteAnOrder(orderNo, oldData.getInpatientNo()); dao.deleteGroup(orderNo); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION); } /** * 删除多条录入的医嘱 * * @param param 参数 * @return 返回提示 */ public ResultVo> deleteMultipleOrders(XinZhenYiZhu param) { QueryWrapper qw = new QueryWrapper<>(); qw.eq("inpatient_no", param.getInpatientNo()); qw.eq("admiss_times", param.getAdmissTimes()); List list = new ArrayList<>(); param.getList().forEach(item -> { list.add(item.getActOrderNo()); }); qw.in("act_order_no", list); List deleteOrderList = dao.getOrdersToDelete(qw); if (ListUtil.isBlank(deleteOrderList)) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到原医嘱可能已经被删除了"); } Map map = new HashMap<>(); deleteOrderList.forEach(item -> { String error = judgeWhetherItCanBeDeleted(item); if (StringUtil.notBlank(error)) { map.put(item.getActOrderNo().stripTrailingZeros().toPlainString(), error); } }); log.info("数据:{}", deleteOrderList); if (map.isEmpty()) { dao.deleteParentChildRelationship(param.getInpatientNo(), param.getAdmissTimes(), list); dao.deleteMultipleOrders(qw); return ResultVoUtil.fail(ExceptionEnum.SUCCESS_AND_NOTIFICATION); } return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "删除失败", map); } private String judgeWhetherItCanBeDeleted(XinZhenYzActOrder oldData) { StringBuilder str = new StringBuilder(); if (oldData == null) { return "没有找到原医嘱可能已经被删除了"; } if (!"1".equals(oldData.getStatusFlag())) { str.append("该医嘱不是录入状态,无法删除"); } if (!oldData.getEnterOper().equals(TokenUtil.getTokenUserId())) { str.append("该医嘱录入人不是您,无法删除."); } return str.toString(); } public ResultVo> stopOrder(XinZhenYiZhu param) { if (ListUtil.isBlank(param.getList())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请先选择数据"); } Map map = new HashMap<>(); param.getList().forEach(item -> { if (item.getEndTime() == null) { map.put(item.getActOrderNo(), "停止时间不能为空。"); } else { // 因为前端用的是浏览器自带的 所以要删除 T if (DateUtil.shiJianDaXiao(item.getEndTime(), item.getStartTime(), "<")) { map.put(item.getActOrderNo(), "停止时间不能小于医嘱的开始时间。"); } } }); if (map.isEmpty()) { dao.setStopTime(param.getList(), TokenUtil.getTokenUserId(), param.getInpatientNo(), param.getAdmissTimes()); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION); } return ResultVoUtil.success(ExceptionEnum.ERROR_MESSAGE, "请修改有错误的医嘱", map); } @Transactional(rollbackFor = Exception.class) public ResultVo voidOrders(String orderNo, String reasonForCancellation) { XinZhenYzActOrder yz = dao.getActOrderNoOne(orderNo); if (yz == null) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "原医嘱找不到了。"); } if ("6".equals(yz.getStatusFlag())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医嘱已作废了。"); } UserInfo userInfo = redisLikeService.getUserInfoByToken(); if (!DateUtil.within24Hours(yz.getStartTime())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "只能对24小时内的医嘱进行作废处理"); } List list = dao.getTheDoctorSDepartment(userInfo.getDeptCode()); list.add(userInfo.getDeptCode()); if (!list.contains(yz.getWardCode())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "非本科室开的医嘱不可作废"); } if (dao.getADoctorSOrderWithADefiniteFee(yz.getInpatientNo(), yz.getAdmissTimes(), orderNo) > 0) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该医嘱已经产生了医技费用,请对应的医技科室进行退费处理。"); } if (dao.getDetailChargeFee(yz.getInstruction(), yz.getAdmissTimes(), orderNo) > 0) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该医嘱已经产生了医技费用,请对应的医技科室进行退费处理。"); } // 患者最大的 detail_sn int maxDetailSn = publicServer.getMaxDetailSn(yz.getInpatientNo(), yz.getAdmissTimes()); dao.cancelMedicalTechnologyAssuranceFee(TokenUtil.getTokenUserId(), orderNo, yz.getInpatientNo(), yz.getAdmissTimes()); // 如果是药品的话就需要自动退费 if (!yz.getSerial().equals(ITEM)) { List parentNoList = dao.getParentChildOrders(orderNo); parentNoList.add(orderNo); List feeList = dao.getExpenseData(yz.getInpatientNo(), yz.getAdmissTimes(), parentNoList); if (ListUtil.notBlank(feeList)) { List refundArray = new ArrayList<>(feeList.size()); for (ZyDetailCharge item : feeList) { // 取负数的费用 item.setChargeFee(item.getChargeFee().negate()); item.setChargeAmount(item.getChargeAmount().negate()); item.setOpIdCode(userInfo.getCode()); item.setOriDetailSn(item.getDetailSn()); // 设置 流水号 item.setDetailSn(maxDetailSn += 1); item.setOrderNo(new BigDecimal(0)); refundArray.add(item); } List> fenGe = ListUtils.partition(refundArray, 20); fenGe.forEach(xiangMuLuRuDao::xiangMuTuiFei); dao.updateItemFlag(yz.getInpatientNo(), yz.getAdmissTimes(), parentNoList); } } dao.updateVoidedOrders(orderNo, userInfo.getCode(), reasonForCancellation); dao.updateChildOrders(orderNo, userInfo.getCode(), reasonForCancellation); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "撤销成功。"); } /** * 获取某一个费用的详细信息 * * @param code 编码 * @param serial 00-项目 01-小包装的药品 99-大包装 * @return 返回该费用的一些详细信息,以及一些提示信息。 */ public ResultVo> huoQuFeiYongXinXi(String code, String serial, String deptCode) { Map map = new HashMap<>(); // 一些提示 List prompt = new ArrayList<>(); // 加载项目信息 if (ITEM.equals(serial.trim())) { List xiangMu = dao.huoQuXiangMu(code); for (XinZhenYzActOrder item : xiangMu) { if (item.getDelFlag() == 1) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("该医嘱下的【%s】,已经被停用了,请联系物价科。", item.getOrderName())); } else if (StringUtil.isBlank(item.getNationalCode())) { prompt.add(String.format("该医嘱下面的【%s】,没有医保编码,请注意。", item.getOrderName())); } else { prompt.add(String.format("该医嘱下【%s】,医保码为:【%s】。", item.getOrderName(), item.getNationalCode())); } } if (ListUtil.isBlank(xiangMu)) { Integer paiChiYiZhu = dao.shiFouPaiChiYiZhu(code); if (paiChiYiZhu != null) { switch (paiChiYiZhu) { case 1: prompt.add("全排斥医嘱"); break; case 2: prompt.add("单组排斥医嘱"); break; case 3: prompt.add("多组斥医嘱"); break; default: break; } } } } else { YaoPinXinXi yp = dao.huoQuYaoPin(code.trim() + serial.trim(), publicServer.getGroupNo()); if (StringUtil.notBlank(deptCode)) { if (dao.restrictedUseInTheDepartment(code.trim(), deptCode) > 0) { return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "该药品禁止在患者所在的科室使用。"); } } if (yp == null) { return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "该医嘱下的药品,可能已经被停用了,请联系药剂科。"); } if (yp.getVisibleFlagZy() == 1) { return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "该药品禁止住院使用。"); } Integer yiShenDengJi = dao.huoQuYiShenDengJi(TokenUtil.getTokenUserId()); int yiShen = yiShenDengJi == null ? 0 : yiShenDengJi; if (yp.getYpLevel() > yiShen + 1) { return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "您没有开此药品的权限。"); } List yaoPingJiLiang = new ArrayList<>(); if (StringUtil.notBlank(yp.getWeighUnit())) { yaoPingJiLiang.add(new YaoPingJiLiang(yp.getWeighUnit(), yp.getWeighUnitName(), yp.getWeight())); } if (StringUtil.notBlank(yp.getVolUnit())) { yaoPingJiLiang.add(new YaoPingJiLiang(yp.getVolUnit(), yp.getVolUnitName(), yp.getVolum())); } if (StringUtil.notBlank(yp.getPackUnit())) { yaoPingJiLiang.add(new YaoPingJiLiang(yp.getPackUnit(), yp.getPackUnitName(), yp.getPackSize())); } if (yp.getKjywFlag() == 1) { prompt.add("抗菌药物,需填写抗菌药物医嘱附注"); } if (yp.getSelfFlagYb() == 1) { prompt.add("该药品医保自费药品,如符合条件请填写记账,不是请填写自费"); } if (StringUtil.isBlank(yp.getNationalCode())) { prompt.add("该药品医保没有匹配医保码"); } else { prompt.add(String.format("药品医保码为:【%s】", yp.getNationalCode())); } if (yp.getStockAmount() != null && BigUtils.bigXiaoYu(yp.getStockAmount(), 10)) { prompt.add(String.format("该药品剩余数量为:【%s】", yp.getStockAmount().stripTrailingZeros().toPlainString())); } if (yp.getPsFlag() == 1) { prompt.add("此药品为皮试药品"); map.put("piShi", dao.piShiGeiYaoFangShi()); } map.put("yaoPingJiLiang", yaoPingJiLiang); map.put("data", yp); } map.put("prompt", prompt); return ResultVoUtil.success(map); } /** * 获取频率 * * @param code 五笔,拼音,中文,编码 * @return 返回对应的数据 */ public ResultVo> huoQuZhuYuanPinLv(String code) { return ResultVoUtil.success(dao.huoQuZhuYuanPinLv("%" + code.toUpperCase() + "%")); } /** * 获取给药方式 * * @param code 五笔,拼音,中文,编码 * @return 返回对应的数据 */ public ResultVo> huoQuGeiYaoFangShi(String code) { return ResultVoUtil.success(dao.huoQuGeiYaoFangShi(StringUtil.isContainChinese(code))); } public ResultVo> getCostFreeDosing(String code) { return ResultVoUtil.success(dao.getCostFreeDosing(StringUtil.isContainChinese(code))); } /** * 获取执行科室 * * @param code 五笔,拼音,中文,编码 * @return 返回对应的数据 */ public ResultVo> huoQuZhiXinKeShi(String code) { return ResultVoUtil.success(dao.huoQuZhiXinKeShi(StringUtil.isContainChinese(code))); } public ResultVo> singleDataCheck(XinZhenYiZhu param) { // 获取医生开药品的权限 Integer doctorLevel = dao.huoQuYiShenDengJi(TokenUtil.getTokenUserId()); Set yaoPingCode = new HashSet<>(); Set xiangMuCode = new HashSet<>(); for (XinZhenYzActOrder item : param.getList()) { if (ITEM.equals(item.getSerial().trim())) { xiangMuCode.add(item.getOrderCode().trim()); } else { yaoPingCode.add(item.getOrderCode().trim() + item.getSerial().trim()); } } XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes()); Map errorMessage = checkData(param.getList().get(0), getDrugInformation(yaoPingCode, huanZheXinXi == null ? null : huanZheXinXi.getSmallDept()), getProjectInformation(xiangMuCode), huanZheXinXi, doctorLevel); errorMessage.put("data", param.getList().get(0)); return ResultVoUtil.success(errorMessage); } /** * 保存医嘱 * * @param param 医嘱数据 * @return 返回错误提示或者别的 */ @Deprecated public ResultVo> saveTheDoctorSOrder(XinZhenYiZhu param) { log.info("上传数据:{}", JSON.toJSONStringWithDateFormat(param, DateUtil.DEFAULT_PATTERN)); // 获取医生开药品的权限 Integer doctorLevel = dao.huoQuYiShenDengJi(TokenUtil.getTokenUserId()); // 药品的 code Set yaoPingCode = new HashSet<>(); // 项目的 code Set xiangMuCode = new HashSet<>(); // id 做 map Map doctorSOrderMap = new HashMap<>(param.getList().size()); for (XinZhenYzActOrder item : param.getList()) { if (ITEM.equals(item.getSerial().trim())) { xiangMuCode.add(item.getOrderCode().trim()); } else { yaoPingCode.add(item.getOrderCode().trim() + item.getSerial().trim()); } doctorSOrderMap.put(item.getId(), item); } // 医嘱 map {医嘱号: { 具体数据 }} // 获取患者信息 XinZhenYiZhu huanZheXinXi = dao.huoQuHuanZheXinXi(param.getInpatientNo(), param.getAdmissTimes()); if (huanZheXinXi == null) { throw new BizException(ExceptionEnum.LOGICAL_ERROR, "没有查询到患者的在院信息。"); } // 设置婴儿标志 huanZheXinXi.setInfantFlag(PublicServer.getInfantFlag(huanZheXinXi.getInpatientNo())); boolean isThereAnyErrorMessage = false; Map map = new HashMap<>(); Map drug = getDrugInformation(yaoPingCode, huanZheXinXi.getSmallDept()); Map> project = getProjectInformation(xiangMuCode); int index = 0; for (XinZhenYzActOrder item : param.getList()) { Map errorMessageMap = checkData(item, drug, project, huanZheXinXi, doctorLevel); if (!errorMessageMap.isEmpty()) { if (!isThereAnyErrorMessage && errorMessageMap.containsKey("error")) { isThereAnyErrorMessage = true; } map.put(item.getId(), errorMessageMap); } errorMessageMap.put("data", item); errorMessageMap.put("index", index++); } if (isThereAnyErrorMessage) { return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请修改错误的医嘱", map); } /* 在这里上传医嘱,一点错误信息都没了的话 */ // 这个是 抗菌药物的信息 List kssList = new ArrayList<>(); // 这个是 转科医嘱的 ZyOrderZk transferData = null; for (XinZhenYzActOrder item : param.getList()) { // 生成医嘱号 item.setActOrderNo(BigDecimal.valueOf(publicServer.getActOrderNo())); if (item.getParentNo() != null && doctorSOrderMap.containsKey(item.getParentNo().stripTrailingZeros().toPlainString())) { item.setParentNo(doctorSOrderMap.get(item.getParentNo().stripTrailingZeros().toPlainString()).getActOrderNo()); } if (item.getKjywFlag() != null && item.getKjywFlag() == 1) { YzActRecordKss kss = new YzActRecordKss(); kss.setActOrderNo(item.getActOrderNo()); kss.setChargeCode(item.getOrderCode()); kss.setYyfs(item.getYyfs()); kss.setSsqk(item.getSsqk()); kss.setYysj(item.getYysj()); kssList.add(kss); } if (ZK_CODE.equals(item.getOrderCode())) { transferData = new ZyOrderZk(); transferData.setActOrderNo(item.getActOrderNo().stripTrailingZeros().toPlainString()).setNewDept(item.getZkDeptCode()).setNewWard(item.getZkWardCode()); } } // 执行人 String inputCode = TokenUtil.getTokenUserId(); // 判断患者是否结算了 publicServer.huanZheJieSuan(param.getInpatientNo(), param.getAdmissTimes()); if (ListUtil.notBlank(kssList)) { dao.shanChuYuanKuangJunYaoWu(kssList); dao.chaRuKuangJunYaoWuXinXi(huanZheXinXi.getInpatientNo(), huanZheXinXi.getAdmissTimes(), inputCode, kssList); } if (transferData != null) { transferData.setOldWard(huanZheXinXi.getDeptCode()).setOldDept(huanZheXinXi.getSmallDept()); dao.insertDoctorSOrder(transferData); } String groupNo = publicServer.getGroupNo(); sendAMessageToTheNurse(param, inputCode, huanZheXinXi, groupNo); // dao.chaRuYiZhu(huanZheXinXi.getInpatientNo(), huanZheXinXi.getAdmissTimes(), inputCode, huanZheXinXi.getInfantFlag(), huanZheXinXi.getDeptCode(), huanZheXinXi.getDeptCode(), huanZheXinXi.getReferPhysician(), param.getList()); return ResultVoUtil.success(map); } public ResultVo doesTheTemplateExist(String name) { if (dao.duplicateTemplateName(name, TokenUtil.getTokenUserId()) == 0) { return ResultVoUtil.success(); } return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "模板名称重复"); } public ResultVo saveTemplate(YzOrderPattern param) { // 如果名字重复了,那么就修改原来的模板 YzOrderPattern yzOrderPattern = dao.yuanLaiDeMuBanBianMa(param.getPatternName(), TokenUtil.getTokenUserId()); UserInfo userInfo = redisLikeService.getUserInfoByCode(TokenUtil.getTokenUserId()); if (null == yzOrderPattern) { yzOrderPattern = new YzOrderPattern(); } String patternCode = yzOrderPattern.getPatternCode(); // 有原来的模板名称而且 还要是自己创建的才能删除,否则就只能创建新的模板了 if (StringUtil.notBlank(patternCode) && userInfo.getCode().equals(yzOrderPattern.getInputId())) { // 更新的时候先删除模板 原来的模板 dao.shanChuLaoMuBan(patternCode); param.setPatternCode(patternCode); } else { // 设置新的模板号 param.setPatternCode(publicServer.getPatternCode()); } String py = PingYinUtils.pyShouZiMuDaXie(param.getPatternName()); String wb = PingYinUtils.getWBCode(param.getPatternName()); param.setPyCode(py.length() > 9 ? py.substring(0, 9) : py); param.setDCode(wb.length() > 9 ? wb.substring(0, 9) : wb); param.setInputId(TokenUtil.getTokenUserId()); param.setDeptCode(userInfo.getDeptCode()); dao.chaRuMuBan(param); Map map = param.getList().stream().collect(Collectors.toMap(XinZhenYzActOrder::getId, a -> a, (k1, k2) -> k1)); for (XinZhenYzActOrder item : param.getList()) { // 设置模板号 item.setActOrderNo(BigDecimal.valueOf(publicServer.getPatternOrderCode())); if (item.getParentNo() != null && map.containsKey(item.getParentNo().stripTrailingZeros().toPlainString())) { item.setParentNo(map.get(item.getParentNo().stripTrailingZeros().toPlainString()).getActOrderNo()); } } dao.chaRuMuBanShuJu(param.getList(), param.getPatternCode()); return ResultVoUtil.success(); } private void calculateDrugAmount(XinZhenYzActOrder item, XinZhenYzActOrder feiYongXinXi, List 错误信息) { if (feiYongXinXi == null) { return; } if (StringUtil.notBlank(feiYongXinXi.getDrugWeightUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugWeightUnit().trim())) { item.setDrugOcc(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight(), 2)); } else if (StringUtil.notBlank(feiYongXinXi.getDrugVolUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugVolUnit())) { item.setDrugOcc(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume(), 2)); } else if (StringUtil.notBlank(feiYongXinXi.getPackUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getPackUnit())) { if (new BigDecimal(item.getDose().intValue()).compareTo(item.getDose()) != 0) { 错误信息.add("已经是最小单位了请不要带小数点"); } item.setDrugOcc(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize(), 2)); } } private Map checkData(XinZhenYzActOrder item, Map drug, Map> project, XinZhenYiZhu huanZheXinXi, Integer 医生级别) { boolean 严格校验 = huanZheXinXi != null; List 错误信息 = new ArrayList<>(); List 警告信息 = new ArrayList<>(); if (ITEM.equals(item.getSerial())) { List 项目明细 = project.get(item.getOrderCode()); // 如果这个项目下面没有费用明细,那么这就是一条口头医,口头医嘱每次只能开一个 if (ListUtil.isBlank(项目明细)) { item.setDrugQuan(BigDecimal.valueOf(1)); item.setDrugOcc(BigDecimal.valueOf(1)); } else { for (XinZhenYzActOrder 明细 : 项目明细) { if (明细.getDelFlag() == 1) { 错误信息.add(String.format("项目:【%s】,已经被物价停用了", 明细.getOrderName())); } if (StringUtil.isBlank(明细.getNationalCode())) { 警告信息.add(String.format("项目:【%s】,没有匹配医保码", 明细.getOrderName())); } } } } else { XinZhenYzActOrder feiYongXinXi = drug.get(item.getOrderCode().trim() + item.getSerial().trim()); if (feiYongXinXi != null) { if (feiYongXinXi.getDelFlag() == 1) { 错误信息.add("药品已经被停用了,请联系药剂科"); } if (feiYongXinXi.getYpLevel() > 医生级别 + 1) { 错误信息.add("您没有开此药品的权限"); } if (StringUtil.isBlank(feiYongXinXi.getNationalCode())) { 警告信息.add("该药品没有医保编码"); } if (feiYongXinXi.getStockAmount() != null && BigUtils.bigXiaoYu(feiYongXinXi.getStockAmount(), 10)) { 警告信息.add(String.format("该药品剩余数量为:【%s】", feiYongXinXi.getStockAmount().stripTrailingZeros().toPlainString())); } if (严格校验) { if (feiYongXinXi.getDeptRestrictions() > 0) { 错误信息.add("该药品禁止在患者所在的科室使用。"); } if (feiYongXinXi.getVisibleFlagZy() == 1) { 错误信息.add("该药品禁止住院患者使用。"); } item.setKjywFlag(feiYongXinXi.getKjywFlag()); if (feiYongXinXi.getKjywFlag() == 1) { if (item.getYyfs() == null) { 错误信息.add("请填写抗菌药物医嘱附注信息录入"); } else if (item.getYyfs() == 1 || item.getYyfs() == 2) { if (item.getSsqk() == null) { 错误信息.add("当用药方式为 1 或 2 时,手术切口和用药时间不能为空"); } } } } if (item.getSelfBuy() != null && "4".equals(item.getSelfBuy())) { // 如果是临时医嘱 开了就结束了. if ("ONCE".equals(item.getFrequCode())) { item.setEndTime(item.getStartTime()); } if (dao.dischargeWithMedicationAdministration(item.getSupplyCode()) == 0) { 错误信息.add("出院带药给药方式不能包含费用。"); } int day = 1; if (item.getStartTime() == null) { 错误信息.add("出院带药请输入开始时间。"); } if (item.getEndTime() == null) { 错误信息.add("出院带药请输入结束时间。"); } else { long cha = item.getEndTime().getTime() - item.getStartTime().getTime(); long nd = 1000 * 24 * 60 * 60; day = (int) (cha / nd); if (day > 15) { 错误信息.add("出院带药天数不得超过 15 天,计算方式结束时间减去开始时间。"); } } // 计算出院带药的领量 Map numberOfTimesADay = dao.numberOfTimesADay(item.getFrequCode()); int times = 1; for (Map.Entry entry : numberOfTimesADay.entrySet()) { if (entry.getValue() != null) { times += entry.getValue(); } } // 最小天数一天 BigDecimal total = new BigDecimal((day <= 0 ? 1 : day) * times); if (StringUtil.notBlank(feiYongXinXi.getDrugWeightUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugWeightUnit().trim())) { item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight(), 2), total)); item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight()), total)); } else if (StringUtil.notBlank(feiYongXinXi.getDrugVolUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugVolUnit())) { item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume(), 2), total)); item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume()), total)); } else if (StringUtil.notBlank(feiYongXinXi.getPackUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getPackUnit())) { if (new BigDecimal(item.getDose().intValue()).compareTo(item.getDose()) != 0) { 错误信息.add("已经是最小单位了请不要带小数点"); } item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize(), 2), total)); item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize()), total)); } } else { // 计算普通药品的领量 durg_quan durg_occ calculateDrugAmount(item, feiYongXinXi, 错误信息); } } } if (StringUtil.isBlank(item.getOrderCode())) { 错误信息.add("项目编码不能为空"); } if (StringUtil.isBlank(item.getOrderName())) { 错误信息.add("项目名称不能为空"); } if (StringUtil.isBlank(item.getExecUnit())) { 错误信息.add("执行科室不能为空"); } else if (item.getExecUnit().startsWith("8")) { 错误信息.add("执行科室不能选择为病区"); } if (ZK_CODE.equals(item.getOrderCode())) { if (StringUtil.isBlank(item.getZkWardCode())) { 错误信息.add("转科病房不能为空"); } if (StringUtil.isBlank(item.getZkDeptCode())) { 错误信息.add("转科科室不能为空"); } } if (StringUtil.isBlank(item.getFrequCode())) { 错误信息.add("频次不能为空"); } // 药品的校验 if (!ITEM.equals(item.getSerial().trim())) { if (StringUtil.isBlank(item.getDrugSpecification())) { 错误信息.add("药品规格不能为空"); } if (StringUtil.isBlank(item.getSupplyCode())) { 错误信息.add("给药方式不能为空"); } if (item.getDose() == null || BigUtils.dengYu(item.getDose(), 0)) { 错误信息.add("一次计量不能为空"); } if (StringUtil.isBlank(item.getDoseUnit())) { 错误信息.add("计量单位不能为空"); } if (StringUtil.isBlank(item.getSerial())) { 错误信息.add("包装大小不能为空"); } } if (严格校验) { // 获取患者的入院时间 if (item.getOrderTime() == null) { 错误信息.add("医嘱时间不能为空"); } else if (item.getStartTime() == null) { 错误信息.add("开始时间不能为空"); } else if (huanZheXinXi.getAdmissDate() == null) { 错误信息.add("没有查询到患者的入院时间"); } else if (DateUtil.shiJianDaXiao(item.getStartTime(), huanZheXinXi.getAdmissDate(), "<")) { 错误信息.add("开始时间不能在患者入院之前,患者入院时间" + DateUtil.formatDatetime(huanZheXinXi.getAdmissDate())); } else if (DateUtil.shiJianDaXiao(item.getStartTime(), item.getOrderTime(), "<")) { 错误信息.add("开始时间不能在开医嘱之前"); } if (item.getEndTime() != null) { if (ONCE.equals(item.getFrequCode().trim())) { item.setEndTime(null); } else { if (DateUtil.shiJianDaXiao(item.getEndTime(), item.getStartTime(), "<")) { 错误信息.add("结束时间不能在开始时间之前"); } } } } Map map = new HashMap<>(Capacity.TWO); if (ListUtil.notBlank(错误信息)) { map.put("error", 错误信息); } if (ListUtil.notBlank(警告信息)) { map.put("warning", 警告信息); } return map; } /*** * 获取项目信息 * @param xiangMuCode 项目编码 * @return 返回数据 */ private Map> getProjectInformation(Set xiangMuCode) { if (!xiangMuCode.isEmpty()) { return dao.huoQuXiangMuXinXi(xiangMuCode).stream().collect(Collectors.groupingBy(item -> item.getOrderCode().trim())); } return new HashMap<>(0); } /** * 获取药品信息 * * @param yaoPingCode 药品编码 * @return 返回数据 */ private Map getDrugInformation(Set yaoPingCode, String dept) { if (!yaoPingCode.isEmpty()) { return dao.huoQuYaoPinXinXi(yaoPingCode, publicServer.getGroupNo(), dept).stream().collect(Collectors.toMap(item -> item.getOrderCode().trim() + item.getSerial().trim(), a -> a, (k1, k2) -> k1)); } return new HashMap<>(0); } private void sendAMessageToTheNurse(XinZhenYiZhu param, String inputCode, XinZhenYiZhu huanZheXinXi, String groupNo) { List content = new ArrayList<>(); for (XinZhenYzActOrder item : param.getList()) { if (StringUtil.isBlank(item.getDrugFlag())) { item.setDrugFlag("o"); } if ("00".equals(item.getSerial().trim())) { item.setGroupNo("00"); } else if ("01".equals(item.getSerial().trim()) || "99".equals(item.getSerial().trim())) { item.setGroupNo(groupNo); } if (item.getEndTime() != null) { item.setModifier(inputCode); } content.add(String.format("医嘱名:【%s】
" + "医嘱时间:【%tF %
" + "患者姓名:【%s】
" + "床位:【%s】
" + "频次:【%s】", item.getOrderName(), item.getOrderTime(), huanZheXinXi.getName(), huanZheXinXi.getBedNo(), item.getFrequCode())); } publicServer.faSongXiaoXi(huanZheXinXi, content, "新增医嘱", inputCode); } /** * 获取医嘱录入的模板1 * * @param code 模板编码 * @param deptCode 科室编码 * @param muBanLeiXing 项目类型 * @param currentPage 当前页 * @param total 总数 * @return 返回模板 */ public ResultVo> huoQuYiZhuMuBan(String code, String deptCode, Integer muBanLeiXing, long currentPage, long total) { IPage page = new Page<>(); if (total == 0) { page.setTotal(dao.huoQuMuBanTotal(StringUtil.isContainChinese(code), TokenUtil.getTokenUserId(), deptCode, muBanLeiXing)); } page.setRecords(dao.huoQuMuBan(StringUtil.isContainChinese(code), TokenUtil.getTokenUserId(), deptCode, muBanLeiXing, currentPage)); return ResultVoUtil.success(page); } /** * 获取 我的医嘱模板的最大医嘱码 * * @return 最大排序码 */ public ResultVo getDoctorSOrderTemplateMaxSortNo() { Integer sortCode = dao.getMyTemplateMaxSortNo(TokenUtil.getTokenUserId()); return ResultVoUtil.success(sortCode == null ? 0 : sortCode); } private String getActOrderNo() { Random random = new Random(); String a = String.valueOf(random.nextInt(5) + 1); String b = String.valueOf(random.nextInt(99999)); return a + b; } /** * 获取模板数据 * * @param code 模板的编码 * @return 返回数据 */ public ResultVo> huoQuMuBanShuJu(String code) { List muBanShuJu = dao.huoQuMuBanShuJu(code); Map map = new HashMap<>(muBanShuJu.size()); List tree = new ArrayList<>(); for (YzActOrder item : muBanShuJu) { item.setId(getActOrderNo()); if (item.getParentNo() == null) { tree.add(item); } map.put(item.getActOrderNo(), item); } for (YzActOrder item : muBanShuJu) { YzActOrder yzActOrder = map.get(item.getParentNo()); if (yzActOrder != null) { item.setParentNo(new BigDecimal(yzActOrder.getId())); item.setIsChildren(true); if (yzActOrder.getChildren() == null) { yzActOrder.setChildren(new ArrayList<>()); } yzActOrder.getChildren().add(item); // 没有副医嘱的就返回到最上层 } else if (!tree.contains(item)) { item.setParentNo(null); tree.add(item); } } return ResultVoUtil.success(tree); } /** * 删除医嘱模板 * * @param patternCode 模板的编码 * @return 提示 */ public ResultVo deleteADoctorSOrderTemplate(String patternCode) { if (StringUtil.isBlank(patternCode)) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "模板编号为空。"); } YzOrderPattern yzOrderPattern = dao.huoQuMuBanXinXi(patternCode); EntityStringTrim.beanAttributeValueTrim(yzOrderPattern); if (yzOrderPattern == null) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有查询到对应的模板信息。"); } String userId = TokenUtil.getTokenUserId(); List role = publicServer.getRoleCode().getData(); if (publicServer.needRule(role, RoleCode.PHYSICIAN_S_ORDER_TEMPLATEEDIT)) { return startDeletingTemplates(patternCode); } if (userId.equals(yzOrderPattern.getInputId())) { return startDeletingTemplates(patternCode); } // 主任可以删除本科室的任意模板 if (publicServer.needRule(role, RoleCode.DIRECTOR) && dao.userDeptCode(userId).equals(yzOrderPattern.getDeptCode())) { return startDeletingTemplates(patternCode); } return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您没有权限删除这个模板。"); } /** * 删除父模板以及下面的子模板 数据 * * @param patternCode 模板编码 */ private ResultVo startDeletingTemplates(String patternCode) { dao.shanChuMuBan(patternCode); log.info("删除医嘱模板==> 操作人:{},模板编码:{}", TokenUtil.getTokenUserId(), patternCode); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "删除成功。"); } /** * 收藏医嘱模板或者取消收藏 * 如果以及收藏了就删除,没有就收藏 * * @param patternCode 模板号 * @return 提示 */ public ResultVo collectDoctorSOrderTemplate(String patternCode) { String userId = TokenUtil.getTokenUserId(); String saveTheDoctorSOrderNumber = dao.whetherToSaveTheDoctorSOrderTemplate(patternCode, userId); if (StringUtil.notBlank(saveTheDoctorSOrderNumber)) { dao.shanChuMuBan(saveTheDoctorSOrderNumber); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "已取消删除。"); } else { YzOrderPattern yzOrderPattern = dao.huoQuMuBanXinXi(patternCode); EntityStringTrim.beanAttributeValueTrim(yzOrderPattern); dao.chaRuShouCang(publicServer.getPatternCode(), yzOrderPattern.getPatternName() + "(收藏)", yzOrderPattern.getPyCode(), yzOrderPattern.getDCode(), dao.userDeptCode(userId), userId, yzOrderPattern.getPatternCode()); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "收藏成功。"); } } /** * 删除或修改模板 * * @param patternCode 模板点吗 * @param patternName 模板名称 * @param sortNo 排序号 * @param flag 标志 1-修改 2- 删除 3-收藏和取消收藏 * @return 返回给前端提示 */ public ResultVo muBanCaoZuo(String patternCode, String patternName, String deptCode, Integer sortNo, Integer flag) { if (StringUtil.isBlank(patternCode)) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "模板编码为空。"); } YzOrderPattern yzOrderPattern = dao.huoQuMuBanXinXi(patternCode); if (yzOrderPattern == null) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有查询到对应的模板信息。"); } EntityStringTrim.beanAttributeValueTrim(yzOrderPattern); String inputId = TokenUtil.getTokenUserId(); List role = publicServer.getRoleCode().getData(); // 管理员 和 医务部的无视 规则 if (!role.contains(1) && !role.contains(38) && flag != 3) { // 只有模板在不等于 自己的时候触发 if (!inputId.equals(yzOrderPattern.getInputId())) { if ("2".equals(yzOrderPattern.getInputType()) && !role.contains(11)) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该模板为科室模板您没有权限修改或删除,请联系科主任进行修改。"); } else if ("1".equals(yzOrderPattern.getInputType())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该模板为全院模板,无法删除或修改。"); } } } if (flag == 1) { if (StringUtil.isBlank(patternName)) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "模板名称不能为空。"); } if (patternName.trim().equals(yzOrderPattern.getPatternName().trim()) && sortNo.equals(yzOrderPattern.getSortNo())) { return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "数据没有变化,请勿点击。"); } dao.genXingMuBan(patternName.trim(), PingYinUtils.pyShouZiMuDaXie(patternName), PingYinUtils.getWBCode(patternName), yzOrderPattern.getPatternCode(), sortNo); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "修改成功。"); } else if (flag == 2) { // 删除父模板以及下面的子模板 数据 dao.shanChuMuBan(yzOrderPattern.getPatternCode()); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "删除成功。"); } else if (flag == 3) { // 收藏模板 String collectCode = dao.chongFuShouCang(inputId, patternCode); if (collectCode == null) { dao.chaRuShouCang(publicServer.getPatternCode(), yzOrderPattern.getPatternName() + "(收藏)", yzOrderPattern.getPyCode(), yzOrderPattern.getDCode(), deptCode, inputId, yzOrderPattern.getPatternCode()); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "收藏成功。"); } else { dao.shanChuMuBan(yzOrderPattern.getPatternCode()); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "已取消收藏。"); } } return ResultVoUtil.success(); } /** * 获取医嘱下面产生的费用 * * @param patNo 住院号 * @param times 住院次数 * @return 返回 */ public ResultVo> expensesForGettingADoctorSOrder(String patNo, Integer times) { List feeDate = dao.expensesForGettingADoctorSOrder(patNo, times); // 这些编码的医嘱都是有问题的 List problem = Arrays.asList("5", "6", "7", "9"); Map problemDoctorSOrder = new HashMap<>(); Map totalCost = new HashMap<>(); Map> map = new HashMap<>(feeDate.size()); for (DoctorSOrderFee fee : feeDate) { // 如果这个没有就代表没有产生费用 if (fee.getOrderNoStr() == null) { continue; } String chargeStatusName = ChargeStatus.getValue(fee.getChargeStatus()); String amount = fee.getChargeAmount().abs().stripTrailingZeros().toPlainString(); String money = fee.getChargeFee().stripTrailingZeros().toPlainString(); // 计算费用总和 if (totalCost.containsKey(fee.getOrderNoStr())) { FeeSum sum = totalCost.get(fee.getOrderNoStr()); sum.setSum(DecimalUtil.add(money, sum.getSum())); sum.setAmount(DecimalUtil.add(amount, sum.getAmount())); totalCost.replace(fee.getOrderNoStr(), sum); } else { FeeSum sum = new FeeSum(); sum.setAmount(amount); sum.setSum(money); totalCost.put(fee.getOrderNoStr(), sum); } if (problem.contains(fee.getChargeStatus())) { problemDoctorSOrder.put(fee.getOrderNoStr(), chargeStatusName); } fee.setChargeStatusName(chargeStatusName); if (map.containsKey(fee.getOrderNoStr())) { map.get(fee.getOrderNoStr()).add(fee); } else { List list = new ArrayList<>(); list.add(fee); map.put(fee.getOrderNoStr(), list); } } Map feeData = new HashMap<>(3); feeData.put("data", map); feeData.put("problem", problemDoctorSOrder); feeData.put("totalCost", totalCost); return ResultVoUtil.success(feeData); } /** * 退药医嘱 * * @param param 医嘱数组 * @return 返回提示 */ @Deprecated public ResultVo drugWithdrawal(List param) { if (ListUtil.isBlank(param)) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有可以退的药品。"); } List> list = ListUtils.partition(param, 40); List yzActOrders = new ArrayList<>(); for (List strings : list) { yzActOrders.addAll(dao.getOriginalOrderData(strings)); } List> returnedDoctorSOrder = ListUtils.partition(yzActOrders, 20); String userCode = TokenUtil.getTokenUserId(); Map fatherAndSonDoctorSAdvice = new HashMap<>(); for (YzActOrder item : yzActOrders) { BigDecimal orderNo = BigDecimal.valueOf(publicServer.getActOrderNo()); BigDecimal oldOrderNo = item.getActOrderNo(); fatherAndSonDoctorSAdvice.put(oldOrderNo.stripTrailingZeros().toPlainString(), orderNo.stripTrailingZeros().toPlainString()); if (item.getParentNo() != null && fatherAndSonDoctorSAdvice.containsKey(item.getParentNo().stripTrailingZeros().toPlainString())) { item.setParentNo(new BigDecimal(fatherAndSonDoctorSAdvice.get(item.getParentNo().stripTrailingZeros().toPlainString()))); } item.setActOrderNo(orderNo); } for (List orders : returnedDoctorSOrder) { dao.insertAReturnOrder(userCode, orders); } return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "退药成功。"); } /** * 设置患者三级医生 * * @param param 参数 * @return 返回值 */ public ResultVo saveTheThirdLevelDoctor(Overview param) { log.info("设置三级医生:==> 操作人{},数据:{}", TokenUtil.getTokenUserId(), JSON.toJSONString(param)); dao.updateTheThirdLevelDoctor(param); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION); } /** * 设置父子医嘱 * * @param param 主医嘱 和 多个子医嘱 * @return 返回数据 */ public ResultVo associateOrders(XinZhenYiZhu param) { log.info("数据:{}", JSON.toJSONString(param)); XinZhenYzActOrder order = dao.getActOrderNoOne(param.getActOrderNo()); if (order.getParentNo() != null) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "操作失败,父医嘱不能为子医嘱。"); } dao.associateOrders(param.getAssociatedGroup(), param.getActOrderNo()); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "关联成功。"); } /** * 批量检验医嘱是否正确 * * @param list 医嘱数据 * @param huanZheXinXi 患者信息 * @param rationalUse 是否要用合理用药 * @return */ public Map batchVerification(List list, XinZhenYiZhu huanZheXinXi, boolean rationalUse) { Map returnMap = new HashMap<>(); // 药品 code Set yaoPingCode = new HashSet<>(); // 项目的 code Set xiangMuCode = new HashSet<>(); huanZheXinXi.setList(list); // 合理用药校验 Map> rationalUseOfMedicine = rationalUse ? rationalUseServer.jiaoYan(huanZheXinXi) : new HashMap<>(list.size()); for (XinZhenYzActOrder item : list) { if (ITEM.equals(item.getSerial())) { xiangMuCode.add(item.getOrderCode()); } else { yaoPingCode.add(item.getOrderCode().trim() + item.getSerial().trim()); } } String userCode = TokenUtil.getTokenUserId(); // 获取医生开药品的权限 Integer doctorLevel = dao.huoQuYiShenDengJi(userCode); Map drug = getDrugInformation(yaoPingCode, huanZheXinXi.getZkWard()); Map> project = getProjectInformation(xiangMuCode); for (XinZhenYzActOrder item : list) { String key = item.getId(); Map errorMessageMap = checkData(item, drug, project, huanZheXinXi, doctorLevel); if (rationalUseOfMedicine.containsKey(key)) { List temp = (List) errorMessageMap.get("error"); if (temp == null) { errorMessageMap.put("error", rationalUseOfMedicine.get(key)); } else { temp.addAll(rationalUseOfMedicine.get(key)); } } if (!errorMessageMap.isEmpty()) { if (errorMessageMap.get("error") != null) { errorMessageMap.put("data", item); returnMap.put(item.getId(), errorMessageMap); } } } return returnMap; } /** * 确认出院带药医嘱 * * @param patNo * @param times * @return */ public ResultVo> confirmTheDoctorSOrderWithMedicine(String patNo, Integer times) { QueryWrapper qw = new QueryWrapper<>(); qw.eq("a.inpatient_no", patNo) .eq("a.admiss_times", times) .eq("a.status_flag", "1") .eq("a.enter_oper", TokenUtil.getTokenUserId()) .eq("a.self_buy", "4"); XinZhenYiZhu patInfo = dao.huoQuHuanZheXinXi(patNo, times); patInfo.setList(dao.huoQuYiZhuShuJu(qw)); if (dao.obtainTheNumberOfDischargedDrugs(patNo, times) > 4) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "出院带药医嘱不得超过 4 种,且不得超过 15 天。"); } String userCode = TokenUtil.getTokenUserId(); // 出院带药需要生成药单 key 是不同的药房。不同的药房就要 Map> takeTheMedicineList = new HashMap<>(Capacity.TWO); for (XinZhenYzActOrder item : patInfo.getList()) { XinZhenYzActOrder feiYongXinXi = dao.getDrugOne(item.getOrderCode() + item.getSerial(), item.getGroupNo()); int day = 1; // 如果是临时医嘱 开了就结束了. if ("ONCE".equals(item.getFrequCode())) { item.setEndTime(item.getStartTime()); } if (item.getStartTime() != null && item.getEndTime() != null) { long cha = item.getEndTime().getTime() - item.getStartTime().getTime(); long nd = 1000 * 24 * 60 * 60; day = (int) (cha / nd); } // 计算出院带药的领量 Map numberOfTimesADay = dao.numberOfTimesADay(item.getFrequCode()); int tempTimes = 1; for (Map.Entry entry : numberOfTimesADay.entrySet()) { if (entry.getValue() != null) { tempTimes += entry.getValue(); } } // 最小天数一天 BigDecimal total = new BigDecimal((day <= 0 ? 1 : day) * tempTimes); if (StringUtil.notBlank(feiYongXinXi.getDrugWeightUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugWeightUnit().trim())) { item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight(), 2), total)); item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugWeight()), total)); } else if (StringUtil.notBlank(feiYongXinXi.getDrugVolUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getDrugVolUnit())) { item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume(), 2), total)); item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getDrugVolume()), total)); } else if (StringUtil.notBlank(feiYongXinXi.getPackUnit()) && item.getDoseUnit().trim().equals(feiYongXinXi.getPackUnit())) { item.setDrugOcc(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize(), 2), total)); item.setDrugQuan(DecimalUtil.multiply(DecimalUtil.divide(item.getDose(), feiYongXinXi.getPackSize()), total)); } // 在这里更新出院带药领量 dao.updateThePickup(item); // 费用标志为 4 的就是出院带药 if ("4".equals(item.getSelfBuy())) { if (takeTheMedicineList.containsKey(item.getGroupNo())) { takeTheMedicineList.get(item.getGroupNo()).add(item); } else { List temp = new ArrayList<>(); temp.add(item); takeTheMedicineList.put(item.getGroupNo(), temp); } } } Map check = batchVerification(patInfo.getList(), patInfo, true); if (check.isEmpty()) { for (XinZhenYzActOrder order : patInfo.getList()) { // 确认医嘱 dao.confirmOrders(order.getActOrderNo(), userCode, new Date()); } // 生成药单 dischargeMedicineList(takeTheMedicineList, patInfo); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION); } else { return ResultVoUtil.fail(ExceptionEnum.ERROR_MESSAGE, "请修改有错误的医嘱。", check); } } }