|
@@ -30,6 +30,7 @@ import thyyxxk.webserver.utils.*;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.util.*;
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
|
/**
|
|
|
* @description: 住院医保交易
|
|
@@ -741,4 +742,275 @@ public class SiZyService {
|
|
|
dao.updateSettleType(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn());
|
|
|
dao.updateChargeStatus(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn());
|
|
|
}
|
|
|
+
|
|
|
+ public String revokeWorkInjuryUploadFees(ZyPatientInfo p) {
|
|
|
+ SiPatInfo siPatInfo = queryDao.selectSiPatInfo(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn());
|
|
|
+ if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) {
|
|
|
+ throw new BizException(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的工伤在院信息!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据传入的明细号决定撤销方式
|
|
|
+ if (null == p.getDetailSns() || p.getDetailSns().isEmpty()) {
|
|
|
+ // 撤销全部:只传门诊/住院流水号,处方号和处方流水号为空
|
|
|
+ return revokeAllWorkInjuryFees(p, siPatInfo);
|
|
|
+ } else {
|
|
|
+ // 撤销指定明细:需要遍历每个明细号
|
|
|
+ return revokeSpecificWorkInjuryFees(p, siPatInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 撤销全部工伤费用
|
|
|
+ */
|
|
|
+ private String revokeAllWorkInjuryFees(ZyPatientInfo p, SiPatInfo siPatInfo) {
|
|
|
+ // 构建工伤撤销请求(处方明细撤销)
|
|
|
+ JSONObject input = new JSONObject();
|
|
|
+ input.put("action", "transaction");
|
|
|
+ input.put("transactionName", "2205");
|
|
|
+
|
|
|
+ JSONObject businessParams = new JSONObject();
|
|
|
+ businessParams.put("ipt_otp_no", siPatInfo.getMdtrtId()); // 门诊/住院流水号
|
|
|
+ businessParams.put("rxno", ""); // 处方号为空
|
|
|
+ businessParams.put("feedetl_sn", ""); // 处方流水号为空
|
|
|
+
|
|
|
+ input.put("businessParams", businessParams);
|
|
|
+
|
|
|
+ // 调用工伤撤销接口
|
|
|
+ JSONObject result = exec.executeWorkInjuryTrade(input);
|
|
|
+
|
|
|
+ if (null == result) {
|
|
|
+ throw new BizException(ExceptionEnum.NETWORK_ERROR, "工伤撤销接口调用失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 工伤接口返回结果处理(支持模拟接口和真实接口切换)
|
|
|
+ Integer infcode = extractWorkInjuryResultCode(result);
|
|
|
+
|
|
|
+ if (null == infcode) {
|
|
|
+ throw new BizException(ExceptionEnum.LOGICAL_ERROR, "工伤撤销接口返回结果解析失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构造工伤日志input(参考工伤预结算写法)
|
|
|
+ JSONObject logInput = new JSONObject();
|
|
|
+ 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 {
|
|
|
+ logInput.put("infno", "2205"); // 工伤撤销接口号
|
|
|
+ logInput.put("insuplc_admdvs", "");
|
|
|
+ logInput.put("msgid", "WORK_INJURY_" + System.currentTimeMillis());
|
|
|
+ logInput.put("opter", p.getStaffId());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ logInput.put("infno", "2205");
|
|
|
+ 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, siPatInfo.getPsnNo()));
|
|
|
+
|
|
|
+ if (infcode == 0) {
|
|
|
+ // 撤销成功,更新数据库状态
|
|
|
+ dao.revokeAllUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn());
|
|
|
+ dao.resetFundpayAmt(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn());
|
|
|
+
|
|
|
+ QueryWrapper<SiChargeTemp> wrapper = new QueryWrapper<>();
|
|
|
+ wrapper.eq("pat_no", p.getInpatientNo());
|
|
|
+ wrapper.eq("times", p.getAdmissTimes());
|
|
|
+ wrapper.eq("ledger_sn", p.getLedgerSn());
|
|
|
+ chrgtmpdao.delete(wrapper);
|
|
|
+
|
|
|
+ return "工伤撤销费用成功。";
|
|
|
+ } else {
|
|
|
+ String errorMsg = extractWorkInjuryErrorMessage(result);
|
|
|
+ throw new BizException(ExceptionEnum.LOGICAL_ERROR, "工伤撤销失败:" + errorMsg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 撤销指定工伤费用明细
|
|
|
+ */
|
|
|
+ private String revokeSpecificWorkInjuryFees(ZyPatientInfo p, SiPatInfo siPatInfo) {
|
|
|
+ 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 = dao.selectRxnoByDetailSn(p.getInpatientNo(), p.getAdmissTimes(), detailSn);
|
|
|
+
|
|
|
+ if (StringUtil.isBlank(rxno)) {
|
|
|
+ // 如果处方号为空,只传门诊/住院流水号,不传处方号和处方流水号
|
|
|
+ // 这样会撤销该门诊/住院流水号下所有未结算处方
|
|
|
+ businessParams.put("rxno", "");
|
|
|
+ businessParams.put("feedetl_sn", "");
|
|
|
+ } else {
|
|
|
+ // 如果处方号有值,传完整的参数
|
|
|
+ businessParams.put("rxno", rxno);
|
|
|
+ businessParams.put("feedetl_sn", detailSn.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ input.put("businessParams", businessParams);
|
|
|
+
|
|
|
+ // 调用工伤撤销接口
|
|
|
+ JSONObject result = exec.executeWorkInjuryTrade(input);
|
|
|
+
|
|
|
+ if (null == result) {
|
|
|
+ log.error("工伤撤销接口调用失败,明细:{}", detailSn);
|
|
|
+ failedDetailSns.add(detailSn);
|
|
|
+ continue; // 继续撤销下一个,不中断整个流程
|
|
|
+ }
|
|
|
+
|
|
|
+ // 工伤接口返回结果处理(支持模拟接口和真实接口切换)
|
|
|
+ Integer infcode = extractWorkInjuryResultCode(result);
|
|
|
+
|
|
|
+ if (null == infcode) {
|
|
|
+ log.error("工伤撤销接口返回结果解析失败,明细:{}", detailSn);
|
|
|
+ failedDetailSns.add(detailSn);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构造工伤日志input(参考工伤预结算写法)
|
|
|
+ JSONObject logInput = new JSONObject();
|
|
|
+ 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 {
|
|
|
+ logInput.put("infno", "2205"); // 工伤撤销接口号
|
|
|
+ logInput.put("insuplc_admdvs", "");
|
|
|
+ logInput.put("msgid", "WORK_INJURY_" + System.currentTimeMillis());
|
|
|
+ logInput.put("opter", p.getStaffId());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ logInput.put("infno", "2205");
|
|
|
+ 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, siPatInfo.getPsnNo()));
|
|
|
+
|
|
|
+ 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());
|
|
|
+ throw new BizException(ExceptionEnum.LOGICAL_ERROR, "工伤撤销全部失败,请检查网络连接和接口状态。");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新数据库
|
|
|
+ if (successDetailSns.size() == p.getDetailSns().size()) {
|
|
|
+ // 全部撤销成功
|
|
|
+ log.info("工伤撤销全部成功,患者:{},明细数:{}", p.getInpatientNo(), successDetailSns.size());
|
|
|
+ dao.revokePartUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), successDetailSns);
|
|
|
+
|
|
|
+ QueryWrapper<SiChargeTemp> wrapper = new QueryWrapper<>();
|
|
|
+ wrapper.eq("pat_no", p.getInpatientNo());
|
|
|
+ wrapper.eq("times", p.getAdmissTimes());
|
|
|
+ wrapper.eq("ledger_sn", p.getLedgerSn());
|
|
|
+ wrapper.in("feedetl_sn", successDetailSns);
|
|
|
+ chrgtmpdao.delete(wrapper);
|
|
|
+ } else {
|
|
|
+ // 部分撤销成功,只更新成功撤销的明细
|
|
|
+ log.info("工伤撤销部分成功,患者:{},成功:{},失败:{}",
|
|
|
+ p.getInpatientNo(), successDetailSns.size(), failedDetailSns.size());
|
|
|
+ dao.revokePartUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), successDetailSns);
|
|
|
+
|
|
|
+ QueryWrapper<SiChargeTemp> wrapper = new QueryWrapper<>();
|
|
|
+ wrapper.eq("pat_no", p.getInpatientNo());
|
|
|
+ wrapper.eq("times", p.getAdmissTimes());
|
|
|
+ wrapper.eq("ledger_sn", p.getLedgerSn());
|
|
|
+ wrapper.in("feedetl_sn", successDetailSns);
|
|
|
+ chrgtmpdao.delete(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("工伤撤销流程完成,患者:{},成功撤销:{},失败撤销:{}",
|
|
|
+ p.getInpatientNo(), successDetailSns.size(), failedDetailSns.size());
|
|
|
+
|
|
|
+ if (failedDetailSns.isEmpty()) {
|
|
|
+ return "工伤撤销费用成功。";
|
|
|
+ } else {
|
|
|
+ return String.format("工伤撤销部分成功。成功:%d,失败:%d", successDetailSns.size(), failedDetailSns.size());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 工伤接口返回结果代码提取(支持模拟接口和真实接口切换)
|
|
|
+ */
|
|
|
+ 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 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 "未知错误";
|
|
|
+ }
|
|
|
}
|