LIJU 2 mesiacov pred
rodič
commit
ef90fa1a24

+ 59 - 0
src/main/java/cn/hnthyy/thmz/entity/yb/SelinfoReturn.java

@@ -160,4 +160,63 @@ public class SelinfoReturn {
     @JSONField(name = "drugtracinfo")
     private List<DrugTracCodg> drugtracinfo;
 
+    /**
+     * 关联字段 - 病人ID(用于关联退药记录)
+     * 数据来源:mz_charge_detail.patient_id 表
+     * 关联用途:与退药统计表 yp_mz_fytj 和追溯码表 mz_drug_trac_codg 进行关联查询
+     * 调用接口:/thmz/getDispensingRecordByAssociation - 通过此字段查询退药记录
+     * 业务意义:唯一标识患者,确保退药记录与医保记录的一一对应
+     * */
+    @JSONField(name = "patient_id")
+    private String patientId;
+    
+    /**
+     * 关联字段 - 就诊次数(用于关联退药记录)
+     * 数据来源:mz_charge_detail.times 表
+     * 关联用途:与退药统计表 yp_mz_fytj 和追溯码表 mz_drug_trac_codg 进行关联查询
+     * 调用接口:/thmz/getDispensingRecordByAssociation - 通过此字段查询退药记录
+     * 业务意义:区分同一患者的不同就诊记录,确保数据准确性
+     * */
+    @JSONField(name = "times")
+    private Integer times;
+    
+    /**
+     * 关联字段 - 发票分票号(用于关联退药记录)
+     * 数据来源:mz_charge_detail.receipt_no 表
+     * 关联用途:与退药统计表 yp_mz_fytj 和追溯码表 mz_drug_trac_codg 进行关联查询
+     * 调用接口:/thmz/getDispensingRecordByAssociation - 通过此字段查询退药记录
+     * 业务意义:标识具体的发票分票,支持多张发票的区分
+     * */
+    @JSONField(name = "receipt_no")
+    private Integer receiptNo;
+    
+    /**
+     * 关联字段 - 处方号(用于关联退药记录)
+     * 数据来源:mz_charge_detail.order_no 表
+     * 关联用途:与退药统计表 yp_mz_fytj 和追溯码表 mz_drug_trac_codg 进行关联查询
+     * 调用接口:/thmz/getDispensingRecordByAssociation - 通过此字段查询退药记录
+     * 业务意义:标识具体的处方,支持同一患者多张处方的区分
+     * */
+    @JSONField(name = "order_no")
+    private Integer orderNo;
+    
+    /**
+     * 关联字段 - 收费项目编码(用于关联退药记录)
+     * 数据来源:mz_charge_detail.charge_item_code 表
+     * 关联用途:与退药统计表 yp_mz_fytj 和追溯码表 mz_drug_trac_codg 进行关联查询
+     * 调用接口:/thmz/getDispensingRecordByAssociation - 通过此字段查询退药记录
+     * 业务意义:标识具体的药品或服务项目,确保退药记录与收费项目的对应关系
+     * */
+    @JSONField(name = "charge_item_code")
+    private String chargeItemCode;
+    
+    /**
+     * 关联字段 - 流水号(用于关联退药记录)
+     * 数据来源:mz_charge_detail.real_no 表
+     * 关联用途:与退药统计表 yp_mz_fytj 和追溯码表 mz_drug_trac_codg 进行关联查询
+     * 调用接口:/thmz/getDispensingRecordByAssociation - 通过此字段查询退药记录
+     * 业务意义:系统内部唯一流水号,确保每条记录的绝对唯一性
+     * */
+    @JSONField(name = "real_no")
+    private Integer realNo;
 }

+ 79 - 21
src/main/java/cn/hnthyy/thmz/service/yb/YbService.java

@@ -151,34 +151,85 @@ public class YbService {
         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.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");
-                    if(produceInfoList != null && produceInfoList.size() > 0) {
-                        JSONObject produceInfo = produceInfoList.getJSONObject(0);
-                        selinfoReturn.setManuLotnum(produceInfo.getString("batchNo"));
-                        selinfoReturn.setManuDate(produceInfo.getString("produceDateStr"));
+        
+        // 记录关联字段信息(用于关联退药记录)
+        // 这些字段用于后续查询退药记录,确保医保记录与退药记录的一一对应
+        log.info("医保退药接口调用 - 关联字段: patientId={}, times={}, receiptNo={}, orderNo={}, chargeItemCode={}, realNo={}", 
+                selinfoReturn.getPatientId(), selinfoReturn.getTimes(), selinfoReturn.getReceiptNo(), 
+                selinfoReturn.getOrderNo(), selinfoReturn.getChargeItemCode(), selinfoReturn.getRealNo());
+
+        // 构建关联键(用于后续查询退药记录)
+        // 关联键格式:patientId=xxx&times=xxx&receiptNo=xxx&orderNo=xxx&chargeItemCode=xxx&realNo=xxx
+        // 用途:用于日志记录和后续查询退药记录,确保医保记录与退药记录的可追溯性
+        // 查询接口:/thmz/getDispensingRecordByAssociation 可通过此关联键查询具体的退药记录
+        String associationKey = String.format("patientId=%s&times=%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("退药操作没有追溯码信息,继续处理");
         }
-        selinfoReturn.setSelRetnCnt(drugTracCodgList.size());
+        
+        selinfoReturn.setSelRetnCnt(drugTracCodgList != null ? drugTracCodgList.size() : 0);
         String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
         selinfoReturn.setSelRetnTime(now);
         selinfoReturn.setMdtrtSn("MDTRT_ID");
@@ -193,9 +244,16 @@ public class YbService {
                 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;

+ 175 - 0
src/main/resources/static/js/mz/west_pharmacy_send.js

@@ -1855,18 +1855,55 @@ function saveRefundMedicine() {
         headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
         data: JSON.stringify(datas),
         success: function (res) {
+            // ========== 调试日志:AJAX成功响应 ==========
+            console.log('=== AJAX成功响应 ===');
+            console.log('响应状态: 成功');
+            console.log('响应数据:', res);
+            
             $("#btn_ty").attr("disabled", false);
             if (res == '401' || res == 401) {
+                console.error('认证失败,跳转到登录页面');
                 window.location.href = '/thmz/login/view'
                 return;
             }
             if (res.code == 0) {
+                console.log('退药处理成功');
                 successMesage(res);
+                
+                // ========== 调用退药医保接口 ==========
+                console.log('=== 开始调用退药医保接口 ===');
+                // 获取退药记录的基本信息
+                let refundData = $table.bootstrapTable('getData');
+                if (refundData && refundData.length > 0) {
+                    let firstItem = refundData[0];
+                    let patientId = firstItem.patient_id;
+                    let times = firstItem.times;
+                    let receiptNo = firstItem.receipt_no;
+                    let orderNo = firstItem.order_no;
+                    let realNo = firstItem.real_no;
+                    let name = firstItem.name;
+                    
+                    console.log('退药医保接口参数:', {
+                        patientId: patientId,
+                        times: times,
+                        receiptNo: receiptNo,
+                        orderNo: orderNo,
+                        realNo: realNo,
+                        name: name
+                    });
+                    
+                    // 调用退药医保接口
+                    callYbReturnGoodsItem(realNo, orderNo, receiptNo, times, patientId, name);
+                } else {
+                    console.warn('没有退药数据,跳过医保接口调用');
+                }
+                
                 // 退药成功后重置匹配状态和全局数据
                 isTyOk = false;
                 window.currentRefundData = null;
                 initTbTable();
             } else {
+                console.error('退药处理失败:', res.message);
                 errorMesage(res);
             }
         },
@@ -3226,4 +3263,142 @@ function callYbSaleGoodsItem(realNo, orderNo, receiptNo, times, patientId, name,
             }
         });
     }
+}
+
+/**
+ * 调用医保商品退货接口
+ * @param realNo 流水号
+ * @param orderNo 处方号
+ * @param receiptNo 发票分票号
+ * @param times 次数
+ * @param patientId 病人ID
+ * @param name 病人姓名
+ */
+function callYbReturnGoodsItem(realNo, orderNo, receiptNo, times, patientId, name) {
+    // 获取退药明细数据
+    let tableData = $("#tb_table").bootstrapTable('getData');
+    
+    if (!tableData || tableData.length === 0) {
+        console.log('没有退药明细数据,跳过医保接口调用');
+        return;
+    }
+    
+    // 获取当前用户信息(药师信息)
+    let currentUserName = localStorage.getItem('userName') || '';
+    let currentUserId = localStorage.getItem('userID') || '';
+    
+    // 获取当前时间
+    let currentTime = new Date();
+    let selRetnTime = currentTime.getFullYear() + '-' + 
+                     String(currentTime.getMonth() + 1).padStart(2, '0') + '-' + 
+                     String(currentTime.getDate()).padStart(2, '0') + ' ' +
+                     String(currentTime.getHours()).padStart(2, '0') + ':' + 
+                     String(currentTime.getMinutes()).padStart(2, '0') + ':' + 
+                     String(currentTime.getSeconds()).padStart(2, '0');
+    
+    // 为每个退药药品调用一次医保接口
+    for (let i = 0; i < tableData.length; i++) {
+        let item = tableData[i];
+        
+        // 只处理有退药数量的药品
+        if (item.dec_amount == 0) {
+            continue;
+        }
+        
+        // 获取医生姓名
+        let doctorName = item.doctor_name || item.name || '';
+        if (!doctorName) {
+            doctorName = '未知医生';
+        }
+        
+        // 构建医保接口参数
+        let ybData = {
+            // 关联字段 - 直接传递到医保接口
+            patientId: patientId,
+            times: times,
+            receiptNo: receiptNo,
+            orderNo: orderNo,
+            chargeItemCode: item.charge_item_code,
+            realNo: realNo,
+            
+            // // 医疗目录编码(医保编码)
+            // medListCodg: item.nationalCode || 'NMLC999',
+            
+            // 销售/退货经办人姓名(必填参数)
+            selRetnOpterName: currentUserName,
+            
+            // // 销售/退货数量
+            // selRetnCnt: item.dec_amount,
+            
+            // // 销售/退货时间
+            // selRetnTime: selRetnTime,
+            
+            // // 最终成交单价
+            // finlTrnsPric: item.unit_price,
+            
+            // // 处方药标志
+            // rxFlag: item.rxFlag || '0',
+            
+            // // 拆零标志(0-否;1-是)
+            // trdnFlag: item.clFlag || '0',
+            
+            // 追溯码信息
+            drugtracinfo: []
+        };
+        
+        // 处理追溯码(从退药匹配表格获取)
+        let tyTable = $('#ty_table_detail').bootstrapTable("getData");
+        if (tyTable && tyTable.length > 0) {
+            // 查找对应的追溯码
+            for (let j = 0; j < tyTable.length; j++) {
+                let tyItem = tyTable[j];
+                if (tyItem.chargeItemCode === item.charge_item_code && 
+                    tyItem.serial === item.serial && 
+                    tyItem.itemNo === item.item_no) {
+                    
+                    if (tyItem.drugTracCodg && tyItem.drugTracCodg.trim() !== '') {
+                        // 提取追溯码(去除HTML标签)
+                        let tracCode = tyItem.drugTracCodg.replace(/<[^>]*>/g, '').trim();
+                        if (tracCode) {
+                            ybData.drugtracinfo.push({
+                                drugTracCodg: tracCode
+                            });
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+        
+        // 如果没有追溯码,添加空数组(保持数据结构一致)
+        if (ybData.drugtracinfo.length === 0) {
+            ybData.drugtracinfo = [];
+        }
+        
+        console.log('调用医保退药接口,药品:', item.drugname, '参数:', ybData);
+        
+        // 调用医保接口
+        $.ajax({
+            type: "POST",
+            url: '/Yb/returnGoodsItem',
+            contentType: "application/json;charset=UTF-8",
+            dataType: "json",
+            headers: {
+                'Accept': 'application/json',
+                'Authorization': 'Bearer ' + localStorage.getItem("token")
+            },
+            data: JSON.stringify(ybData),
+            success: function (res) {
+                console.log('医保退药接口调用成功:', res);
+                if (res.code !== 0) {
+                    console.error('医保退药接口调用失败:', res.message);
+                    // 医保接口失败不影响退药流程,只记录日志
+                }
+            },
+            error: function (xhr, status, error) {
+                console.error('医保退药接口调用失败:', error);
+                // 医保接口失败不影响退药流程,只记录日志
+            }
+        });
+    }
 }