package hnthyyxxk.cssybuploadfees.service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import hnthyyxxk.cssybuploadfees.dao.Dao; import hnthyyxxk.cssybuploadfees.pojo.Fee; import hnthyyxxk.cssybuploadfees.pojo.DJRet; import hnthyyxxk.cssybuploadfees.pojo.SimpleResponse; import hnthyyxxk.cssybuploadfees.pojo.UploadFeeParam; import hnthyyxxk.cssybuploadfees.utils.DTool; import hnthyyxxk.cssybuploadfees.utils.ExceptionEnum; import hnthyyxxk.cssybuploadfees.utils.MsgProducer; import hnthyyxxk.cssybuploadfees.utils.SnowFlakeId; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; import static hnthyyxxk.cssybuploadfees.utils.DTool.betweenAutoUpload; /** * @author dj */ @Slf4j @Service public class UploadFeeService { private final Dao dao; private final MsgProducer producer; @Autowired public UploadFeeService(Dao dao, MsgProducer producer) { this.dao = dao; this.producer = producer; } public DJRet multipleUpload(List list) { if (betweenAutoUpload()) { return DJRet.fail(ExceptionEnum.LOGICAL_ERROR, "01:55:00 至 08:00:00 为自动上传时间,请勿在此时间段内做上传操作!"); } JSONObject obj = new JSONObject(); DJRet djRet = DJRet.success(); for (int i = 0; i < list.size(); i ++) { obj.put("name", "updatePatientIndex"); obj.put("val", i + 1); producer.sendTopicQueue(list.get(0).getSid(), obj.toJSONString()); UploadFeeParam item = list.get(i); djRet = uploadFees(item); if (djRet.getCode() != ExceptionEnum.SUCCESS.getCode()) { log.warn("[ 操作员:{} ] - 上传出错>>> {}", item.getStaffId(), obj); sendUploadFeeResponse(item.getInpatientNo(), item.getName(), -1, djRet.getMessage(), item.getSid()); } } return djRet; } public DJRet uploadFees(UploadFeeParam param) { UploadFeeParam temp = dao.getPatientInfo(param.getInpatientNo()); param.merge(temp); log.info("上传费用:{}", param); return startUpload(param); } private DJRet startUpload(UploadFeeParam param) { if (null == param.getSid()) { return DJRet.fail(ExceptionEnum.LOGICAL_ERROR, "未检测到连接id,请刷新页面。"); } if (!"autoUpload".equals(param.getSid()) && DTool.betweenAutoUpload()) { return DJRet.fail(ExceptionEnum.LOGICAL_ERROR, "01:55:00 至 08:00:00 为自动上传时间,请勿在此时间段内做上传操作!"); } param.setFeeSize(dao.queryFeeSize(param.getInpatientNo(), param.getAdmissTimes())); if (param.getFeeSize() == 0) { return DJRet.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有需要上传的费用。"); } SimpleResponse response = makeUploadStmt(param, 1, 0); int code = response.getCode(); if (code == -9) { return DJRet.fail(ExceptionEnum.LOGICAL_ERROR, response.getMessage()); } response = makeUploadStmt(param, 2, code); if (response.getCode() == -9) { return DJRet.fail(ExceptionEnum.LOGICAL_ERROR, response.getMessage()); } return preCalculateCost(param); } private SimpleResponse makeUploadStmt(UploadFeeParam param, int flag, int index) { Queue fees = flag == 1 ? dao.getCssybProjectFee(param.getInpatientNo(), param.getAdmissTimes()) : dao.getCssybMedicineFee(param.getInpatientNo(), param.getAdmissTimes()); SimpleResponse response = new SimpleResponse(); if (null == fees || fees.isEmpty()) { response.setCode(0); return response; } List refundDetailSn = new ArrayList<>(); JSONObject socketMsg = new JSONObject(); while (!fees.isEmpty()) { Fee fee = fees.poll(); if (null == fee.getYbCode() || "".equals(fee.getYbCode().trim())) { String message = "项目/药品【" + fee.getName() + "】未匹配,请联系物价科进行匹配,内线电话:2104"; sendUploadFeeResponse(param.getInpatientNo(), param.getName(), fee.getDetailSn(), message, param.getSid()); } String amount = fee.getAmount(); if (null == amount || "".equals(amount.trim())) { amount = fee.getChargeAmount(); } if (null == amount || "".equals(amount.trim())) { log.info("项目/药品数量不正确:{}", fee); continue; } if (amount.startsWith("-") && !refundDetailSn.contains(fee.getDetailSn())) { refundDetailSn.add(fee.getDetailSn()); fees.offer(fee); log.info("退费项目,安排到末尾 >>> {}", fee); continue; } fee.setPrice(DTool.mathDivide(fee.getChargeFee(), amount)); log.info("[ 操作员:{} ] - [ 患者{} ] - 费用上传>>> {}", param.getStaffId(), param.getMainInfo(), JSON.toJSONString(fee)); String stmt = getUploadFuncId(param.getYbType().trim()) + "^43010150145^" + param.getStaffId() + "^^" + SnowFlakeId.getInstance().nextId() + "^0000^" + param.getYbJlh() + "|" + fee.getYbClass() + "|" + fee.getYbBillCode() + "|" + fee.getDetailSn() + "|" + formatChargeDate(fee.getChargeDate()) + "|" + fee.getChargeCode() + "|" + fee.getYbCode() + "|" + fee.getName() + "|" + fee.getPrice() + "|" + amount + "|||||||||||||" + fee.getStatusFlag() + "|^"; response = executeSybTrade(param.getStaffId(), stmt); log.info("[ 操作员:{} ] - [ 患者{} ] - 费用上传回执>>> {}", param.getStaffId(), param.getMainInfo(), response); if ((response.getCode() == 0) || (response.getMessage().contains("主键重复"))) { if (response.getCode() == 0) { String retPrice = response.getMessage().split("\\|")[1].trim(); int offset = DTool.mathCompare(retPrice.trim(), fee.getChargeFee().trim()); if (offset != 0) { log.warn("[ 操作员:{} ] - [ 患者{} ] - 本条上传HIS费用和医保接收到的不一致。医保返回为 {}," + "本条费用HIS详细为 {} ", param.getStaffId(), param.getMainInfo(), response, fee); } } dao.updateTransFlagYbBySingle(param.getInpatientNo(), param.getAdmissTimes(), fee.getDetailSn()); } else { if (response.getMessage().contains("没有找到此人的登记信息")) { response.setCode(-9); response.setMessage(response.getMessage()); return response; } if (response.getMessage().contains("费用金额大于目前系统中有效的金额")) { response.setMessage(response.getMessage() + "(意思就是退费金额比收费金额大,退多了。)"); } String message = "项目/药品 - " + fee.getName() + ":" + response.getMessage(); sendUploadFeeResponse(param.getInpatientNo(), param.getName(), fee.getDetailSn(), message, param.getSid()); } if (response.getCode() == 9) { return response; } index ++; socketMsg.put("name", "updateProgress"); socketMsg.put("percentage", makePercentage(index, param.getFeeSize())); producer.sendTopicQueue(param.getSid(), socketMsg.toJSONString()); } if (flag == 1) { response.setCode(index); } else { log.info("[ 操作员:{} ] - 上传结束>>> {}", param.getStaffId(), param.getMainInfo()); } return response; } public DJRet preCalculateCost(UploadFeeParam param) { log.info("[ 操作员:{} ] - 预结算>>> {}", param.getStaffId(), param.getMainInfo()); final String serialNo = SnowFlakeId.getInstance().nextId(); final String staff = dao.getStaffNameByCode(param.getStaffId()); String dismissDate = dao.getDismissDate(param.getInpatientNo(), param.getAdmissTimes()); if (null == dismissDate) { dismissDate = formatDateWithoutDash(); } else { dismissDate = dismissDate.replaceAll("-", ""); } final String stmt = String.format("2420^43010150145^%s^^%s^0000^" + "%s|%s|%s|%s|%s||%s|||||0|0||%s|^", param.getStaffId(), serialNo, param.getYbJlh(), serialNo, param.getYbType(), formatDateWithoutDash(), dismissDate, param.getIcdCode(), staff); final SimpleResponse response = executeSybTrade(param.getStaffId(), stmt); log.info("预结算结果:{}", response); if (response.getCode() == 0) { Map feeMap = makeFeeMap(response.getMessage()); final String hisCharge = getHisChargeFee(param.getInpatientNo(), param.getAdmissTimes()); if (DTool.mathCompare(feeMap.get("fundPay"), hisCharge) == 1) { feeMap.replace("fundPay", hisCharge); } dao.preCalculateCost(feeMap.get("fundPay"), feeMap.get("fullSelfPay"), feeMap.get("partSelfPay"), param.getInpatientNo(), param.getAdmissTimes()); if (DTool.feeDiffsOverOneRmb(hisCharge, feeMap.get("totalCost"))) { String message = "患者:" + param.getName() + ",住院号:" + param.getInpatientNo() + " HIS总费用:" + hisCharge + "与医保上传总费用:" + feeMap.get("totalCost") + "不一致!"; return DJRet.fail(ExceptionEnum.NEED_PROOFREAD, message, feeMap); } else { return DJRet.success(feeMap); } } else { return DJRet.fail(ExceptionEnum.LOGICAL_ERROR, response.getMessage()); } } private String getUploadFuncId(String ybType) { final boolean isGs = "42".equals(ybType) || "44".equals(ybType); return isGs ? "2330" : "2310"; } private int makePercentage(int index, int size) { float per = (float)index / (float)size; return (int) (per * 100); } private String formatChargeDate(String target) { return target.replaceAll("-", "") .replaceAll("/", "") .replaceAll(":", "") .replaceAll(" ", ""); } private String formatDateWithoutDash() { DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); return df.format(new Date()); } private String getHisChargeFee(String inpatientNo, Integer admissTimes) { int hasInfant = dao.hasInfant(inpatientNo, admissTimes); return hasInfant == 0 ? dao.getTotalCharge(inpatientNo, admissTimes) : dao.getMomFee(inpatientNo, admissTimes); } private Map makeFeeMap(String feeMsg) { String[] arr = feeMsg.split("\\|"); Map map = new HashMap<>(); map.put("totalCost", arr[10]); map.put("fundPay", DTool.mathMinus(arr[10], arr[14])); map.put("cashPay", arr[14]); try { map.put("fullSelfPay", arr[46]); map.put("partSelfPay", arr[47]); } catch (Exception e) { map.put("fullSelfPay", ""); map.put("partSelfPay", ""); } return map; } private SimpleResponse executeSybTrade(String codeRs, String statement) { CssybCore core = CssybCore.getInstance(); core.setStaffId(codeRs); core.setStmt(statement); return core.call(); } private void sendUploadFeeResponse(String zyh, String patName, Integer detailSn, String message, String sid) { JSONObject socketMsg = new JSONObject(); socketMsg.put("name", "uploadFeeResponse"); socketMsg.put("inpatientNo", zyh); socketMsg.put("patientName", patName); socketMsg.put("detailSn", detailSn); socketMsg.put("msg", message); producer.sendTopicQueue(sid, socketMsg.toJSONString()); } }