package thyyxxk.sizyfeeoprnsystm.service; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.client.RestTemplate; import thyyxxk.sizyfeeoprnsystm.config.SocketConfig; import thyyxxk.sizyfeeoprnsystm.dao.SiLogDao; import thyyxxk.sizyfeeoprnsystm.dao.SiZyDao; import thyyxxk.sizyfeeoprnsystm.dicts.MdtrtCertType; import thyyxxk.sizyfeeoprnsystm.dicts.PsnSetlWay; import thyyxxk.sizyfeeoprnsystm.dicts.SiFunction; import thyyxxk.sizyfeeoprnsystm.dicts.YesOrNo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import thyyxxk.sizyfeeoprnsystm.pojo.*; import thyyxxk.sizyfeeoprnsystm.pojo.socketmsg.Message; import thyyxxk.sizyfeeoprnsystm.pojo.socketmsg.SocketMsg; import thyyxxk.sizyfeeoprnsystm.pojo.socketmsg.SocketTask; import thyyxxk.sizyfeeoprnsystm.utils.*; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.Date; /** * @author dj */ @Slf4j @Service public class SiZyFeeService { private static final String RESULT_CODE = "infcode"; private static final String ERROR_MESSAGE = "err_msg"; private static final String OUTPUT = "output"; private final SiZyDao zyDao; private final SiLogDao logDao; private final ExecService exec; private final RedisLikeService redis; private final RestTemplate template; private final SocketConfig cfg; private static final ConcurrentHashMap uploadingMap; private static final ConcurrentHashMap staffMap; static { uploadingMap = new ConcurrentHashMap<>(); staffMap = new ConcurrentHashMap<>(); } @Autowired public SiZyFeeService(SiZyDao zyDao, SiLogDao logDao, ExecService exec, RedisLikeService redis, RestTemplate template, SocketConfig cfg) { this.zyDao = zyDao; this.logDao = logDao; this.exec = exec; this.redis = redis; this.template = template; this.cfg = cfg; } private void revokeUploadFees(ZyPatientInfo p) { if (null == p.getDetailSns() || p.getDetailSns().isEmpty()) { return; } SiPatInfo siPatInfo = zyDao.selectSiPatInfoForZy(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) { return; } JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_HOSPITALIZATION_FEE_DETAILS, siPatInfo.getInsuplcAdmdvs(), p.getStaffId()); JSONArray data = new JSONArray(); p.getDetailSns().forEach(detailSn -> { JSONObject item = new JSONObject(); item.put("feedetl_sn", detailSn); item.put("mdtrt_id", siPatInfo.getMdtrtId()); item.put("psn_no", siPatInfo.getPsnNo()); data.add(item); }); input.getJSONObject("input").put("data", data); JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_HOSPITALIZATION_FEE_DETAILS); log.info("【操作员:{}】撤销已上传的费用:\n参数:{},\n结果:{}", p.getStaffId(), input, result); if (null == result || null == result.getInteger(RESULT_CODE)) { ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR); return; } if (result.getIntValue(RESULT_CODE) == 0) { if (null == p.getDetailSns() || p.getDetailSns().isEmpty()) { zyDao.revokeAllUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); zyDao.deleteSiChrmTemp(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); } else { zyDao.revokePartUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), p.getDetailSns()); zyDao.deletePartSiChrmTemp(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), p.getDetailSns()); } ResultVoUtil.success("撤销费用上传成功。"); } } public ResultVo uploadMultiplePatientFees(List overviews) { String sid = overviews.get(0).getStaffId(); SocketTask socketTask = new SocketTask(); socketTask.setUserCode(sid); socketTask.setTextInside(true); socketTask.setId("feeupload"+sid); for (int i = 0; i < overviews.size(); i++) { Overview overview = overviews.get(i); if (!staffMap.containsKey(overview.getStaffId())) { staffMap.put(overview.getStaffId(), zyDao.selectStaff(overview.getStaffId())); } sendUpdatePatientIndexMsg(socketTask,i + 1, overviews.size()); if (uploadingMap.containsKey(overview.getInpatientNo())) { String message = "该患者正在其他机器上传,操作人是" + uploadingMap.get(overview.getInpatientNo()).getStaff(); sendDuringUpload(overview, message); continue; } uploadingMap.put(overview.getInpatientNo(), staffMap.get(overview.getStaffId())); ResultVo resVo; try { resVo = uploadFeeDetail(overview, socketTask); } catch (Exception e) { resVo = ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, e.getMessage()); } finally { uploadingMap.remove(overview.getInpatientNo()); } String msg = resVo.getCode() == ExceptionEnum.SUCCESS.getCode() ? resVo.getData() : resVo.getMessage(); sendDuringUpload(overview, msg); if (overviews.size() == 1) { return resVo; } } return ResultVoUtil.success("上传完成,请点击【上传信息】查看详情。"); } public ResultVo uploadFeeDetail(Overview o, SocketTask socketTask) { if (null == o.getLedgerSn()) { Integer ledger = zyDao.selectMaxLedgerSn(o.getInpatientNo(), o.getAdmissTimes()); if (null == ledger) { ledger = 1; } o.setLedgerSn(ledger); } if (null == o.getMidSetl()) { o.setMidSetl(false); } SiPatInfo siPatInfo = zyDao.selectSiPatInfoForZy(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn()); if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的医保在院信息!"); } beforeUpload(o); zyDao.hisRecount(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn()); zyDao.fillReferPhysician(o.getInpatientNo(), o.getAdmissTimes()); ZyPatientInfo zyPtnt = zyDao.selectPatientInfo(o.getInpatientNo()); zyPtnt.setSid(o.getStaffId()); zyPtnt.setStaffId(o.getStaffId()); zyPtnt.setLedgerSn(o.getLedgerSn()); zyPtnt.setMdtrtId(siPatInfo.getMdtrtId()); zyPtnt.setPsnNo(siPatInfo.getPsnNo()); zyPtnt.setMedType(siPatInfo.getMedType()); zyPtnt.setAdmdvs(siPatInfo.getInsuplcAdmdvs()); if (o.getMidSetl()) { List notAllowedSns = zyDao.selectNotAllowedSnForMidSetl(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), o.getEndtime()); if (!notAllowedSns.isEmpty()) { List tempSns = new ArrayList<>(); for (int sn : notAllowedSns) { tempSns.add(sn); if (tempSns.size() == 50) { zyPtnt.setDetailSns(tempSns); revokeUploadFees(zyPtnt); tempSns.clear(); } } if (!tempSns.isEmpty()) { zyPtnt.setDetailSns(tempSns); revokeUploadFees(zyPtnt); } } } Map> allFees = getAllFeesNotUploaded(o); Queue allPositiveFees = allFees.get("positive"); Queue allNegativeFees = allFees.get("negative"); if (allPositiveFees.isEmpty() && allNegativeFees.isEmpty()) { return hospitalizationPreSettlement(zyPtnt, o); } int index = 0; int feeSize = allPositiveFees.size() + allNegativeFees.size(); int[] pstvres = prepareUploadFees(allPositiveFees, index, feeSize, zyPtnt, socketTask); index = pstvres[0]; int[] ngtvres = prepareUploadFees(allNegativeFees, index, feeSize, zyPtnt, socketTask); index = ngtvres[0]; if (pstvres[1] == 1 || ngtvres[1] == 1) { allFees = getAllFeesNotUploaded(o); allPositiveFees = allFees.get("positive"); allNegativeFees = allFees.get("negative"); log.info("医保中心数据有遗漏,继续上传遗漏部分。"); index = prepareUploadFees(allPositiveFees, index, feeSize, zyPtnt, socketTask)[0]; prepareUploadFees(allNegativeFees, index, feeSize, zyPtnt, socketTask); } return hospitalizationPreSettlement(zyPtnt, o); } private Map> getAllFeesNotUploaded(Overview o) { Queue allPositiveFees, allNegativeFees; if (o.getMidSetl()) { allPositiveFees = zyDao.selectNotUploadedPositiveFeesForMidSetl(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), o.getBegntime(), o.getEndtime()); allNegativeFees = zyDao.selectNotUploadedNegativeFeesForMidSetl(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), o.getBegntime(), o.getEndtime()); } else { String today = getTodayEndTime(); allPositiveFees = zyDao.selectNotUploadedPositiveFees(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), today); allPositiveFees.removeIf(item -> StringUtil.isBlank(item.getMedListCodg())); allNegativeFees = zyDao.selectNotUploadedNegativeFees(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), today); } Map> result = new HashMap<>(); result.put("positive", allPositiveFees); result.put("negative", allNegativeFees); return result; } private String getTodayEndTime() { SimpleDateFormat smdate = new SimpleDateFormat("yyyy-MM-dd"); String date = smdate.format(new Date()); return date + " 23:59:59.999"; } private int[] prepareUploadFees(Queue feeQueue, int index, int feeSize, ZyPatientInfo p, SocketTask socketTask) { int[] result = new int[] {0,0}; if (feeQueue.isEmpty()) { return result; } JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.UPLOAD_HOSPITALIZATION_FEE_DETAILS, p.getAdmdvs(), p.getStaffId()); List tempList = new ArrayList<>(); while (!feeQueue.isEmpty()) { FeeDtle feeDtle = feeQueue.poll(); assert feeDtle != null; if (StringUtil.isBlank(feeDtle.getBilgDrCodg())) { feeDtle.setBilgDrCodg(redis.getEmployeeSiCode(feeDtle.getOpIdCode())); } if (StringUtil.isBlank(feeDtle.getBilgDrCodg())) { if (StringUtil.notBlank(feeDtle.getDoctorCode())) { String siCode = redis.getEmployeeSiCode(feeDtle.getDoctorCode()); if (StringUtil.isBlank(siCode)) { CodeName doctor = redis.getEmployeeCodeRs(feeDtle.getDoctorCode()); sendDoctorNoSiCodeMessage(p, doctor.getStaff(), feeDtle.getFeedetlSn()); continue; } } else { if (StringUtil.notBlank(feeDtle.getReferPhysician())) { String siCode = redis.getEmployeeSiCode(feeDtle.getReferPhysician()); if (StringUtil.isBlank(siCode)) { CodeName doctor = redis.getEmployeeCodeRs(feeDtle.getReferPhysician()); sendDoctorNoSiCodeMessage(p, doctor.getStaff(), feeDtle.getFeedetlSn()); continue; } } else { if (StringUtil.notBlank(feeDtle.getOpIdCode())) { String siCode = redis.getEmployeeSiCode(feeDtle.getOpIdCode()); if (StringUtil.isBlank(siCode)) { CodeName doctor = redis.getEmployeeCodeRs(feeDtle.getOpIdCode()); sendDoctorNoSiCodeMessage(p, doctor.getStaff(), feeDtle.getFeedetlSn()); continue; } } } } } feeDtle.setOrdersDrCode(feeDtle.getBilgDrCodg()); feeDtle.setOrdersDrName(feeDtle.getBilgDrName()); tempList.add(feeDtle); if (tempList.size() == 50) { int[] upldres = executeUploadFees(input, tempList, p); index += upldres[0]; if (upldres[1] > 0) { result[1] = 1; } tempList.clear(); socketTask.setPercentage(makePercentage(index, feeSize)); sendTaskProgress(socketTask); } } if (!tempList.isEmpty()) { int[] upldres = executeUploadFees(input, tempList, p); index += upldres[0]; if (upldres[1] > 0) { result[1] = 1; } socketTask.setPercentage(makePercentage(index, feeSize)); sendTaskProgress(socketTask); } return result; } private void sendTaskProgress(SocketTask socketTask) { JSONObject js = new JSONObject(); js.put("mode", "SINGLE"); js.put("sid", socketTask.getUserCode()); js.put("msg", SocketMsg.socketVo(Message.backgroundTask, JSONObject.toJSONString(socketTask))); template.postForObject(cfg.getApiUrl(), js, String.class); } private void sendDoctorNoSiCodeMessage(ZyPatientInfo p, String doctor, Integer feedetlSn) { String message = String.format("【流水号:%d】%s医师没有医保赋码,请联系医保科。", feedetlSn, doctor); sendUploadResponse(p, message); } private void sendUpdatePatientIndexMsg(SocketTask socketTask, int index, int total) { socketTask.setName("费用上传(共" + total + "人,正在上传第" + index + "人)"); socketTask.setPercentage(0); JSONObject js = new JSONObject(); js.put("mode", "SINGLE"); js.put("sid", socketTask.getUserCode()); js.put("msg", SocketMsg.socketVo(Message.backgroundTask, JSONObject.toJSONString(socketTask))); template.postForObject(cfg.getApiUrl(), js, String.class); } private void sendUploadResponse(ZyPatientInfo p, String message) { sendUploadResMsg(message, p.getInpatientNo(), p.getName(), p.getAdmissTimes(), p.getLedgerSn(), p.getStaffId()); } private void sendDuringUpload(Overview overview, String message) { sendUploadResMsg(message, overview.getInpatientNo(), overview.getName(), overview.getAdmissTimes(), overview.getLedgerSn(), overview.getStaffId()); } public void sendUploadResMsg(String message, String inpatientNo, String name, Integer admissTimes, Integer ledgerSn, String sid) { JSONObject msg = new JSONObject(); msg.put("name", "uploadFeeResponse"); msg.put("patNo", inpatientNo); msg.put("patName", name); msg.put("times", admissTimes); msg.put("ledgerSn", ledgerSn); msg.put("message", message); msg.put("title", String.format("住院号:【%s】,住院次数:【%d】,账页号:【%d】。", inpatientNo, admissTimes, ledgerSn)); JSONObject js = new JSONObject(); js.put("mode", "SINGLE"); js.put("sid", sid); js.put("msg", SocketMsg.socketVo(Message.MEDINS_FEE_UPLOAD_PROGRESS, msg)); template.postForObject(cfg.getApiUrl(), js, String.class); } private int[] executeUploadFees(JSONObject input, List fees, ZyPatientInfo p) { String ref = JSONArray.toJSONString(fees); input.getJSONObject("input").put("feedetail", JSONArray.parse(ref)); JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_HOSPITALIZATION_FEE_DETAILS); int infcode = result.getIntValue(RESULT_CODE); String logMsg = infcode + "," + result.getString("inf_refmsgid"); log.info("【操作员:{}】,医保费用上传:\n患者:{},\n结果:{},\n参数:{}", p.getStaffId(), p.getPsnInfo(), logMsg, input); if (infcode == 0) { JSONArray array = result.getJSONObject(OUTPUT).getJSONArray("result"); List tempList = new ArrayList<>(); for (int i = 0; i < array.size(); i++) { JSONObject upldretrn = array.getJSONObject(i); SiChargeTemp chrgtemp = JSONObject.parseObject(upldretrn.toJSONString(), SiChargeTemp.class); chrgtemp.setPatNo(p.getInpatientNo()); chrgtemp.setTimes(p.getAdmissTimes()); chrgtemp.setLedgerSn(p.getLedgerSn()); tempList.add(chrgtemp); } zyDao.updateTransFlag(p.getInpatientNo(), p.getAdmissTimes(), tempList); zyDao.insertSiChargeTempFeeBatch(tempList); return new int[]{tempList.size(), fees.size() - tempList.size()}; } else { String message = result.getString(ERROR_MESSAGE); sendUploadResponse(p, message); return new int[]{fees.size(), 0}; } } public ResultVo hospitalizationPreSettlement(ZyPatientInfo p, Overview o) { uploadingMap.remove(o.getInpatientNo()); ZyPreSetlmt zyPreSetlmt; if (o.getMidSetl()) { zyPreSetlmt = zyDao.selectPreSetlmtForMidSetl(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), o.getBegntime(), o.getEndtime()); } else { zyPreSetlmt = zyDao.selectPreSetlmt(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), getTodayEndTime()); } if (null == zyPreSetlmt || StringUtil.isBlank(zyPreSetlmt.getMdtrtId())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的医保在院信息!"); } zyPreSetlmt.setMdtrtCertType(MdtrtCertType.RESIDENT_IDENTITY_CARD.getCode()); zyPreSetlmt.setPsnSetlway(p.getDbg() ? PsnSetlWay.SETTLE_BY_QUOTA.getCode() : PsnSetlWay.SETTLE_BY_ITEMS.getCode()); zyPreSetlmt.setAcctUsedFlag(YesOrNo.NO.getCodeStr()); zyPreSetlmt.setMidSetlFlag(YesOrNo.NO.getCodeStr()); JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.HOSPITALIZATION_PRE_SETTLEMENT, zyPreSetlmt.getInsuplcAdmdvs(), p.getStaffId()); String ref = JSONObject.toJSONString(zyPreSetlmt); input.getJSONObject("input").put("data", JSONObject.parseObject(ref)); JSONObject result = exec.executeTrade(input, SiFunction.HOSPITALIZATION_PRE_SETTLEMENT); log.info("预结算:\n参数:{},\n结果:{}", input, result); if (null == result) { return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR); } Integer infcode = result.getInteger(RESULT_CODE); logDao.insert(new SiLog(input, result, p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), infcode, zyPreSetlmt.getPsnNo())); if (null == infcode) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message")); } if (infcode == 0) { JSONObject setlinfo = result.getJSONObject(OUTPUT).getJSONObject("setlinfo"); String fundPay = setlinfo.getString("fund_pay_sumamt"); zyDao.updateFundPay(fundPay, p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); zyDao.recountDeposit(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); zyDao.updateBalance(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); String balance = zyDao.selectLedgerBalance(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); if (StringUtil.isBlank(balance)) { balance = "0"; } zyDao.updateZyActPatientBalance(p.getInpatientNo(), balance); String message = "患者【" + p.getName() + "】院内总费用与医保中心总费用一致,医保报销金额为:¥ " + fundPay + "。"; return ResultVoUtil.success(message); } return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE)); } private int makePercentage(int index, int size) { float per = (float)index / (float)size; return (int) (per * 100); } private void beforeUpload(Overview o) { Date disdate = zyDao.selectDscgDate(o.getInpatientNo(), o.getAdmissTimes()); if (null != disdate) { int num = zyDao.updateChargedate(o.getInpatientNo(), o.getAdmissTimes(), disdate); log.info("修改费用时间大于出院医嘱时间的费用条目数:{}", num); } List negativeCharges = zyDao.selectNegativeFeesWithOriDetlSn( o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn()); if (null == negativeCharges || negativeCharges.isEmpty()) { log.info("正负相抵完成,抵消费用总条目:0"); return; } List positiveCharges = new ArrayList<>(); List tempSn = new ArrayList<>(); for (FeeCounteract feeCounteract : negativeCharges) { tempSn.add(feeCounteract.getOriDetailSn()); if (tempSn.size() == 30) { positiveCharges.addAll(zyDao.selectPositiveFeesByDetlSn( o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), tempSn)); tempSn.clear(); } } if (!tempSn.isEmpty()) { positiveCharges.addAll(zyDao.selectPositiveFeesByDetlSn( o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), tempSn)); } ConcurrentHashMap positiveChargeMap = new ConcurrentHashMap<>(); positiveCharges.forEach(itm -> { if (!positiveChargeMap.containsKey(itm.getDetailSn())) { positiveChargeMap.put(itm.getDetailSn(), itm); } }); int count = 0; for (FeeCounteract negativeCharge : negativeCharges) { if (positiveChargeMap.containsKey(negativeCharge.getOriDetailSn())) { FeeCounteract positiveCharge = positiveChargeMap.get(negativeCharge.getOriDetailSn()); if (positiveCharge.getUsed()) { continue; } if (negativeCharge.getChargeAmount() + positiveCharge.getChargeAmount() == 0d && negativeCharge.getChargeFee() + positiveCharge.getChargeFee() == 0d) { zyDao.updateYbTransFlagInPair(o.getInpatientNo(), o.getAdmissTimes(), negativeCharge.getDetailSn(), negativeCharge.getOriDetailSn()); count += 2; positiveCharge.setUsed(true); } } } log.info("正负相抵完成,抵消费用总条目:{}", count); } /** * 工伤费用明细上传主方法 * 功能:批量上传工伤患者的费用明细到工伤中心 */ public ResultVo uploadWorkInjuryFees(List overviews) { String sid = overviews.get(0).getStaffId(); SocketTask socketTask = new SocketTask(); socketTask.setUserCode(sid); socketTask.setTextInside(true); socketTask.setId("workInjuryFeeUpload"+sid); for (int i = 0; i < overviews.size(); i++) { Overview overview = overviews.get(i); if (!staffMap.containsKey(overview.getStaffId())) { staffMap.put(overview.getStaffId(), zyDao.selectStaff(overview.getStaffId())); } sendUpdatePatientIndexMsg(socketTask,i + 1, overviews.size()); if (uploadingMap.containsKey(overview.getInpatientNo())) { String message = "该患者正在其他机器上传,操作人是" + uploadingMap.get(overview.getInpatientNo()).getStaff(); sendDuringUpload(overview, message); continue; } uploadingMap.put(overview.getInpatientNo(), staffMap.get(overview.getStaffId())); ResultVo resVo; try { resVo = uploadWorkInjuryFeeDetail(overview, socketTask); } catch (Exception e) { resVo = ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, e.getMessage()); } finally { uploadingMap.remove(overview.getInpatientNo()); } String msg = resVo.getCode() == ExceptionEnum.SUCCESS.getCode() ? resVo.getData() : resVo.getMessage(); sendDuringUpload(overview, msg); if (overviews.size() == 1) { return resVo; } } return ResultVoUtil.success("工伤费用上传完成,请点击【上传信息】查看详情。"); } /** * 处理单个工伤患者的费用上传 */ public ResultVo uploadWorkInjuryFeeDetail(Overview o, SocketTask socketTask) { if (null == o.getLedgerSn()) { Integer ledger = zyDao.selectMaxLedgerSn(o.getInpatientNo(), o.getAdmissTimes()); if (null == ledger) { ledger = 1; } o.setLedgerSn(ledger); } if (null == o.getMidSetl()) { o.setMidSetl(false); } // 查询工伤患者信息(使用相同的表) SiPatInfo siPatInfo = zyDao.selectSiPatInfoForZy(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn()); if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的工伤在院信息!"); } // 工伤费用预处理 beforeWorkInjuryUpload(o); // 重新计算费用 zyDao.hisRecount(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn()); // 填充转诊医师信息 zyDao.fillReferPhysician(o.getInpatientNo(), o.getAdmissTimes()); // 构建工伤患者信息对象 ZyPatientInfo zyPtnt = zyDao.selectPatientInfo(o.getInpatientNo()); zyPtnt.setSid(o.getStaffId()); zyPtnt.setStaffId(o.getStaffId()); zyPtnt.setLedgerSn(o.getLedgerSn()); zyPtnt.setMdtrtId(siPatInfo.getMdtrtId()); zyPtnt.setPsnNo(siPatInfo.getPsnNo()); zyPtnt.setMedType(siPatInfo.getMedType()); zyPtnt.setAdmdvs(siPatInfo.getInsuplcAdmdvs()); // 如果是中间结算,需要撤销超出时间范围的费用 if (o.getMidSetl()) { List notAllowedSns = zyDao.selectNotAllowedSnForMidSetl(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), o.getEndtime()); if (!notAllowedSns.isEmpty()) { List tempSns = new ArrayList<>(); for (int sn : notAllowedSns) { tempSns.add(sn); if (tempSns.size() == 100) { zyPtnt.setDetailSns(tempSns); revokeWorkInjuryUploadFees(zyPtnt); tempSns.clear(); } } if (!tempSns.isEmpty()) { zyPtnt.setDetailSns(tempSns); revokeWorkInjuryUploadFees(zyPtnt); } } } // 获取未上传的工伤费用(使用相同的表) Map> allFees = getAllFeesNotUploaded(o); Queue allPositiveFees = allFees.get("positive"); Queue allNegativeFees = allFees.get("negative"); if (allPositiveFees.isEmpty() && allNegativeFees.isEmpty()) { return workInjuryPreSettlement(zyPtnt, o); } int index = 0; int feeSize = allPositiveFees.size() + allNegativeFees.size(); int[] pstvres = prepareWorkInjuryUploadFees(allPositiveFees, index, feeSize, zyPtnt, socketTask); index = pstvres[0]; int[] ngtvres = prepareWorkInjuryUploadFees(allNegativeFees, index, feeSize, zyPtnt, socketTask); index = ngtvres[0]; if (pstvres[1] == 1 || ngtvres[1] == 1) { allFees = getAllFeesNotUploaded(o); allPositiveFees = allFees.get("positive"); allNegativeFees = allFees.get("negative"); log.info("工伤中心数据有遗漏,继续上传遗漏部分。"); index = prepareWorkInjuryUploadFees(allPositiveFees, index, feeSize, zyPtnt, socketTask)[0]; prepareWorkInjuryUploadFees(allNegativeFees, index, feeSize, zyPtnt, socketTask); } return workInjuryPreSettlement(zyPtnt, o); } /** * 撤销工伤已上传的费用 */ private void revokeWorkInjuryUploadFees(ZyPatientInfo p) { if (null == p.getDetailSns() || p.getDetailSns().isEmpty()) { return; } SiPatInfo siPatInfo = zyDao.selectSiPatInfoForZy(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) { return; } // 工伤撤销只能单个输入,需要遍历撤销每个明细 List successDetailSns = new ArrayList<>(); // 记录成功撤销的明细 List failedDetailSns = new ArrayList<>(); // 记录失败撤销的明细 for (Integer detailSn : p.getDetailSns()) { // 构建工伤撤销请求(处方明细撤销) JSONObject input = new JSONObject(); input.put("action", "transaction"); input.put("transactionName", "2205"); JSONObject businessParams = new JSONObject(); businessParams.put("ipt_otp_no", siPatInfo.getMdtrtId()); // 门诊/住院流水号 // 根据工伤文档要求:不允许传入处方号为空且处方流水号非空 // 需要获取对应的处方号 String rxno = zyDao.selectRxnoByDetailSn(p.getInpatientNo(), p.getAdmissTimes(), detailSn); businessParams.put("rxno", StringUtil.isBlank(rxno) ? "" : rxno); // 处方号 businessParams.put("feedetl_sn", detailSn.toString()); // 处方流水号 input.put("businessParams", businessParams); // 调用工伤撤销接口 JSONObject result = exec.executeWorkInjuryTrade(input); log.info("【操作员:{}】撤销工伤已上传的费用明细{}:\n参数:{},\n结果:{}", p.getStaffId(), detailSn, input, result); // 工伤接口返回结果处理(支持模拟接口和真实接口切换) Integer infcode = extractWorkInjuryResultCode(result); if (null == result || null == infcode) { log.error("工伤撤销接口调用失败,明细:{}", detailSn); failedDetailSns.add(detailSn); continue; // 继续撤销下一个,不中断整个流程 } if (infcode == 0) { log.info("工伤撤销成功,明细:{}", detailSn); successDetailSns.add(detailSn); } else { String errorMsg = extractWorkInjuryErrorMessage(result); log.error("工伤撤销失败,明细:{},错误:{}", detailSn, errorMsg); failedDetailSns.add(detailSn); } } // 根据撤销结果分别更新数据库状态 if (successDetailSns.isEmpty()) { log.warn("工伤撤销全部失败,患者:{},明细数:{}", p.getInpatientNo(), p.getDetailSns().size()); return; // 全部失败,不更新数据库状态 } if (successDetailSns.size() == p.getDetailSns().size()) { // 全部撤销成功 log.info("工伤撤销全部成功,患者:{},明细数:{}", p.getInpatientNo(), successDetailSns.size()); if (null == p.getDetailSns() || p.getDetailSns().isEmpty()) { zyDao.revokeAllUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); zyDao.deleteSiChrmTemp(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); } else { zyDao.revokePartUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), p.getDetailSns()); zyDao.deletePartSiChrmTemp(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), p.getDetailSns()); } } else { // 部分撤销成功,只更新成功撤销的明细 log.info("工伤撤销部分成功,患者:{},成功:{},失败:{}", p.getInpatientNo(), successDetailSns.size(), failedDetailSns.size()); zyDao.revokePartUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), successDetailSns); zyDao.deletePartSiChrmTemp(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), successDetailSns); } log.info("工伤撤销流程完成,患者:{},成功撤销:{},失败撤销:{}", p.getInpatientNo(), successDetailSns.size(), failedDetailSns.size()); } /** * 准备并上传工伤费用 */ private int[] prepareWorkInjuryUploadFees(Queue feeQueue, int index, int feeSize, ZyPatientInfo p, SocketTask socketTask) { int[] result = new int[] {0,0}; if (feeQueue.isEmpty()) { return result; } // 构建工伤费用上传请求头(处方明细上报) JSONObject input = new JSONObject(); input.put("action", "transaction"); input.put("transactionName", "2204"); input.put("businessParams", new JSONArray()); List tempList = new ArrayList<>(); while (!feeQueue.isEmpty()) { FeeDtle feeDtle = feeQueue.poll(); assert feeDtle != null; // 设置医生编码(工伤可能使用不同的编码规则) if (StringUtil.isBlank(feeDtle.getBilgDrCodg())) { feeDtle.setBilgDrCodg(redis.getEmployeeSiCode(feeDtle.getOpIdCode())); } if (StringUtil.isBlank(feeDtle.getBilgDrCodg())) { if (StringUtil.notBlank(feeDtle.getDoctorCode())) { String siCode = redis.getEmployeeSiCode(feeDtle.getDoctorCode()); if (StringUtil.isBlank(siCode)) { CodeName doctor = redis.getEmployeeCodeRs(feeDtle.getDoctorCode()); sendDoctorNoSiCodeMessage(p, doctor.getStaff(), feeDtle.getFeedetlSn()); continue; } } else { if (StringUtil.notBlank(feeDtle.getReferPhysician())) { String siCode = redis.getEmployeeSiCode(feeDtle.getReferPhysician()); if (StringUtil.isBlank(siCode)) { CodeName doctor = redis.getEmployeeCodeRs(feeDtle.getReferPhysician()); sendDoctorNoSiCodeMessage(p, doctor.getStaff(), feeDtle.getFeedetlSn()); continue; } } else { if (StringUtil.notBlank(feeDtle.getOpIdCode())) { String siCode = redis.getEmployeeSiCode(feeDtle.getOpIdCode()); if (StringUtil.isBlank(siCode)) { CodeName doctor = redis.getEmployeeCodeRs(feeDtle.getOpIdCode()); sendDoctorNoSiCodeMessage(p, doctor.getStaff(), feeDtle.getFeedetlSn()); continue; } } } } } feeDtle.setOrdersDrCode(feeDtle.getBilgDrCodg()); feeDtle.setOrdersDrName(feeDtle.getBilgDrName()); tempList.add(feeDtle); if (tempList.size() == 100) { int[] upldres = executeWorkInjuryUploadFees(input, tempList, p); index += upldres[0]; if (upldres[1] > 0) { result[1] = 1; } tempList.clear(); socketTask.setPercentage(makePercentage(index, feeSize)); sendTaskProgress(socketTask); } } if (!tempList.isEmpty()) { int[] upldres = executeWorkInjuryUploadFees(input, tempList, p); index += upldres[0]; if (upldres[1] > 0) { result[1] = 1; } socketTask.setPercentage(makePercentage(index, feeSize)); sendTaskProgress(socketTask); } return result; } /** * 执行工伤费用上传 */ private int[] executeWorkInjuryUploadFees(JSONObject input, List fees, ZyPatientInfo p) { // 构建符合工伤接口文档的businessParams数组 JSONArray businessParams = new JSONArray(); for (FeeDtle feeDtle : fees) { JSONObject feeItem = new JSONObject(); // 根据工伤接口文档构建字段映射 feeItem.put("ipt_otp_no", p.getMdtrtId()); // 门诊/住院流水号 feeItem.put("list_type", feeDtle.getMedListCodgType() != null ? feeDtle.getMedListCodgType().toString() : "2"); // 三大目录类别:1-药品,2-诊疗项目,3-材料 feeItem.put("rxno", feeDtle.getDrordNo()); // 处方号 feeItem.put("feedetl_sn", feeDtle.getFeedetlSn()); // 处方流水号 feeItem.put("fee_ocur_time", formatDateTime(feeDtle.getFeeOcurTime())); // 处方日期 feeItem.put("med_list_codg", feeDtle.getMedListCodg()); // 收费项目中心编码 feeItem.put("pric", feeDtle.getPric()); // 单价 feeItem.put("cnt", feeDtle.getCnt()); // 数量 feeItem.put("umamt", feeDtle.getDetItemFeeSumamt()); // 总金额 feeItem.put("bilg_dr_codg", feeDtle.getBilgDrCodg()); // 医生编码 feeItem.put("bilg_dept_codg", feeDtle.getBilgDeptCodg()); // 科室编码 // 根据工伤文档要求:空默认为否,所以不传这两个字段,让系统使用默认值 // feeItem.put("min_unit", ""); // 是否最小计量单位 // feeItem.put("allSelfFlag", ""); // 全额自费标志 businessParams.add(feeItem); } input.put("businessParams", businessParams); // 调用工伤费用上传接口 JSONObject result = exec.executeWorkInjuryTrade(input); // 工伤接口返回结果处理(支持模拟接口和真实接口切换) Integer infcode = extractWorkInjuryResultCode(result); String logMsg = (infcode != null ? infcode.toString() : "null") + "," + (result != null ? result.getString("inf_refmsgid") : "null"); log.info("【操作员:{}】,工伤费用上传:\n患者:{},\n结果:{}", p.getStaffId(), p.getPsnInfo(), logMsg); if (infcode == 0) { // 工伤接口返回结果提取(支持模拟接口和真实接口切换) JSONArray array = extractWorkInjuryUploadResult(result); List tempList = new ArrayList<>(); for (int i = 0; i < array.size(); i++) { JSONObject upldretrn = array.getJSONObject(i); // 1. 获取费用明细流水号 Integer feedetlSn = upldretrn.getInteger("feedetl_sn"); if (feedetlSn == null) continue; // 2. 数据库补全工伤缺失字段 Map missingFields = zyDao.selectWorkInjuryMissingFields( p.getInpatientNo(), p.getAdmissTimes().intValue(), feedetlSn); if (missingFields != null && !missingFields.isEmpty()) { if (upldretrn.getString("rxno") == null && missingFields.get("rxno") != null) upldretrn.put("rxno", missingFields.get("rxno")); if (upldretrn.getString("fee_ocur_time") == null && missingFields.get("feeOcurTime") != null) upldretrn.put("fee_ocur_time", missingFields.get("feeOcurTime")); if (upldretrn.getString("med_list_codg") == null && missingFields.get("medListCodg") != null) upldretrn.put("med_list_codg", missingFields.get("medListCodg")); } // 3. 字段映射(工伤→医保字段名) SiChargeTemp chrgtemp = new SiChargeTemp(); chrgtemp.setPatNo(p.getInpatientNo()); chrgtemp.setTimes(p.getAdmissTimes()); chrgtemp.setLedgerSn(p.getLedgerSn()); chrgtemp.setFeedetlSn(feedetlSn); chrgtemp.setDetItemFeeSumamt(upldretrn.getString("umamt")); chrgtemp.setFulamtOwnpayAmt(upldretrn.getString("ownpay_amt")); chrgtemp.setOverlmtAmt(upldretrn.getString("alwpay_amt")); chrgtemp.setPricUplmtAmt(upldretrn.getString("pric_uplmt_amt")); chrgtemp.setChrgitmLv(upldretrn.getString("chrgitm_lv")); chrgtemp.setMemo(upldretrn.getString("memo")); // 其他字段可设为null或默认 tempList.add(chrgtemp); } zyDao.updateTransFlag(p.getInpatientNo(), p.getAdmissTimes(), tempList); zyDao.insertSiChargeTempFeeBatch(tempList); return new int[]{tempList.size(), fees.size() - tempList.size()}; } else { String message = extractWorkInjuryErrorMessage(result); sendUploadResponse(p, message); return new int[]{fees.size(), 0}; } } /** * 工伤预结算 */ public ResultVo workInjuryPreSettlement(ZyPatientInfo p, Overview o) { uploadingMap.remove(o.getInpatientNo()); ZyPreSetlmt zyPreSetlmt; if (o.getMidSetl()) { zyPreSetlmt = zyDao.selectPreSetlmtForMidSetl(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), o.getBegntime(), o.getEndtime()); } else { zyPreSetlmt = zyDao.selectPreSetlmt(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), getTodayEndTime()); } if (null == zyPreSetlmt || StringUtil.isBlank(zyPreSetlmt.getMdtrtId())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的工伤在院信息!"); } // 设置工伤预结算参数 zyPreSetlmt.setMdtrtCertType(MdtrtCertType.RESIDENT_IDENTITY_CARD.getCode()); zyPreSetlmt.setPsnSetlway(p.getDbg() ? PsnSetlWay.SETTLE_BY_QUOTA.getCode() : PsnSetlWay.SETTLE_BY_ITEMS.getCode()); zyPreSetlmt.setAcctUsedFlag(YesOrNo.NO.getCodeStr()); zyPreSetlmt.setMidSetlFlag(YesOrNo.NO.getCodeStr()); // 构建工伤预结算请求(费用预结算) JSONObject input = new JSONObject(); input.put("action", "transaction"); input.put("transactionName", "2206"); // 根据工伤接口文档构建预结算参数 JSONObject businessParams = new JSONObject(); businessParams.put("ipt_otp_no", zyPreSetlmt.getMdtrtId()); // 门诊/住院流水号 businessParams.put("mdtrt_id", ""); // 单据号(预结算传空) businessParams.put("med_type", p.getMedType()); // 医疗类别(从患者信息获取) businessParams.put("setl_time", formatDateTime(new Date())); // 结算日期(当前时间) businessParams.put("dscg_time", formatDateTime(new Date())); // 出院日期(当前时间) businessParams.put("dscg_trt_rslt", "01"); // 出院原因(默认治愈) // 从数据库获取诊断信息 String diagCode = zyDao.selectDiagCode(p.getInpatientNo(), p.getAdmissTimes()); String diagDscr = zyDao.selectDiagDscr(p.getInpatientNo(), p.getAdmissTimes()); businessParams.put("diag_code", StringUtil.isBlank(diagCode) ? "" : diagCode); // 出院诊断疾病主编码 businessParams.put("psn_no", zyPreSetlmt.getPsnNo()); // 个人唯一识别码 // 从数据库获取科室编码和医生编码 String admDeptCodg = zyDao.selectAdmDeptCodg(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); String atddrNo = zyDao.selectAtddrNo(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); businessParams.put("adm_dept_codg", StringUtil.isBlank(admDeptCodg) ? "" : admDeptCodg); // 科室编码 businessParams.put("atddr_no", StringUtil.isBlank(atddrNo) ? "" : atddrNo); // 医生编码 businessParams.put("diag_dscr", StringUtil.isBlank(diagDscr) ? "" : diagDscr); // 出院诊断 businessParams.put("occupationalType", "01"); // 职业病类型(默认普通住院) input.put("businessParams", businessParams); // 调用工伤预结算接口 JSONObject result = exec.executeWorkInjuryTrade(input); log.info("工伤预结算:\n参数:{},\n结果:{}", input, result); if (null == result) { return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR); } // 工伤接口返回结果处理(支持模拟接口和真实接口切换) Integer infcode = extractWorkInjuryResultCode(result); // 工伤接口日志记录(支持模拟接口和真实接口切换) JSONObject logInput = new JSONObject(); // 模拟接口处理(当前使用) if (result != null && result.containsKey("data") && result.getJSONObject("data").containsKey("data")) { JSONObject innerData = result.getJSONObject("data").getJSONObject("data"); if (innerData.containsKey("transformed_parameters")) { JSONObject transformedParams = innerData.getJSONObject("transformed_parameters"); logInput.put("infno", transformedParams.getString("infno")); logInput.put("insuplc_admdvs", ""); logInput.put("msgid", transformedParams.getString("msgid")); logInput.put("opter", transformedParams.getString("opter")); } else { // 如果没有transformed_parameters,使用默认值 logInput.put("infno", "2206"); logInput.put("insuplc_admdvs", ""); logInput.put("msgid", "WORK_INJURY_" + System.currentTimeMillis()); logInput.put("opter", p.getStaffId()); } } // 真实接口处理(注释掉,需要时手动切换) // else if (result != null && result.containsKey("data")) { // JSONObject data = result.getJSONObject("data"); // if (data.containsKey("transformed_parameters")) { // JSONObject transformedParams = data.getJSONObject("transformed_parameters"); // logInput.put("infno", transformedParams.getString("infno")); // logInput.put("insuplc_admdvs", ""); // logInput.put("msgid", transformedParams.getString("msgid")); // logInput.put("opter", transformedParams.getString("opter")); // } else { // // 如果没有transformed_parameters,使用默认值 // logInput.put("infno", "2206"); // logInput.put("insuplc_admdvs", ""); // logInput.put("msgid", "WORK_INJURY_" + System.currentTimeMillis()); // logInput.put("opter", p.getStaffId()); // } // } else { // 如果result为空,使用默认值 logInput.put("infno", "2206"); logInput.put("insuplc_admdvs", ""); logInput.put("msgid", "WORK_INJURY_" + System.currentTimeMillis()); logInput.put("opter", p.getStaffId()); } logDao.insert(new SiLog(logInput, result, p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), infcode, zyPreSetlmt.getPsnNo())); if (null == infcode) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "工伤中心报错:" + (result != null ? result.getString("message") : "未知错误")); } if (infcode == 0) { // 工伤接口返回结果提取(支持模拟接口和真实接口切换) JSONObject setlinfo = extractWorkInjuryPreSettlementResult(result); String fundPay = setlinfo != null ? setlinfo.getString("hifp_pay") : "0"; // 工伤使用 hifp_pay 字段 // 更新工伤报销金额(使用相同的表) zyDao.updateFundPay(fundPay, p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); zyDao.recountDeposit(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); zyDao.updateBalance(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); String balance = zyDao.selectLedgerBalance(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()); if (StringUtil.isBlank(balance)) { balance = "0"; } zyDao.updateZyActPatientBalance(p.getInpatientNo(), balance); String message = "患者【" + p.getName() + "】工伤费用预结算成功,工伤报销金额为:¥ " + fundPay + "。"; return ResultVoUtil.success(message); } return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, extractWorkInjuryErrorMessage(result)); } /** * 工伤接口返回结果代码提取(支持模拟接口和真实接口切换) */ private Integer extractWorkInjuryResultCode(JSONObject result) { if (result == null) { return null; } // 模拟接口返回结构:result.getJSONObject("data").getJSONObject("data").getString("infcode") // 真实接口返回结构:result.getJSONObject("data").getString("infcode") // 模拟接口处理(当前使用) if (result.containsKey("data") && result.getJSONObject("data").containsKey("data")) { JSONObject innerData = result.getJSONObject("data").getJSONObject("data"); return innerData != null ? innerData.getInteger(RESULT_CODE) : null; } // 真实接口处理(注释掉,需要时手动切换) // else if (result.containsKey("data")) { // JSONObject data = result.getJSONObject("data"); // return data != null ? data.getInteger(RESULT_CODE) : null; // } return null; } /** * 工伤费用上传返回结果提取(支持模拟接口和真实接口切换) */ private JSONArray extractWorkInjuryUploadResult(JSONObject result) { if (result == null) { return new JSONArray(); } // 模拟接口返回结构:result.getJSONObject("data").getJSONObject("data").getJSONObject("output") // 真实接口返回结构:result.getJSONObject("data").getJSONObject("output") // 模拟接口处理(当前使用) if (result.containsKey("data") && result.getJSONObject("data").containsKey("data")) { JSONObject innerData = result.getJSONObject("data").getJSONObject("data"); if (innerData != null && innerData.containsKey(OUTPUT)) { Object output = innerData.get(OUTPUT); if (output instanceof JSONArray) { return (JSONArray) output; } } } // 真实接口处理(注释掉,需要时手动切换) // else if (result.containsKey("data")) { // JSONObject data = result.getJSONObject("data"); // if (data != null && data.containsKey(OUTPUT)) { // Object output = data.get(OUTPUT); // if (output instanceof JSONArray) { // return (JSONArray) output; // } // } // } return new JSONArray(); } /** * 工伤预结算返回结果提取(支持模拟接口和真实接口切换) */ private JSONObject extractWorkInjuryPreSettlementResult(JSONObject result) { if (result == null) { return new JSONObject(); } // 模拟接口返回结构:result.getJSONObject("data").getJSONObject("data").getJSONObject("output") // 真实接口返回结构:result.getJSONObject("data").getJSONObject("output") // 模拟接口处理(当前使用) if (result.containsKey("data") && result.getJSONObject("data").containsKey("data")) { JSONObject innerData = result.getJSONObject("data").getJSONObject("data"); if (innerData != null && innerData.containsKey(OUTPUT)) { Object output = innerData.get(OUTPUT); if (output instanceof JSONObject) { return (JSONObject) output; } } } // 真实接口处理(注释掉,需要时手动切换) // else if (result.containsKey("data")) { // JSONObject data = result.getJSONObject("data"); // if (data != null && data.containsKey(OUTPUT)) { // Object output = data.get(OUTPUT); // if (output instanceof JSONObject) { // return (JSONObject) output; // } // } // } return new JSONObject(); } /** * 工伤接口错误信息提取(支持模拟接口和真实接口切换) */ private String extractWorkInjuryErrorMessage(JSONObject result) { if (result == null) { return "未知错误"; } // 模拟接口返回结构:result.getJSONObject("data").getJSONObject("data").getString("err_msg") // 真实接口返回结构:result.getJSONObject("data").getString("err_msg") // 模拟接口处理(当前使用) if (result.containsKey("data") && result.getJSONObject("data").containsKey("data")) { JSONObject innerData = result.getJSONObject("data").getJSONObject("data"); if (innerData != null) { String errorMsg = innerData.getString(ERROR_MESSAGE); return StringUtil.isBlank(errorMsg) ? "未知错误" : errorMsg; } } // 真实接口处理(注释掉,需要时手动切换) // else if (result.containsKey("data")) { // JSONObject data = result.getJSONObject("data"); // if (data != null) { // String errorMsg = data.getString(ERROR_MESSAGE); // return StringUtil.isBlank(errorMsg) ? "未知错误" : errorMsg; // } // } return "未知错误"; } /** * 工伤费用预处理 */ private void beforeWorkInjuryUpload(Overview o) { // 工伤费用预处理逻辑(与医保类似,但可能有特殊规则) Date disdate = zyDao.selectDscgDate(o.getInpatientNo(), o.getAdmissTimes()); if (null != disdate) { int num = zyDao.updateChargedate(o.getInpatientNo(), o.getAdmissTimes(), disdate); log.info("修改工伤费用时间大于出院医嘱时间的费用条目数:{}", num); } // 工伤费用正负相抵逻辑(与医保类似) List negativeCharges = zyDao.selectNegativeFeesWithOriDetlSn( o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn()); if (null == negativeCharges || negativeCharges.isEmpty()) { log.info("工伤正负相抵完成,抵消费用总条目:0"); return; } List positiveCharges = new ArrayList<>(); List tempSn = new ArrayList<>(); for (FeeCounteract feeCounteract : negativeCharges) { tempSn.add(feeCounteract.getOriDetailSn()); if (tempSn.size() == 30) { positiveCharges.addAll(zyDao.selectPositiveFeesByDetlSn( o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), tempSn)); tempSn.clear(); } } if (!tempSn.isEmpty()) { positiveCharges.addAll(zyDao.selectPositiveFeesByDetlSn( o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), tempSn)); } ConcurrentHashMap positiveChargeMap = new ConcurrentHashMap<>(); positiveCharges.forEach(itm -> { if (!positiveChargeMap.containsKey(itm.getDetailSn())) { positiveChargeMap.put(itm.getDetailSn(), itm); } }); int count = 0; for (FeeCounteract negativeCharge : negativeCharges) { if (positiveChargeMap.containsKey(negativeCharge.getOriDetailSn())) { FeeCounteract positiveCharge = positiveChargeMap.get(negativeCharge.getOriDetailSn()); if (positiveCharge.getUsed()) { continue; } if (negativeCharge.getChargeAmount() + positiveCharge.getChargeAmount() == 0d && negativeCharge.getChargeFee() + positiveCharge.getChargeFee() == 0d) { zyDao.updateYbTransFlagInPair(o.getInpatientNo(), o.getAdmissTimes(), negativeCharge.getDetailSn(), negativeCharge.getOriDetailSn()); count += 2; positiveCharge.setUsed(true); } } } log.info("工伤正负相抵完成,抵消费用总条目:{}", count); } /** * 格式化日期时间为工伤接口要求的格式 * @param date 日期时间 * @return 格式化的日期时间字符串 YYYYMMDDHH24MISS */ private String formatDateTime(Date date) { if (date == null) { return ""; } SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); return sdf.format(date); } }