From 1fad0578c97abbb7fc30f59eb1de0f23f08ddde1 Mon Sep 17 00:00:00 2001
From: zhangmei <645025773@qq.com>
Date: 星期四, 27 三月 2025 15:21:15 +0800
Subject: [PATCH] 流水、开票营业部权限

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java |  386 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 379 insertions(+), 7 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java
index 8aa5914..b45ecd7 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java
@@ -1,7 +1,24 @@
 package com.ruoyi.web.controller.api;
 
-import com.taxi591.bankapi.dto.CovertPayBackResult;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.ruoyi.common.constant.AmountConstant;
+import com.ruoyi.common.enums.BillTypeEnum;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.system.dto.TBillDto;
+import com.ruoyi.system.model.TOrderBill;
+import com.ruoyi.system.model.TPayOrder;
+import com.ruoyi.system.service.TBillService;
+import com.ruoyi.system.service.TOrderBillService;
+import com.ruoyi.system.service.TPayOrderService;
+import com.taxi591.bankapi.dto.*;
 import com.taxi591.bankapi.service.BankService;
+import com.taxi591.bankapi.service.SignatureAndVerification;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.binary.Base64;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -9,25 +26,380 @@
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 @RestController
 @RequestMapping("open/bank")
+@Slf4j
 public class BankOutController {
 
     @Autowired
     BankService bankService;
 
+    @Autowired
+    TBillService tBillService;
 
-    @PostMapping(value = "payCallback")
-    public @ResponseBody String payCallback(HttpServletRequest request){
-        CovertPayBackResult result = bankService.covertPayCallBack(request, (billRequest) -> {
+    @Autowired
+    SignatureAndVerification signatureAndVerification;
 
-            return true;
-        });
-        return result.getBack();
+    @Autowired
+    TOrderBillService orderBillService;
+
+    @Autowired
+    TPayOrderService payOrderService;
+
+    public static String getRequestBody(HttpServletRequest request)
+            throws IOException {
+        /** 读取httpbody内容 */
+        StringBuilder httpBody = new StringBuilder();
+        BufferedReader br = null;
+        try {
+            br = new BufferedReader(new InputStreamReader(
+                    request.getInputStream()));
+            String line = null;
+            while ((line = br.readLine()) != null) {
+                httpBody.append(line);
+            }
+        } catch (IOException ex) {
+            throw ex;
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException ex) {
+                    ex.printStackTrace();
+                }
+            }
+        }
+        return httpBody.toString();
     }
 
+    @PostMapping(value = "payCallback")
+    public void payCallback(HttpServletRequest servletRequest,HttpServletResponse servletResponse){
+        String request = null;
+        String responseJson = null;
+        try {
+            log.info("--------进入getRequest4Sale----------------------------------");
+            // 接收报文
+            String requestContent = getRequestBody(servletRequest).trim();
+            String signatureString = requestContent.substring(0,
+                    requestContent.indexOf("||"));
+            log.info("-----ChargeBillController------------截取报文的signatureString:{}", signatureString);
+            String requestBody = requestContent.substring(signatureString
+                    .length() + 2);
+            log.info("-----ChargeBillController------------截取报文的requestBody:{}", requestBody);
+            //如果有双引号,则截取双引号内requestBody的内容
+            Pattern p=Pattern.compile("\"");
+            Matcher m=p.matcher(requestBody);
+            while(m.find()){
+                requestBody=requestBody.replace(m.group(), "");
+                log.info("-----ChargeBillController------如果有双引号,则截取后的requestBody:{}", requestBody);
+            }
+            //requestBody是base64加密后的数据,需解析出来
+            request = new String(
+                    com.alibaba.fastjson.util.Base64.decodeFast(requestBody));
+            log.info("-----ChargeBillController------------解析完成后的requestBody-------{}" + request);
+            ChargeBillRequest chargeBillRequest = JSON.parseObject(request,
+                    new TypeReference<ChargeBillRequest>() {
+                    });
+            boolean b = signatureAndVerification.read_cer_and_verify_sign(requestBody,
+                    signatureString);
+            if (!b){
+                throw new ServiceException("验签失败");
+            }
+            /** 销账报文重发次数,通过resendTimes此字段识别销账报文是否为重发的,0表示首次、1表示重发一次,2表示重发2次,最多重发3次*/
+            if(chargeBillRequest!=null && "0".equals(chargeBillRequest.getMessage().getInfo().getResendTimes())){
+                ChargeBillResponse chargeBillResponse = new ChargeBillResponse(
+                        chargeBillRequest);
+                ChargeBillResponse.Message respMessage = chargeBillResponse
+                        .getMessage();
+                ChargeBillResponse.Message.Head respHead = chargeBillResponse
+                        .getMessage().getHead();
+                ChargeBillResponse.Message.Info respInfo = chargeBillResponse
+                        .getMessage().getInfo();
+                respHead.setTransFlag("02");
+                respHead.setTimeStamp(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS"));
+                // respHead.setChannel("MBNK");
+                respHead.setChannel(chargeBillRequest.getMessage().getHead()
+                        .getChannel());
+                // respHead.setTranCode("chargeBill");
+                respHead.setTransCode(chargeBillRequest.getMessage().getHead()
+                        .getTransCode());
+                respHead.setTransSeqNum(chargeBillRequest.getMessage().getHead()
+                        .getTransSeqNum());
+                //测试销账返回报文中,本来是销账成功的报文,但是不要送0000成功码   (JF190510134746710555这个流水号是在Demo的returnCode设置成null的时候产生的,流水状态为6;)
 
+                String epayCode = chargeBillRequest.getMessage().getInfo()
+                        .getEpayCode();
+                String traceNo = chargeBillRequest.getMessage().getInfo()
+                        .getTraceNo();
+                String numOpenMerchantOrder = chargeBillRequest.getMessage()
+                        .getInfo().getNumOpenMerchantOrder();
+                respInfo.setNumOpenMerchantOrder(numOpenMerchantOrder);
+                respInfo.setEpayCode(epayCode);
+                respInfo.setTraceNo(traceNo);
+
+                try{
+                    tBillService.completePay(chargeBillRequest);
+                    respHead.setReturnCode("0000");
+                    respHead.setReturnMessage("账单缴费成功");
+                }catch (Exception e){
+                    respHead.setReturnCode("1111");
+                    respHead.setReturnMessage("账单处理失败");
+                    log.error("支付第一次回调出现异常,{}",request,e);
+                }
+                //第一次处理失败,不退款
+                respInfo.setRefundFlag("false");
+                respMessage.setInfo(respInfo);
+                respMessage.setHead(respHead);
+                chargeBillResponse.setMessage(respMessage);
+                responseJson = JSON.toJSONString(chargeBillResponse);
+                //加签名
+                String signatrue = signatureAndVerification
+                        .signWhithsha1withrsa(responseJson);
+                log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密前):" + responseJson);
+                responseJson = signatrue + "||"
+                        + new String(Base64.encodeBase64(responseJson.getBytes("utf-8")));
+                log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密后):" + responseJson);
+                servletResponse.setCharacterEncoding("utf-8");
+                servletResponse.setContentType("text/plain");
+                servletResponse.getWriter().write(responseJson);
+            }else{
+                //销账报文重发次数,通过resendTimes此字段识别销账报文是否为重发的,0表示首次、1表示重发一次,2表示重发2次,最多重发3次
+                //商户端要注意销账重复通知的情况,要进行订单唯一性处理
+
+
+                ChargeBillResponse chargeBillResponse = new ChargeBillResponse(
+                        chargeBillRequest);
+                ChargeBillResponse.Message respMessage = chargeBillResponse
+                        .getMessage();
+                ChargeBillResponse.Message.Head respHead = chargeBillResponse
+                        .getMessage().getHead();
+                ChargeBillResponse.Message.Info respInfo = chargeBillResponse
+                        .getMessage().getInfo();
+                respHead.setTransFlag("02");
+                respHead.setTimeStamp(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS"));
+                // respHead.setChannel("MBNK");
+                respHead.setChannel(chargeBillRequest.getMessage().getHead()
+                        .getChannel());
+                // respHead.setTranCode("chargeBill");
+                respHead.setTransCode(chargeBillRequest.getMessage().getHead()
+                        .getTransCode());
+                respHead.setTransSeqNum(chargeBillRequest.getMessage().getHead()
+                        .getTransSeqNum());
+                try{
+                    tBillService.completePay(chargeBillRequest);
+                    respHead.setReturnCode("0000");
+                    respHead.setReturnMessage("账单缴费成功");
+                }catch (Exception e){
+                    respHead.setReturnCode("1111");
+                    respHead.setReturnMessage("账单处理失败");
+                    log.error("支付第一次回调出现异常,{}",request,e);
+                }
+                // 再次推送未处理成功,则返回退款标志
+                if (!"0000".equals(respHead.getReturnCode())) {
+                    respInfo.setRefundFlag("true");
+                }
+                String epayCode = chargeBillRequest.getMessage().getInfo()
+                        .getEpayCode();
+                String traceNo = chargeBillRequest.getMessage().getInfo()
+                        .getTraceNo();
+                String numOpenMerchantOrder = chargeBillRequest.getMessage()
+                        .getInfo().getNumOpenMerchantOrder();
+                respInfo.setNumOpenMerchantOrder(numOpenMerchantOrder);
+                respInfo.setEpayCode(epayCode);
+                respInfo.setTraceNo(traceNo);
+
+                respMessage.setInfo(respInfo);
+                respMessage.setHead(respHead);
+                chargeBillResponse.setMessage(respMessage);
+                responseJson = JSON.toJSONString(chargeBillResponse);
+                //加签名
+                String signatrue = signatureAndVerification
+                        .signWhithsha1withrsa(responseJson);
+                log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密前):" + responseJson);
+                responseJson = signatrue + "||"
+                        + new String(Base64.encodeBase64(responseJson.getBytes("utf-8")));
+                log.info("-----ChargeBillController------------responseJson打印结果是(responseJson加密后):" + responseJson);
+                servletResponse.setCharacterEncoding("utf-8");
+                servletResponse.setContentType("text/plain");
+                servletResponse.getWriter().write(responseJson);
+
+            }
+
+        }catch (Exception e) {
+            log.error("处理支付回调发生异常:返回内容:{}",request,e);
+        }
+    }
+
+    @PostMapping(value = "queryBill")
+    public void bills(HttpServletRequest request, HttpServletResponse httpServletResponse){
+        log.info("进入QueryBillController账单查询接口--------(金额规则为0的)-------");
+
+        String responseJson = null;
+        try {
+            //接收报文request返回截取并返回requestBody和使用base64解析后的requestBody
+            Map<String, String> requestMap = signatureAndVerification.requestBodyOfBase64(request);
+            //使用base64解析完成后的requestBody
+            String requestBodyOfDecoded = requestMap.get("requestBodyOfDecoded");
+            //解析前的requestBody
+            String requestBody = requestMap.get("requestBody");
+            //获取缴费中心传送过来的签名
+            String signatureString = requestMap.get("signatureString");
+
+            // 验签
+            boolean flag = signatureAndVerification.read_cer_and_verify_sign(requestBody,
+                    signatureString);
+
+            log.info("【QueryBill:getBill4DirectJoinMerch】缴费中心响应的报文验签结果为:{}" , flag);
+
+            QueryBillRequest queryBillRequest = JSON.parseObject(requestBodyOfDecoded,
+                    new TypeReference<QueryBillRequest>() {
+                    });
+            //交易编号
+            String traceNo = queryBillRequest.getMessage().getInfo()
+                    .getTraceNo();
+            //返回给缴费中心的响应
+            QueryBillResponse response = new QueryBillResponse(queryBillRequest);
+            QueryBillResponse.Message respMessage = response.getMessage();
+            QueryBillResponse.Message.Head respHead = response.getMessage()
+                    .getHead();
+            QueryBillResponse.Message.Info respInfo = response.getMessage()
+                    .getInfo();
+            //缴费账单子账单
+            ArrayList<QueryBillResponse.Message.Info.Bill> respBills = new ArrayList<QueryBillResponse.Message.Info.Bill>();
+//            ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail> respDescDetail =
+//                    new ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail>();
+            QueryBillResponse.Message.Info.Bill respBill = respInfo.new Bill();
+            //缴费子商户账单
+//            ArrayList<QueryBillResponse.Message.Info.Bill.SplitSubMerInfo> splitSubMerInfos = new ArrayList<QueryBillResponse.Message.Info.Bill.SplitSubMerInfo>();
+
+            //封装返回给缴费中心的响应
+
+            String epayCode = queryBillRequest.getMessage().getInfo()
+                    .getEpayCode();
+            respInfo.setEpayCode(epayCode);
+            String merchantId = queryBillRequest.getMessage().getInfo()
+                    .getMerchantId();
+            respInfo.setMerchantId(merchantId);
+            respInfo.setTraceNo(traceNo);
+            respInfo.setInput1(queryBillRequest.getMessage().getInfo()
+                    .getInput1());
+            respInfo.setInput2(queryBillRequest.getMessage().getInfo()
+                    .getInput2());
+            respInfo.setInput3(queryBillRequest.getMessage().getInfo()
+                    .getInput3());
+            respInfo.setInput4(queryBillRequest.getMessage().getInfo()
+                    .getInput4());
+            respInfo.setInput5(queryBillRequest.getMessage().getInfo()
+                    .getInput5());
+            String orderid= queryBillRequest.getMessage().getInfo().getInput1();
+            if (StringUtils.isEmpty(orderid)){
+                respHead.setReturnCode("0009");
+                respHead.setReturnMessage("参数错误,input1订单号不能为空");
+            }else{
+                if (flag){
+
+                    TPayOrder order = payOrderService.getById(orderid);
+                    List<TOrderBill> orderBills = orderBillService.getByOrderNo(orderid);
+                    List<TBillDto> bills = orderBills.stream().map(ob
+                            -> tBillService.getDetailByBillId(ob.getBillId())).collect(Collectors.toList());
+                    respBill.setBillNo(orderid);
+                    List<String> types = bills.stream().map(bill -> BillTypeEnum.getByCode(Integer.parseInt(bill.getBillType())).getName()).distinct().collect(Collectors.toList());
+//	        封装详细账单信息
+                    respBill.setBillName("缴费:"+CollectionUtil.join(types,","));
+                    respBill.setOweAmt(BigDecimal.valueOf(order.getAmount()).divide(AmountConstant.b100,2, RoundingMode.HALF_DOWN).toPlainString());
+                    respBills.add(respBill);
+                    respInfo.setCustName(order.getUserName());
+                    respInfo.setCustAddress("");
+                    respInfo.setCacheMem("");
+                    respInfo.setRemark("");
+                    respInfo.setCallBackText("西藏国资委");
+                    //respInfo.setCallBackUrl("https://abcsr.keepfx.cn/b/ejy/payResult/");
+                    //使用base64加密信息
+//                    respInfo.setCallBackUrl("aHR0cDp3d3cuYWJjaGluYS5jb20vY24v");
+                    //金额规则字段
+                    String amtRule = "0";
+                    respInfo.setAmtRule(amtRule);
+	            /*QueryBillResponse.Message.Info.Bill.UnitDetail unitDetail = respBill.new UnitDetail(
+	                    "unitName", "6.66", "1");*/
+                    //欠费金额
+                    respBill.setFeeAmt("0.00");
+//
+//                    QueryBillResponse.Message.Info.Bill.DescDetail descDtail1 = respBill.new DescDetail(
+//                            "缴费月份:", "2020年6月份");
+//                    QueryBillResponse.Message.Info.Bill.DescDetail descDtail2 = respBill.new DescDetail(
+//                            "供电局编号:", "4340152");
+//                    QueryBillResponse.Message.Info.Bill.DescDetail descDtail3 = respBill.new DescDetail(
+//                            "欠费金额:", "0.00元");
+//                    QueryBillResponse.Message.Info.Bill.DescDetail descDtail4 = respBill.new DescDetail(
+//                            "缴费月份:", "2020年6月份");
+//                    QueryBillResponse.Message.Info.Bill.DescDetail descDtail5 = respBill.new DescDetail(
+//                            "服务时间:", "每天0:30-23:30期间均可缴费");
+//                    QueryBillResponse.Message.Info.Bill.DescDetail descDtail6 = respBill.new DescDetail(
+//                            "温馨提示:", "北京电力电费代缴,咨询电话:95598 该用户为:预付费用户");
+//                    respDescDetail.add(descDtail1);
+//                    respDescDetail.add(descDtail2);
+//                    respDescDetail.add(descDtail3);
+//                    respDescDetail.add(descDtail4);
+//                    respDescDetail.add(descDtail5);
+//                    respDescDetail.add(descDtail6);
+
+//                    respBill.setRcvMerchantId("103881104410001");
+
+//	          商户子商户详细信息
+//                    QueryBillResponse.Message.Info.Bill.SplitSubMerInfo splitSubMerInfo1 =respBill.new SplitSubMerInfo("10388", "0.01");
+//                    QueryBillResponse.Message.Info.Bill.SplitSubMerInfo splitSubMerInfo2 =respBill.new SplitSubMerInfo("1038819201", "0.02");
+//                    splitSubMerInfos.add(splitSubMerInfo1);
+//                    splitSubMerInfos.add(splitSubMerInfo2);
+
+//                    respBill.setSplitSubMerInfos(splitSubMerInfos);
+//                    respBill.setDescDetails(respDescDetail);
+                    respInfo.setTotalBillCount(String.valueOf(respBills.size()));
+                    respInfo.setBill(respBills);
+
+                    // 有定制电子回单附言信息的,需添加自定义定制附言信息字段
+                    respInfo.setMerchantRemark("");
+                    respHead.setReturnCode("0000");
+                    respHead.setReturnMessage("账单查询成功,返回成功标志");
+                }else {
+                    respHead.setReturnCode("0009");
+                    respHead.setReturnMessage("缴费中心传送给商户的请求报文签名验签失败!");
+                }
+            }
+
+            respHead.setTransFlag("02");
+            respHead.setTimeStamp(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS"));
+
+            respMessage.setInfo(respInfo);
+            respMessage.setHead(respHead);
+            response.setMessage(respMessage);
+            responseJson = JSON.toJSONString(response);
+            // 加签名
+            String signatrue = signatureAndVerification
+                    .signWhithsha1withrsa(responseJson);
+            log.info("signatrue" + responseJson);
+            log.info("responseJson打印结果是(responseJson加密前):" + responseJson);
+            responseJson = signatrue + "||"
+                    + new String(Base64.encodeBase64(responseJson.getBytes("utf-8")));
+            log.info("responseJson打印结果是(responseJson加密后):{}", responseJson);
+            httpServletResponse.setCharacterEncoding("utf-8");
+            httpServletResponse.setContentType("text/plain");
+            httpServletResponse.getWriter().write(responseJson);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
 
 
 }

--
Gitblit v1.7.1