|
@@ -52,6 +52,11 @@ import cn.hnthyy.thmz.vo.MzRefundMedicineVo;
|
|
|
import cn.hnthyy.thmz.vo.MzSendMedicineVo;
|
|
|
import cn.hnthyy.thmz.vo.PharmacyCellVo;
|
|
|
import cn.hnthyy.thmz.vo.YpMzFytjVo;
|
|
|
+import cn.hnthyy.thmz.controller.yb.YbController;
|
|
|
+import cn.hnthyy.thmz.entity.yb.SelinfoSold;
|
|
|
+import cn.hnthyy.thmz.entity.yb.SelinfoSoldTotal;
|
|
|
+import cn.hnthyy.thmz.entity.yb.DrugTracCodg;
|
|
|
+import cn.hnthyy.thmz.entity.jy.ResultVo;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.apache.commons.lang3.time.DateUtils;
|
|
@@ -123,6 +128,9 @@ public class MzPharmacyController {
|
|
|
private MzZdInstructionCodeService mzZdInstructionCodeService;
|
|
|
@Resource
|
|
|
private YpZdGroupNameService ypZdGroupNameService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private YbController ybController;
|
|
|
/**
|
|
|
* 查询处方信息
|
|
|
*
|
|
@@ -1980,4 +1988,277 @@ public class MzPharmacyController {
|
|
|
|
|
|
return resultMap;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 撤销退药时调用医保销售接口
|
|
|
+ * 内嵌获取退药明细、追溯码查询、医保接口调用
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/cancelRefundWithYb", method = {RequestMethod.POST})
|
|
|
+ @UserLoginToken
|
|
|
+ public Map<String, Object> cancelRefundWithYb(@RequestBody Map<String, Object> params) {
|
|
|
+ Map<String, Object> resultMap = new HashMap<>();
|
|
|
+ try {
|
|
|
+ log.info("撤销退药医保接口调用开始,参数:{}", params);
|
|
|
+
|
|
|
+ // 1. 使用简化版的查询方式(和 getRefundYpMx 一样)
|
|
|
+ ChargeFeeParamsVo chargeFeeParamsVo = new ChargeFeeParamsVo();
|
|
|
+ chargeFeeParamsVo.setPatientId((String) params.get("patientId"));
|
|
|
+ chargeFeeParamsVo.setTimes((Integer) params.get("times"));
|
|
|
+ // 处理 receiptNo 和 orderNo 的类型转换,支持 Integer 和 String 两种类型
|
|
|
+ Object receiptNoObj = params.get("receiptNo");
|
|
|
+ Object orderNoObj = params.get("orderNo");
|
|
|
+ chargeFeeParamsVo.setReceiptNo(receiptNoObj instanceof Integer ? String.valueOf(receiptNoObj) : (String) receiptNoObj);
|
|
|
+ chargeFeeParamsVo.setOrderNo(orderNoObj instanceof Integer ? String.valueOf(orderNoObj) : (String) orderNoObj);
|
|
|
+ chargeFeeParamsVo.setGroupNoOut((String) params.get("groupNoOut"));
|
|
|
+ chargeFeeParamsVo.setConfirmFlag(2); // 已退药状态
|
|
|
+
|
|
|
+ List<Map<String, Object>> refundDetailList = mzPharmacyService.getPrescriptionYpMxCxTySimple(chargeFeeParamsVo);
|
|
|
+
|
|
|
+ if (refundDetailList == null || refundDetailList.isEmpty()) {
|
|
|
+ resultMap.put("code", -1);
|
|
|
+ resultMap.put("message", "未找到退药明细数据");
|
|
|
+ return resultMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("获取到退药明细数据,共{}条", refundDetailList.size());
|
|
|
+
|
|
|
+ // 2. 遍历每个药品,获取追溯码并调用医保接口
|
|
|
+ int successCount = 0;
|
|
|
+ int failCount = 0;
|
|
|
+ StringBuilder errorMsg = new StringBuilder();
|
|
|
+
|
|
|
+ for (Map<String, Object> item : refundDetailList) {
|
|
|
+ try {
|
|
|
+ // 2.1 构建追溯码查询参数
|
|
|
+ MzDrugTracCodg tracCodgQuery = new MzDrugTracCodg();
|
|
|
+ tracCodgQuery.setPatientId((String) item.get("patient_id"));
|
|
|
+ // 处理类型转换,支持 Short 和 Integer 两种类型
|
|
|
+ Object timesObj = item.get("times");
|
|
|
+ Object itemReceiptNoObj = item.get("receipt_no");
|
|
|
+ Object itemOrderNoObj = item.get("order_no");
|
|
|
+ Object itemNoObj = item.get("item_no");
|
|
|
+
|
|
|
+ tracCodgQuery.setTimes(timesObj instanceof Short ? ((Short) timesObj).intValue() : (Integer) timesObj);
|
|
|
+ // 修复:追溯码表中 receipt_no 是正数,需要转换
|
|
|
+ Integer itemReceiptNo = itemReceiptNoObj instanceof Short ? ((Short) itemReceiptNoObj).intValue() : (Integer) itemReceiptNoObj;
|
|
|
+ tracCodgQuery.setReceiptNo(Math.abs(itemReceiptNo)); // 转换为正数
|
|
|
+ tracCodgQuery.setOrderNo(itemOrderNoObj instanceof Short ? ((Short) itemOrderNoObj).intValue() : (Integer) itemOrderNoObj);
|
|
|
+ tracCodgQuery.setChargeItemCode((String) item.get("charge_item_code"));
|
|
|
+ tracCodgQuery.setSerial((String) item.get("serial"));
|
|
|
+ tracCodgQuery.setItemNo(itemNoObj instanceof Short ? ((Short) itemNoObj).intValue() : (Integer) itemNoObj);
|
|
|
+ // 修复:添加 group_no 参数,从 params 中获取 groupNoOut
|
|
|
+ String groupNoOut = (String) params.get("groupNoOut");
|
|
|
+ tracCodgQuery.setGroupNo(groupNoOut);
|
|
|
+
|
|
|
+ // 添加调试日志
|
|
|
+ log.info("追溯码查询参数: patientId={}, times={}, receiptNo={}, orderNo={}, chargeItemCode={}, serial={}, itemNo={}, groupNo={}",
|
|
|
+ tracCodgQuery.getPatientId(), tracCodgQuery.getTimes(), tracCodgQuery.getReceiptNo(),
|
|
|
+ tracCodgQuery.getOrderNo(), tracCodgQuery.getChargeItemCode(), tracCodgQuery.getSerial(),
|
|
|
+ tracCodgQuery.getItemNo(), tracCodgQuery.getGroupNo());
|
|
|
+
|
|
|
+ // 2.2 获取追溯码数据
|
|
|
+ List<MzDrugTracCodg> tracCodgList = mzDrugTracCodgService.getMzDrugTracCodgData(tracCodgQuery);
|
|
|
+
|
|
|
+ if (tracCodgList == null || tracCodgList.isEmpty()) {
|
|
|
+ log.warn("药品{}未找到追溯码数据", item.get("charge_item_code"));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2.3 构建医保接口参数
|
|
|
+ Map<String, Object> ybParams = buildYbParamsForCancelRefund(item, params);
|
|
|
+
|
|
|
+ // 2.4 记录医保接口传参日志
|
|
|
+ log.info("医保接口参数: {}", ybParams);
|
|
|
+
|
|
|
+ // 2.5 构建 SelinfoSoldTotal 对象
|
|
|
+ SelinfoSoldTotal selinfoSoldTotal = new SelinfoSoldTotal();
|
|
|
+
|
|
|
+ // 构建 SelinfoSold 对象
|
|
|
+ SelinfoSold selinfoSold = new SelinfoSold();
|
|
|
+ selinfoSold.setPatientId((String) item.get("patient_id"));
|
|
|
+ selinfoSold.setTimes(timesObj instanceof Short ? ((Short) timesObj).intValue() : (Integer) timesObj);
|
|
|
+ selinfoSold.setReceiptNo(itemReceiptNoObj instanceof Short ? ((Short) itemReceiptNoObj).intValue() : (Integer) itemReceiptNoObj);
|
|
|
+ selinfoSold.setOrderNo(itemOrderNoObj instanceof Short ? ((Short) itemOrderNoObj).intValue() : (Integer) itemOrderNoObj);
|
|
|
+ selinfoSold.setChargeItemCode((String) item.get("charge_item_code"));
|
|
|
+ // 处理 realNo 的类型转换
|
|
|
+ Object realNoObj = item.get("real_no");
|
|
|
+ selinfoSold.setRealNo(realNoObj instanceof Short ? ((Short) realNoObj).intValue() : (Integer) realNoObj);
|
|
|
+ selinfoSold.setMedListCodg((String) item.get("national_code"));
|
|
|
+ selinfoSold.setPrscDrName(getCurrentDoctorName(params));
|
|
|
+ selinfoSold.setPharName(getCurrentUserName(params));
|
|
|
+ selinfoSold.setPharPracCertNo(getPharPracCertNo(params));
|
|
|
+ selinfoSold.setSelRetnOpterName(getCurrentUserName(params));
|
|
|
+ selinfoSold.setMdtrtSetlType(item.get("mdtrtSetlType") != null ? (String) item.get("mdtrtSetlType") : "2");
|
|
|
+ selinfoSold.setRxFlag(item.get("rx_flag") != null ? (String) item.get("rx_flag") : "0");
|
|
|
+ selinfoSold.setTrdnFlag(item.get("cl_flag") != null ? (String) item.get("cl_flag") : "0");
|
|
|
+ selinfoSold.setPsnCertType(item.get("psnCertType") != null ? (String) item.get("psnCertType") : "01");
|
|
|
+ selinfoSold.setCertno(item.get("certno") != null ? (String) item.get("certno") : "");
|
|
|
+ selinfoSold.setPsnName(item.get("psnName") != null ? (String) item.get("psnName") : "");
|
|
|
+
|
|
|
+ selinfoSoldTotal.setSelinfoSold(selinfoSold);
|
|
|
+
|
|
|
+ // 构建追溯码列表
|
|
|
+ List<DrugTracCodg> drugTracCodgList = new ArrayList<>();
|
|
|
+ for (MzDrugTracCodg tracCodg : tracCodgList) {
|
|
|
+ DrugTracCodg drugTracCodg = new DrugTracCodg();
|
|
|
+ drugTracCodg.setDrugTracCodg(tracCodg.getDrugTracCodg());
|
|
|
+ drugTracCodgList.add(drugTracCodg);
|
|
|
+ }
|
|
|
+ selinfoSoldTotal.setDrugtracinfo(drugTracCodgList);
|
|
|
+
|
|
|
+ log.info("最终调用医保接口参数: {}", selinfoSoldTotal);
|
|
|
+
|
|
|
+ // 2.6 调用医保销售接口
|
|
|
+ ResultVo ybResult = ybController.saleGoodsItem(selinfoSoldTotal);
|
|
|
+
|
|
|
+ if (ybResult != null && ybResult.getCode() == 0) {
|
|
|
+ successCount++;
|
|
|
+ log.info("药品{}医保接口调用成功", item.get("charge_item_code"));
|
|
|
+ } else {
|
|
|
+ failCount++;
|
|
|
+ String errorMessage = ybResult != null ? ybResult.getMessage() : "医保接口返回空结果";
|
|
|
+ errorMsg.append("药品").append(item.get("charge_item_code")).append(": ").append(errorMessage).append("; ");
|
|
|
+ log.error("药品{}医保接口调用失败: {}", item.get("charge_item_code"), errorMessage);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ failCount++;
|
|
|
+ String errorMessage = "药品" + item.get("charge_item_code") + "处理异常: " + e.getMessage();
|
|
|
+ errorMsg.append(errorMessage).append("; ");
|
|
|
+ log.error(errorMessage, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 返回结果
|
|
|
+ if (failCount == 0) {
|
|
|
+ resultMap.put("code", 0);
|
|
|
+ resultMap.put("message", "撤销退药医保接口调用成功,共处理" + successCount + "个药品");
|
|
|
+ } else {
|
|
|
+ resultMap.put("code", -1);
|
|
|
+ resultMap.put("message", "撤销退药医保接口调用部分失败,成功" + successCount + "个,失败" + failCount + "个。错误信息:" + errorMsg.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ return resultMap;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("撤销退药医保接口调用异常", e);
|
|
|
+ resultMap.put("code", -1);
|
|
|
+ resultMap.put("message", "撤销退药医保接口调用异常:" + e.getMessage());
|
|
|
+ return resultMap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建撤销退药医保接口参数
|
|
|
+ */
|
|
|
+ private Map<String, Object> buildYbParamsForCancelRefund(Map<String, Object> item, Map<String, Object> params) {
|
|
|
+ Map<String, Object> ybParams = new HashMap<>();
|
|
|
+
|
|
|
+ // 关联字段
|
|
|
+ ybParams.put("patientId", item.get("patientId"));
|
|
|
+ ybParams.put("times", item.get("times"));
|
|
|
+ ybParams.put("receiptNo", item.get("receiptNo"));
|
|
|
+ ybParams.put("orderNo", item.get("orderNo"));
|
|
|
+ ybParams.put("chargeItemCode", item.get("chargeItemCode"));
|
|
|
+ ybParams.put("realNo", item.get("realNo"));
|
|
|
+
|
|
|
+ // 医疗目录编码(医保编码)
|
|
|
+ ybParams.put("medListCodg", item.get("nationalCode"));
|
|
|
+
|
|
|
+ // 开方医师姓名(从处方明细中获取,如果没有则使用当前用户)
|
|
|
+ String doctorName = getCurrentDoctorName(params);
|
|
|
+ ybParams.put("prscDrName", doctorName);
|
|
|
+
|
|
|
+ // 药师姓名(使用前端传递的药师姓名)
|
|
|
+ String pharName = getCurrentUserName(params);
|
|
|
+ ybParams.put("pharName", pharName);
|
|
|
+
|
|
|
+ // 药师执业资格证号
|
|
|
+ String pharPracCertNo = getPharPracCertNo(params);
|
|
|
+ ybParams.put("pharPracCertNo", pharPracCertNo);
|
|
|
+
|
|
|
+ // 销售/退货经办人姓名
|
|
|
+ ybParams.put("selRetnOpterName", pharName);
|
|
|
+
|
|
|
+ // 就诊结算类型(1-医保结算 2-自费结算)
|
|
|
+ ybParams.put("mdtrtSetlType", item.get("mdtrtSetlType") != null ? item.get("mdtrtSetlType") : "2");
|
|
|
+
|
|
|
+ // 处方药标志
|
|
|
+ ybParams.put("rxFlag", item.get("rxFlag") != null ? item.get("rxFlag") : "0");
|
|
|
+
|
|
|
+ // 拆零标志(0-否;1-是)
|
|
|
+ ybParams.put("trdnFlag", item.get("clFlag") != null ? item.get("clFlag") : "0");
|
|
|
+
|
|
|
+ // 患者相关参数
|
|
|
+ ybParams.put("psnCertType", item.get("psnCertType") != null ? item.get("psnCertType") : "01");
|
|
|
+ ybParams.put("certno", item.get("certno") != null ? item.get("certno") : "");
|
|
|
+ ybParams.put("psnName", item.get("psnName") != null ? item.get("psnName") : "");
|
|
|
+
|
|
|
+ return ybParams;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前医生姓名
|
|
|
+ */
|
|
|
+ private String getCurrentDoctorName(Map<String, Object> params) {
|
|
|
+ // 从前端参数中获取医生姓名
|
|
|
+ String doctorName = (String) params.get("doctorName");
|
|
|
+ if (doctorName != null && !doctorName.trim().isEmpty()) {
|
|
|
+ return doctorName;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果前端没有传递医生姓名,则报错
|
|
|
+ throw new RuntimeException("前端参数中未找到医生姓名(doctorName),请检查参数传递");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前用户姓名
|
|
|
+ */
|
|
|
+ private String getCurrentUserName(Map<String, Object> params) {
|
|
|
+ // 从前端参数中获取药师姓名
|
|
|
+ String pharName = (String) params.get("pharName");
|
|
|
+ if (pharName != null && !pharName.trim().isEmpty()) {
|
|
|
+ return pharName;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果前端没有传递,则从当前用户信息获取
|
|
|
+ try {
|
|
|
+ User currentUser = TokenUtil.getUser();
|
|
|
+ if (currentUser != null) {
|
|
|
+ return currentUser.getUserName();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取当前用户信息失败", e);
|
|
|
+ }
|
|
|
+ return "药师姓名"; // 默认值
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取药师执业资格证号
|
|
|
+ */
|
|
|
+ private String getPharPracCertNo(Map<String, Object> params) {
|
|
|
+ // 从前端参数中获取药师执业资格证号
|
|
|
+ String pharPracCertNo = (String) params.get("pharPracCertNo");
|
|
|
+ if (pharPracCertNo != null && !pharPracCertNo.trim().isEmpty()) {
|
|
|
+ return pharPracCertNo;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果前端没有传递,则从当前用户信息获取
|
|
|
+ try {
|
|
|
+ User currentUser = TokenUtil.getUser();
|
|
|
+ if (currentUser != null) {
|
|
|
+ // 根据当前用户编码查询员工信息
|
|
|
+ Employee employee = employeeService.queryByUserCode(currentUser.getUserCode());
|
|
|
+ if (employee != null) {
|
|
|
+ // 获取药师执业资格证号:优先取执业证编码,如果为空则取医保赋码
|
|
|
+ if (StringUtils.isNotBlank(employee.getPracticeCertificate())) {
|
|
|
+ return employee.getPracticeCertificate();
|
|
|
+ } else if (StringUtils.isNotBlank(employee.getYbCode())) {
|
|
|
+ return employee.getYbCode();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取当前用户信息失败", e);
|
|
|
+ }
|
|
|
+ return "药师执业资格证号"; // 默认值
|
|
|
+ }
|
|
|
}
|