1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219 |
- 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<String, CodeName> uploadingMap;
- private static final ConcurrentHashMap<String, CodeName> 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<String> uploadMultiplePatientFees(List<Overview> 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<String> 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<String> 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<Integer> notAllowedSns = zyDao.selectNotAllowedSnForMidSetl(o.getInpatientNo(), o.getAdmissTimes(),
- o.getLedgerSn(), o.getEndtime());
- if (!notAllowedSns.isEmpty()) {
- List<Integer> 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<String, Queue<FeeDtle>> allFees = getAllFeesNotUploaded(o);
- Queue<FeeDtle> allPositiveFees = allFees.get("positive");
- Queue<FeeDtle> 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<String, Queue<FeeDtle>> getAllFeesNotUploaded(Overview o) {
- Queue<FeeDtle> 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<String, Queue<FeeDtle>> 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<FeeDtle> 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<FeeDtle> 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<FeeDtle> 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<SiChargeTemp> 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<String> 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<FeeCounteract> negativeCharges = zyDao.selectNegativeFeesWithOriDetlSn(
- o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn());
- if (null == negativeCharges || negativeCharges.isEmpty()) {
- log.info("正负相抵完成,抵消费用总条目:0");
- return;
- }
- List<FeeCounteract> positiveCharges = new ArrayList<>();
- List<Integer> 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<Integer, FeeCounteract> 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<String> uploadWorkInjuryFees(List<Overview> 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<String> 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<String> 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<Integer> notAllowedSns = zyDao.selectNotAllowedSnForMidSetl(o.getInpatientNo(), o.getAdmissTimes(),
- o.getLedgerSn(), o.getEndtime());
- if (!notAllowedSns.isEmpty()) {
- List<Integer> 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<String, Queue<FeeDtle>> allFees = getAllFeesNotUploaded(o);
- Queue<FeeDtle> allPositiveFees = allFees.get("positive");
- Queue<FeeDtle> 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<Integer> successDetailSns = new ArrayList<>(); // 记录成功撤销的明细
- List<Integer> 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<FeeDtle> 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<FeeDtle> 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<FeeDtle> 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<SiChargeTemp> 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<String, Object> 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<String> 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<FeeCounteract> negativeCharges = zyDao.selectNegativeFeesWithOriDetlSn(
- o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn());
- if (null == negativeCharges || negativeCharges.isEmpty()) {
- log.info("工伤正负相抵完成,抵消费用总条目:0");
- return;
- }
-
- List<FeeCounteract> positiveCharges = new ArrayList<>();
- List<Integer> 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<Integer, FeeCounteract> 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);
- }
- }
|