123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- package cn.hnthyy.thmz.service.yb;
- import cn.hnthyy.thmz.Utils.HttpUtil;
- import cn.hnthyy.thmz.entity.his.zy.ZyActpatient;
- import cn.hnthyy.thmz.entity.jy.ResultVo;
- import cn.hnthyy.thmz.entity.yb.*;
- import cn.hnthyy.thmz.mapper.his.yb.SelinfoSoldMapper;
- import cn.hnthyy.thmz.mapper.his.zy.ZyActpatientMapper;
- import cn.hnthyy.thmz.service.taobao.TaobaoService;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.alibaba.fastjson.serializer.SerializerFeature;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.BeanUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- import org.yaml.snakeyaml.util.UriEncoder;
- import java.text.SimpleDateFormat;
- import java.util.*;
- @Slf4j
- @Service
- public class YbService {
- @Value("${siInventoryServiceUrl}")
- private String siInventoryServiceUrl;
- @Autowired
- private TaobaoService taobaoService;
- @Autowired
- private SelinfoSoldMapper selinfoSoldMapper;
- @Autowired
- private ZyActpatientMapper zyActpatientMapper;
- /**
- * 医保商品销售接口
- * 功能说明:将发药信息上报给医保系统,实现医保结算
- *
- * 关联字段说明:
- * - patientId: 患者ID,来自 mz_charge_detail.patient_id
- * - times: 就诊次数,来自 mz_charge_detail.times
- * - receiptNo: 发票分票号,来自 mz_charge_detail.receipt_no
- * - orderNo: 处方号,来自 mz_charge_detail.order_no
- * - chargeItemCode: 收费项目编码,来自 mz_charge_detail.charge_item_code
- * - realNo: 流水号,来自 mz_charge_detail.real_no
- *
- * 关联查询接口:
- * - /thmz/getDispensingRecordByAssociation: 通过关联字段查询发药记录
- *
- * 关联数据表:
- * - yp_mz_fytj: 发药统计表,记录发药数量、金额等统计信息
- * - mz_drug_trac_codg: 药品追溯码表,记录药品追溯码信息
- * - mz_charge_detail: 收费明细表,记录收费项目详细信息
- *
- * 业务流程:
- * 1. 前端发药页面调用 /thmz/sendMedicineProcessing 进行发药处理
- * 2. 发药成功后调用此接口上报医保系统
- * 3. 医保系统记录关联字段,便于后续查询和审计
- * 4. 可通过关联字段查询具体的发药记录和追溯码信息
- *
- * @param selinfoSoldTotal 医保销售信息对象,包含关联字段和药品追溯码信息
- * @return ResultVo 医保接口调用结果
- */
- public ResultVo saleGoodsItem(SelinfoSoldTotal selinfoSoldTotal) {
- ResultVo response = null;
- SelinfoSold selInfo = selinfoSoldTotal.getSelinfoSold();
- List<DrugTracCodg> drugTracCodgList = selinfoSoldTotal.getDrugtracinfo();
- // 记录关联字段信息(用于关联发药记录)
- // 这些字段用于后续查询发药记录,确保医保记录与发药记录的一一对应
- log.info("医保接口调用 - 关联字段: patientId={}, times={}, receiptNo={}, orderNo={}, chargeItemCode={}, realNo={}, drugTracCodgList={}",
- selInfo.getPatientId(), selInfo.getTimes(), selInfo.getReceiptNo(),
- selInfo.getOrderNo(), selInfo.getChargeItemCode(), selInfo.getRealNo(), JSONObject.toJSONString(drugTracCodgList));
- if(drugTracCodgList == null || drugTracCodgList.isEmpty()) {
- response = new ResultVo(-1, "追溯码不能为空");
- return response;
- }
- String drugTracCodg = drugTracCodgList.get(0).getDrugTracCodg();
- String result = taobaoService.sendGet("/queryCodeDetail?codes=" + drugTracCodg);
- JSONObject resultJson = JSONObject.parseObject(result);
- Integer code = resultJson.getInteger("code");
- if (code == 200) {
- JSONObject data = resultJson.getJSONObject("data");
- Integer dataCode = data.getInteger("code");
- if (dataCode == 0) {
- JSONArray content = data.getJSONArray("data");
- if(content != null && content.size() > 0) {
- JSONObject item = content.getJSONObject(0);
- JSONArray produceInfoList = item.getJSONObject("codeProduceInfoDTO").getJSONArray("produceInfoList");
- JSONObject drugEntBase = item.getJSONObject("drugEntBaseDTO");
- if(drugEntBase != null) {
- selInfo.setFixmedinsHilistName(drugEntBase.getString("physicName"));
- }
- if(produceInfoList != null && produceInfoList.size() > 0) {
- JSONObject produceInfo = produceInfoList.getJSONObject(0);
- selInfo.setManuLotnum(produceInfo.getString("batchNo"));
- selInfo.setManuDate(produceInfo.getString("produceDateStr"));
- }
- }
- }
- }
- int randomNumber = new Random().nextInt(90) + 10;
- String rtalDocno = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
- String mdtrtId = zyActpatientMapper.selectMdtrtId(selInfo.getPatientId(), selInfo.getTimes());
- if(StringUtils.isNotBlank(mdtrtId)) {
- selInfo.setMdtrtSn(mdtrtId);
- selInfo.setMdtrtSetlType("1");
- } else {
- selInfo.setMdtrtSn(rtalDocno + randomNumber);
- selInfo.setMdtrtSetlType("2");
- }
- selInfo.setRtalDocno(rtalDocno + randomNumber);
- selInfo.setFixmedinsBchno(rtalDocno + randomNumber);
- if("0".equals(selInfo.getTrdnFlag())) {
- selInfo.setSelRetnCnt(drugTracCodgList.size());
- }
- String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
- selInfo.setSelRetnTime(now);
- selInfo.setFixmedinsHilistId(selInfo.getMedListCodg());
- String id = UUID.randomUUID().toString().replaceAll("-", "");
- selInfo.setId(id);
- List<SelinfoSold> selinfoSoldList =
- selinfoSoldMapper.getSelinfoSoldList(selInfo.getPatientId(), selInfo.getTimes(),
- selInfo.getOrderNo(), selInfo.getChargeItemCode(), selInfo.getRealNo());
- if(selinfoSoldList != null && !selinfoSoldList.isEmpty()
- && selinfoSoldList.get(0).getMedListCodg().equals(selInfo.getMedListCodg())) {
- selInfo.setId(selinfoSoldList.get(0).getId());
- } else {
- selinfoSoldMapper.insert(selInfo);
- }
- selInfo.setPsnName(UriEncoder.encode(selInfo.getPsnName()));
- selInfo.setPrscDrName(UriEncoder.encode(selInfo.getPrscDrName()));
- selInfo.setPharName(UriEncoder.encode(selInfo.getPharName()));
- selInfo.setSelRetnOpterName(UriEncoder.encode(selInfo.getSelRetnOpterName()));
- selInfo.setFixmedinsHilistName(UriEncoder.encode(selInfo.getFixmedinsHilistName()));
- // 构建关联键(用于后续查询发药记录)
- // 关联键格式:patientId=xxx×=xxx&receiptNo=xxx&orderNo=xxx&chargeItemCode=xxx&realNo=xxx
- // 用途:用于日志记录和后续查询发药记录,确保医保记录与发药记录的可追溯性
- // 查询接口:/thmz/getDispensingRecordByAssociation 可通过此关联键查询具体的发药记录
- String associationKey = String.format("patientId=%s×=%s&receiptNo=%s&orderNo=%s&chargeItemCode=%s&realNo=%s",
- selInfo.getPatientId(), selInfo.getTimes(), selInfo.getReceiptNo(),
- selInfo.getOrderNo(), selInfo.getChargeItemCode(), selInfo.getRealNo());
- log.info("医保接口 - 关联键: {}", associationKey);
- String realUrl = siInventoryServiceUrl + "/saleGoodsItem";
- Selinfo selinfoParam = new Selinfo();
- BeanUtils.copyProperties(selInfo, selinfoParam);
- if("0".equals(selInfo.getTrdnFlag())) {
- selinfoParam.setDrugtracinfo(drugTracCodgList);
- }
- try {
- String jsonString = JSONObject.toJSONString(selinfoParam, SerializerFeature.WriteNonStringKeyAsString);
- String ybResult = HttpUtil.sendHttpPost(realUrl, jsonString, 8000);
- JSONObject ybResultJson = JSONObject.parseObject(ybResult);
- int responseCode = 0;
- if(ybResultJson.getInteger("code") != 200) {
- responseCode = ybResultJson.getInteger("code");
- }
- String successFlag = "0";
- JSONObject data = ybResultJson.getJSONObject("data");
- log.info("3505医保接口调用结果 - 结果: {}", JSONObject.toJSONString(data));
- if(data != null) {
- String infcode = data.getString("infcode");
- successFlag = "0".equals(infcode) ? "1" : "0";
- }
- response = new ResultVo(responseCode, ybResultJson.getString("message"));
- for(DrugTracCodg codg : drugTracCodgList) {
- String itemId = UUID.randomUUID().toString().replaceAll("-", "");
- /*String successFlag = "0";
- Map<String, String> param = new HashMap<>();
- param.put("med_list_codg", selInfo.getMedListCodg());
- param.put("trac_codg", codg.getDrugTracCodg());
- try {
- JSONObject selinfoResult = getGoodsItemByCode(param);
- JSONObject data = selinfoResult.getJSONObject("data");
- if(selinfoResult.getInteger("code") == 200) {
- JSONArray output = data.getJSONArray("output");
- if(output != null && !output.isEmpty()) {
- successFlag = "1";
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- log.error("医保接口调用失败 - 关联键: {}, 错误: {}", associationKey, e.getMessage());
- }*/
- selinfoSoldMapper.insertSelinfoSoldDrugtrac(itemId, selInfo.getId(), codg.getDrugTracCodg(), successFlag);
- }
-
- // 记录医保接口调用结果
- // 通过关联键可以快速定位具体的发药记录,便于问题排查和审计
- log.info("医保接口调用结果 - 关联键: {}, 结果: {}", associationKey, response);
-
- } catch (Exception e) {
- e.printStackTrace();
- response = new ResultVo(-1, "商品销售失败");
- // 记录错误信息时包含关联键,便于快速定位问题
- log.error("医保接口调用失败 - 关联键: {}, 错误: {}", associationKey, e.getMessage());
- }
- return response;
- }
- /**
- * 医保商品退货接口
- * 功能说明:将退药信息上报给医保系统,实现医保退费结算
- *
- * 关联字段说明:
- * - patientId: 患者ID,来自 mz_charge_detail.patient_id
- * - times: 就诊次数,来自 mz_charge_detail.times
- * - receiptNo: 发票分票号,来自 mz_charge_detail.receipt_no
- * - orderNo: 处方号,来自 mz_charge_detail.order_no
- * - chargeItemCode: 收费项目编码,来自 mz_charge_detail.charge_item_code
- * - realNo: 流水号,来自 mz_charge_detail.real_no
- *
- * 关联查询接口:
- * - /thmz/getDispensingRecordByAssociation: 通过关联字段查询退药记录
- *
- * 关联数据表:
- * - yp_mz_fytj: 退药统计表,记录退药数量、金额等统计信息
- * - mz_drug_trac_codg: 药品追溯码表,记录药品追溯码信息
- * - mz_charge_detail: 收费明细表,记录收费项目详细信息
- *
- * 业务流程:
- * 1. 前端退药页面调用 /thmz/refundMedicineProcessing 进行退药处理
- * 2. 退药成功后调用此接口上报医保系统
- * 3. 医保系统记录关联字段,便于后续查询和审计
- * 4. 可通过关联字段查询具体的退药记录和追溯码信息
- *
- * 必填参数:
- * - selRetnOpterName: 销售/退货经办人姓名(字符型,50位)
- * - drugtracinfo: 溯源码节点信息,包含药品追溯码
- *
- * @param selinfoReturn 医保退货信息对象,包含关联字段和药品追溯码信息
- * @return ResultVo 医保接口调用结果
- */
- public ResultVo returnGoodsItem(SelinfoReturn selinfoReturn) {
- ResultVo response = null;
- List<DrugTracCodg> drugTracCodgList = selinfoReturn.getDrugtracinfo();
- if(drugTracCodgList == null || drugTracCodgList.size() == 0) {
- response = new ResultVo(-1, "追溯码不能为空");
- return response;
- }
-
- // 记录关联字段信息(用于关联退药记录)
- // 这些字段用于后续查询退药记录,确保医保记录与退药记录的一一对应
- log.info("医保退药接口调用 - 关联字段: patientId={}, times={}, receiptNo={}, orderNo={}, chargeItemCode={}, realNo={}",
- selinfoReturn.getPatientId(), selinfoReturn.getTimes(), selinfoReturn.getReceiptNo(),
- selinfoReturn.getOrderNo(), selinfoReturn.getChargeItemCode(), selinfoReturn.getRealNo());
- // 构建关联键(用于后续查询退药记录)
- // 关联键格式:patientId=xxx×=xxx&receiptNo=xxx&orderNo=xxx&chargeItemCode=xxx&realNo=xxx
- // 用途:用于日志记录和后续查询退药记录,确保医保记录与退药记录的可追溯性
- // 查询接口:/thmz/getDispensingRecordByAssociation 可通过此关联键查询具体的退药记录
- String associationKey = String.format("patientId=%s×=%s&receiptNo=%s&orderNo=%s&chargeItemCode=%s&realNo=%s",
- selinfoReturn.getPatientId(), selinfoReturn.getTimes(), selinfoReturn.getReceiptNo(),
- selinfoReturn.getOrderNo(), selinfoReturn.getChargeItemCode(), selinfoReturn.getRealNo());
- log.info("医保退药接口 - 关联键: {}", associationKey);
- // 处理追溯码信息(如果有的话)
- /*if(drugTracCodgList != null && !drugTracCodgList.isEmpty()) {
- String drugTracCodg = drugTracCodgList.get(0).getDrugTracCodg();
- String result = taobaoService.sendGet("/queryCodeDetail?codes=" + drugTracCodg);
- JSONObject resultJson = JSONObject.parseObject(result);
- Integer code = resultJson.getInteger("code");
- if (code == 200) {
- JSONObject data = resultJson.getJSONObject("data");
- Integer dataCode = data.getInteger("code");
- if (dataCode == 0) {
- JSONArray content = data.getJSONArray("data");
- if(content != null && content.size() > 0) {
- JSONObject item = content.getJSONObject(0);
- JSONArray produceInfoList = item.getJSONObject("codeProduceInfoDTO").getJSONArray("produceInfoList");
- if(produceInfoList != null && produceInfoList.size() > 0) {
- JSONObject produceInfo = produceInfoList.getJSONObject(0);
- selinfoReturn.setManuLotnum(produceInfo.getString("batchNo"));
- selinfoReturn.setManuDate(produceInfo.getString("produceDateStr"));
- }
- }
- }
- }
- } else {
- log.warn("退药操作没有追溯码信息,继续处理");
- }*/
- List<SelinfoSold> selinfoSoldList =
- selinfoSoldMapper.getSelinfoSoldList(selinfoReturn.getPatientId(), selinfoReturn.getTimes(),
- selinfoReturn.getOrderNo(), selinfoReturn.getChargeItemCode(), selinfoReturn.getRealNo());
- if(selinfoSoldList == null || selinfoSoldList.size() == 0) {
- response = new ResultVo(-1, "关联追溯码上传失败");
- return response;
- }
- SelinfoSold selinfoSold = selinfoSoldList.get(0);
- // selinfoReturn.setSelRetnCnt(drugTracCodgList != null ? drugTracCodgList.size() : 0);
- String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
- selinfoReturn.setMedListCodg(selinfoSold.getMedListCodg());
- selinfoReturn.setSelRetnTime(now);
- selinfoReturn.setMdtrtSn(selinfoSold.getMdtrtSn());
- selinfoReturn.setFixmedinsBchno(selinfoSold.getFixmedinsBchno());
- selinfoReturn.setManuLotnum(selinfoSold.getManuLotnum());
- selinfoReturn.setManuDate(selinfoSold.getManuDate());
- selinfoReturn.setRxFlag(selinfoSold.getRxFlag());
- selinfoReturn.setTrdnFlag(selinfoSold.getTrdnFlag());
- selinfoReturn.setSelRetnOpterName(UriEncoder.encode(selinfoReturn.getSelRetnOpterName()));
- String realUrl = siInventoryServiceUrl + "/returnGoodsItem";
- try {
- String jsonString = JSONObject.toJSONString(selinfoReturn, SerializerFeature.WriteNonStringKeyAsString);
- String ybResult = HttpUtil.sendHttpPost(realUrl, jsonString, 8000);
- JSONObject ybResultJson = JSONObject.parseObject(ybResult);
- int responseCode = 0;
- if(ybResultJson.getInteger("code") != 200) {
- responseCode = ybResultJson.getInteger("code");
- }
- response = new ResultVo(responseCode, ybResultJson.getString("message"));
-
- // 记录医保接口调用结果
- // 通过关联键可以快速定位具体的退药记录,便于问题排查和审计
- log.info("医保退药接口调用结果 - 关联键: {}, 结果: {}", associationKey, response);
-
- } catch (Exception e) {
- e.printStackTrace();
- response = new ResultVo(-1, "商品销售撤销失败");
- // 记录错误信息时包含关联键,便于快速定位问题
- log.error("医保退药接口调用失败 - 关联键: {}, 错误: {}", associationKey, e.getMessage());
- }
- return response;
- }
- public ResultVo getGoods(SelinfoSold selinfoSold) {
- ResultVo response = null;
- List<SelinfoSold> selinfoSoldList =
- selinfoSoldMapper.getSelinfoSoldList(selinfoSold.getPatientId(), selinfoSold.getTimes(),
- selinfoSold.getOrderNo(), selinfoSold.getChargeItemCode(), selinfoSold.getRealNo());
- if(selinfoSoldList == null || selinfoSoldList.size() == 0) {
- response = new ResultVo(-1, "关联追溯码上传失败");
- return response;
- }
- List<Object> datas = new ArrayList<>();
- String realUrl = siInventoryServiceUrl + "/selectSalesGoodsItem";
- for(SelinfoSold sold : selinfoSoldList) {
- List<Map<String, String>> selinfoSoldDrugtracById = selinfoSoldMapper.getSelinfoSoldDrugtracById(sold.getId());
- for(Map<String, String> map : selinfoSoldDrugtracById) {
- Map<String, String> param = new HashMap<>();
- param.put("med_list_codg", sold.getMedListCodg());
- param.put("drug_trac_codg", map.get("trac_codg"));
- try {
- String jsonString = JSONObject.toJSONString(param, SerializerFeature.WriteNonStringKeyAsString);
- String ybResult = HttpUtil.sendHttpPost(realUrl, jsonString, 8000);
- JSONObject ybResultJson = JSONObject.parseObject(ybResult);
- int responseCode = 0;
- if(ybResultJson.getInteger("code") != 200) {
- responseCode = ybResultJson.getInteger("code");
- }
- // response = new ResultVo(responseCode, ybResultJson.getString("message"), ybResultJson.get("data"));
- JSONObject data = ybResultJson.getJSONObject("data");
- JSONArray output = data.getJSONArray("output");
- if(output != null && !output.isEmpty()) {
- datas.add(output.get(0));
- }
- // 记录医保接口调用结果
- // 通过关联键可以快速定位具体的退药记录,便于问题排查和审计
- log.info("医保退药接口调用结果 - 结果: {}", response);
- } catch (Exception e) {
- e.printStackTrace();
- response = new ResultVo(-1, "商品销售查询失败");
- // 记录错误信息时包含关联键,便于快速定位问题
- log.error("医保退药接口调用失败 - 错误: {}", e.getMessage());
- }
- }
- }
- response = new ResultVo(0, "查询成功", datas);
- return response;
- }
- public ResultVo getGoodsByCode(Map<String, String> map) {
- ResultVo response = null;
- JSONArray output = null;
- try {
- JSONObject ybResultJson = getGoodsItemByCode(map);
- JSONObject data = ybResultJson.getJSONObject("data");
- if(ybResultJson.getInteger("code") == 200) {
- output = data.getJSONArray("output");
- response = new ResultVo(0, "查询成功", output);
- }
- // 记录医保接口调用结果
- // 通过关联键可以快速定位具体的退药记录,便于问题排查和审计
- log.info("医保查询接口调用结果 - 结果: {}", response);
- } catch (Exception e) {
- e.printStackTrace();
- response = new ResultVo(-1, "商品销售查询失败");
- // 记录错误信息时包含关联键,便于快速定位问题
- log.error("医保查询接口调用失败 - 错误: {}", e.getMessage());
- }
- return response;
- }
- public JSONObject getGoodsItemByCode(Map<String, String> map) throws Exception {
- String realUrl = siInventoryServiceUrl + "/selectSalesGoodsItem";
- String jsonString = JSONObject.toJSONString(map, SerializerFeature.WriteNonStringKeyAsString);
- String ybResult = HttpUtil.sendHttpPost(realUrl, jsonString, 8000);
- return JSONObject.parseObject(ybResult);
- }
- public ResultVo getErrorCodes() {
- List<Map<String, String>> errors = new ArrayList<>();
- List<Map<String, String>> selinfoSoldDrugtracList = selinfoSoldMapper.getSelinfoSoldDrugtracById(null);
- for(Map<String, String> drug : selinfoSoldDrugtracList) {
- Map<String, String> param = new HashMap<>();
- param.put("med_list_codg", drug.get("med_list_codg"));
- param.put("trac_codg", drug.get("trac_codg"));
- try {
- JSONObject result = getGoodsItemByCode(param);
- JSONObject data = result.getJSONObject("data");
- if(result.getInteger("code") == 200) {
- JSONArray output = data.getJSONArray("output");
- if(output == null || output.isEmpty()) {
- errors.add(drug);
- }
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- return new ResultVo(0, "查询成功", errors);
- }
- }
|