MrShi
2023-12-12 9088209cdd7e3158d2a04caae05e6726ba3b3ad6
Merge branch 'devPartner' of http://139.186.142.91:10010/r/productDev/parkBike into devPartner
已删除9个文件
已修改23个文件
1332 ■■■■■ 文件已修改
admin/src/views/business/wxBill.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/platform/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/platform/src/main/java/com/doumee/task/ScheduleTool.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/platform/src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/pom.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/wx/WxMiniConfig.java 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java 106 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/wx/WxPayProperties.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/wx/pay/WxBillUtil.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/GoodsorderService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/RefundService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java 201 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/RefundServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/WxBillDetailServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/WxBillServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/resources/application-dev.yml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/resources/application-pro.yml 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/resources/application-test.yml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/api/web/PaymentCallback.java 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/config/shiro/ShiroCache.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/config/shiro/ShiroConfig.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/config/shiro/ShiroRealm.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/wxBill.vue
@@ -107,7 +107,6 @@
        startDate: ''
      },
      sumData: {
      },
      pickerOptions: {}
    }
server/platform/pom.xml
@@ -24,7 +24,7 @@
    </dependencies>
    <build>
        <finalName>platform</finalName>
        <finalName>bike_admin_api</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
server/platform/src/main/java/com/doumee/task/ScheduleTool.java
@@ -10,12 +10,10 @@
import com.doumee.core.wx.WxPayProperties;
import com.doumee.dao.business.model.Goodsorder;
import com.doumee.dao.system.model.SystemDictData;
import com.doumee.service.business.GoodsorderService;
import com.doumee.service.business.MemberRidesService;
import com.doumee.service.business.SitesService;
import com.doumee.service.business.WxBillService;
import com.doumee.service.business.*;
import com.doumee.service.system.SystemDictDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
@@ -41,6 +39,8 @@
    @Autowired
    private SystemDictDataBiz systemDictDataBiz;
    @Autowired
    private RefundService refundService;
    @Autowired
    private SystemDictDataService systemDictDataService;
@@ -115,6 +115,11 @@
        ThreadContext.bind(manager);
        String appId = wxPayProperties.getAppId();
        String appSecret = wxPayProperties.getAppSecret();
        if(wxPayProperties.getExistsSub() ==1){
            //如果是服务商支付,取子商户信息
             appId = StringUtils.trimToNull(wxPayProperties.getSubMchId());
            appSecret =StringUtils.trimToNull(wxPayProperties.getSubAppSecret());
        }
        //生成微信token
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
        String response = HttpsUtil.doGet(url,null);
@@ -126,6 +131,15 @@
            systemDictDataService.updateById(systemDictData);
        }
    }
    /**
     * æ›´æ–°å¾®ä¿¡ ACCESS_TOKEN
     */
    @Scheduled(fixedDelay = 1000L * 60L )
    public void autoCancelRefunOrder(){
        log.info("=====================开始 è‡ªå‹•取消未推送退款状态的退款单状态=======================");
        refundService.autoCancelRefunOrder();;
        log.info("=====================结束 è‡ªå‹•取消未推送退款状态的退款单状态=======================");
    }
}
server/platform/src/main/resources/application.yml
@@ -61,5 +61,5 @@
  port: 10026
mqtt:
  clientid: doumeetestplat
  subclientid: doumeetestplatSub
  clientid: doumeeplat
  subclientid: doumeeplatSub
server/pom.xml
@@ -41,9 +41,7 @@
    <jjwt.version>0.9.1</jjwt.version>
    <!-- hutool å·¥å…·ç›¸å…³-->
    <hutool.version>5.5.8</hutool.version>
    <!-- å¾®ä¿¡å°ç¨‹åº -->
    <weixin-java-miniapp.version>4.1.0</weixin-java-miniapp.version>
    <!-- å¾®ä¿¡æ”¯ä»˜ -->
    <weixin-java-pay.version>4.1.0</weixin-java-pay.version>
  </properties>
@@ -272,10 +270,10 @@
    <dependency>
      <groupId>com.github.binarywang</groupId>
      <artifactId>weixin-java-miniapp</artifactId>
      <version>${weixin-java-miniapp.version}</version>
      <version>4.1.0</version>
    </dependency>
    <!-- WeChat æ”¯ä»˜ -->
    <dependency>
  <dependency>
      <groupId>com.github.binarywang</groupId>
      <artifactId>weixin-java-pay</artifactId>
      <version>${weixin-java-pay.version}</version>
@@ -283,14 +281,13 @@
    <dependency>
      <groupId>com.github.wechatpay-apiv3</groupId>
      <artifactId>wechatpay-java</artifactId>
      <version>0.2.11</version>
      <version>0.2.12</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.paho</groupId>
      <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
      <version>1.2.2</version>
    </dependency>
  </dependencies>
  <build>
server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java
@@ -28,6 +28,7 @@
    NOT_ALLOWED(5110, "不允许的操作"),
    BE_OVERDUE(5112, "未登录"),
    TOKEN_EXCEED_TIME(5113, "登陆已过期"),
    NO_UNCLOSEED_ORDER(5114, "登陆已过期"),
    ;
    private int code;
server/services/src/main/java/com/doumee/core/wx/WxMiniConfig.java
@@ -3,28 +3,40 @@
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.config.mybatis.SpringUtils;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.billdownload.BillDownloadService;
import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiService;
import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.refund.RefundService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
/**
 * å¾®ä¿¡å°ç¨‹åºç»„ä»¶
 */
@Configuration
@Slf4j
public class WxMiniConfig {
    /********微信小程序服务**********/
    public static WxMaService wxMaService;
    /********微信小程序支付**********/
    public static WxPayService wxPayService;
    public static JsapiService wxPayService;
    public static WxPayService wxPayV2Service;
    public static RefundService refundService;
    public static JsapiServiceExtension jsapiExtService;
    public static BillDownloadService billDownloadService;
    public static WxPayProperties wxProperties;
    @Autowired
    private WxPayProperties wxPayProperties;
@@ -36,37 +48,67 @@
    void init() {
        this.load_WxMaService();
        this.load_wxPayService();
        this.load_wxPayV2Service();
        this.wxProperties = wxPayProperties;
    }
    /**
     * åˆå§‹åŒ–微信小程序
     */
    public void load_WxMaService() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(StringUtils.trimToNull(wxPayProperties.getAppId()));
        config.setSecret(StringUtils.trimToNull(wxPayProperties.getAppSecret()));
        if(wxPayProperties.getExistsSub() ==1){
            //如果是服务商支付,取子商户信息
            config.setAppid(StringUtils.trimToNull(wxPayProperties.getSubAppId()));
            config.setSecret(StringUtils.trimToNull(wxPayProperties.getSubAppSecret()));
        }else {
            config.setAppid(StringUtils.trimToNull(wxPayProperties.getAppId()));
            config.setSecret(StringUtils.trimToNull(wxPayProperties.getAppSecret()));
        }
        config.setMsgDataFormat("JSON");
        //config.setToken("");
        //config.setAesKey("");
        WxMaService wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(config);
        this.wxMaService = wxMaService;
    }
    /**
     * åˆå§‹åŒ–微信小程序支付
     */
    public void load_wxPayService() {
    public void load_wxPayService()
    {
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(wxPayProperties.getMchId())
                        .privateKeyFromPath(wxPayProperties.getPrivateKeyPath())
                        .merchantSerialNumber(wxPayProperties.getSerialNumer())
                        .apiV3Key(wxPayProperties.getApiV3Key())
                        .build();
        this.wxPayService =  new JsapiService.Builder().config(config).build();
        this.jsapiExtService =  new JsapiServiceExtension.Builder().config(config).build();
        this.refundService = new RefundService.Builder().config(config).build();
        this.billDownloadService = new BillDownloadService.Builder().config(config).build();;
    }
    /**
     * åˆå§‹åŒ–微信小程序支付
     */
    public void load_wxPayV2Service()
    {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setTradeType(WxPayConstants.TradeType.JSAPI);
        payConfig.setSignType(WxPayConstants.SignType.MD5);
        payConfig.setAppId(StringUtils.trimToNull(wxPayProperties.getAppId()));
        payConfig.setMchId(StringUtils.trimToNull(wxPayProperties.getMchId()));
        payConfig.setMchKey(StringUtils.trimToNull(wxPayProperties.getMchKey()));
        payConfig.setKeyPath(StringUtils.trimToNull(wxPayProperties.getKeyPath()));
        payConfig.setAppId(StringUtils.trimToNull(wxPayProperties.getSubAppId()));
        payConfig.setMchId(StringUtils.trimToNull(wxPayProperties.getSubMchId()));
        payConfig.setMchKey(StringUtils.trimToNull(wxPayProperties.getSubMchKey()));
//        payConfig.setKeyPath(StringUtils.trimToNull(wxPayProperties.getKeyPath()));
        payConfig.setNotifyUrl(StringUtils.trimToNull(wxPayProperties.getNotifyUrl()));
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        this.wxPayService = wxPayService;
        this.wxPayV2Service = wxPayService;
    }
server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java
@@ -14,28 +14,25 @@
import com.doumee.dao.business.model.Transactions;
import com.doumee.dao.business.web.request.RefundDTO;
import com.doumee.dao.system.model.SystemDictData;
import com.doumee.service.business.RefundService;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import io.netty.handler.codec.base64.Base64Decoder;
import io.netty.handler.codec.base64.Base64Encoder;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.misc.BASE64Decoder;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
 * å¾®ä¿¡å°ç¨‹åº-公共方法
@@ -52,24 +49,73 @@
    @Autowired
    private SystemDictDataBiz systemDictDataBiz;
    @Autowired
    private WxPayProperties wxPayProperties;
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    public Refund wxRefund(RefundDTO refundDTO) {
    public boolean wxRefund(RefundDTO refundDTO) {
        // å‘送退款请求
        Refund refund = new Refund();
        refund.setId(Constants.getUUID());
        refund.setCreateDate(new Date());
        refund.setMemberId(refundDTO.getMemberId());
        refund.setMoney(refundDTO.getRefundAmount());
//        refund.setOnlineOrderid(refNum);
        refund.setPayWay(Constants.ZERO);
        refund.setStatus(Constants.ZERO);
        refund.setDoneDate(new Date());
        refund.setCreator(refundDTO.getCreator());
        refund.setType(refundDTO.getType());
        refund.setObjId(refundDTO.getOrderId());
        refund.setReason(refundDTO.getReason());
        refund.setCanBalance(refundDTO.getCanBalance());
        refundMapper.insert(refund);
        CreateRequest request = new CreateRequest();
        request.setOutTradeNo(refundDTO.getOrderId());
        request.setOutRefundNo(refund.getId());
        request.setSubMchid(WxMiniConfig.wxProperties.getSubMchId());
        request.setNotifyUrl(WxMiniConfig.wxProperties.getRefundNotifyUrl());
        AmountReq amountReq = new AmountReq();
        amountReq.setTotal(refundDTO.getTotalAmount().longValue());
        amountReq.setRefund(refundDTO.getRefundAmount().longValue());
        amountReq.setCurrency("CNY");
        request.setAmount(amountReq);
        try {
            // å‘送退款请求
            String refNum = ID.nextGUID();
            WxPayRefundRequest request = new WxPayRefundRequest();
            request.setOutTradeNo(refundDTO.getOrderId());
            request.setOutRefundNo(refNum);
            request.setTotalFee(refundDTO.getTotalAmount().intValue());
            request.setRefundFee(refundDTO.getRefundAmount().intValue());
            System.out.println("实际总金额" + refundDTO.getTotalAmount());
            System.out.println("实际退款金额" + refundDTO.getRefundAmount());
            com.wechat.pay.java.service.refund.model.Refund response = WxMiniConfig.refundService.create(request);
            if ("SUCCESS".equals(response.getStatus().name())
                    || "PROCESSING".equals(response.getStatus().name()) ) {
                return  true;
            }else{
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,退款申请失败哦!");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,退款申请失败!");
        }
    }
    public Refund wxRefundOld(RefundDTO refundDTO) {
        // å‘送退款请求
        String refNum = ID.nextGUID();
        CreateRequest request = new CreateRequest();
        request.setOutTradeNo(refundDTO.getOrderId());
        request.setOutRefundNo(refNum);
        request.setSubMchid(WxMiniConfig.wxProperties.getSubMchId());
        request.setNotifyUrl(WxMiniConfig.wxProperties.getRefundNotifyUrl());
//
        AmountReq amountReq = new AmountReq();
        amountReq.setTotal(refundDTO.getTotalAmount().longValue());
        amountReq.setRefund(refundDTO.getRefundAmount().longValue());
        amountReq.setCurrency("CNY");
        request.setAmount(amountReq);
        System.out.println("实际总金额" + refundDTO.getTotalAmount());
        System.out.println("实际退款金额" + refundDTO.getRefundAmount());
//            request.setTotalFee(1);
//            request.setRefundFee(1);
            WxPayRefundResult response = WxMiniConfig.wxPayService.refund(request);
            if ("SUCCESS".equals(response.getReturnCode()) && "SUCCESS".equals(response.getResultCode())) {
        try {
            com.wechat.pay.java.service.refund.model.Refund response = WxMiniConfig.refundService.create(request);
            if ("SUCCESS".equals(response.getStatus().name()) ) {
                //存储退款记录 ä¸Ž æµæ°´è®°å½•
                Refund refund = new Refund();
                refund.setId(Constants.getUUID());
@@ -119,12 +165,16 @@
                transactionsMapper.insert(transactions);
                return refund;
            } else{
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),response.getErrCode() + response.getErrCodeDes());
                throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,退款失败!");
            }
        } catch (WxPayException e) {
        }catch (BusinessException e){
            throw e;
        }catch (Exception e){
            e.printStackTrace();
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,退款失败!");
        }
        throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"退款发生异常请联系管理员");
    }
server/services/src/main/java/com/doumee/core/wx/WxPayProperties.java
@@ -19,6 +19,7 @@
     * AppID
     */
    private String appId;
    private String apiV3Key;
    /**
     * AppSecret
@@ -34,15 +35,32 @@
     * æ”¯ä»˜API密钥
     */
    private String mchKey;
    /**
     * æ”¯ä»˜API密钥
     */
    private String subMchKey;
    /**
     * æ”¯ä»˜å›žè°ƒåœ°å€
     */
    private String notifyUrl;
    /**
     * é€€æ¬¾å›žè°ƒåœ°å€
     */
    private String refundNotifyUrl;
    /**
     * æ”¯ä»˜è¯ä¹¦(p12)
     */
    private String keyPath;
    private String serialNumer;
    private int existsSub;// true
    private String subAppId;//wxcd2b89fd2ff065f8
    private String subMchId;// 1229817002
    private String subAppSecret;// 1229817002
    private String typeId;// gybike
    private String privateKeyPath ;
    private String privateCertPath;// gybike
}
server/services/src/main/java/com/doumee/core/wx/pay/WxBillUtil.java
@@ -1,13 +1,9 @@
package com.doumee.core.wx.pay;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.config.WxPayConfig;
import okhttp3.HttpUrl;
import java.io.UnsupportedEncodingException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
@@ -22,7 +18,6 @@
    public static void getBill(){
        // åˆ›å»ºå¾®ä¿¡æ”¯ä»˜API对象
        WxPayConfig config = new WxPayConfig();
//        WxPay wxpay = new WxMaServiceImpl();
//        wxpay.setWxMaConfig(config);
server/services/src/main/java/com/doumee/service/business/GoodsorderService.java
@@ -12,6 +12,7 @@
import com.doumee.dao.business.web.response.HomeResponse;
import com.doumee.dao.business.web.response.GoodsorderDetailDTO;
import com.doumee.dao.business.web.response.RidesDetailResponse;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import java.math.BigDecimal;
import java.util.List;
@@ -144,7 +145,8 @@
     * @param id
     * @return
     */
    void closeGoodsorder(Goodsorder order,int type );
    void closeGoodsorder(Goodsorder  order,int type );
    void closeGoodsorderDone(RefundNotification param);
    void forceCloseGoodsorder(String orderId);
    /**
server/services/src/main/java/com/doumee/service/business/RefundService.java
@@ -4,6 +4,7 @@
import com.doumee.core.model.PageWrap;
import com.doumee.dao.business.model.Refund;
import com.doumee.dao.business.model.RefundPlatExportVO;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import java.util.List;
@@ -100,4 +101,6 @@
    PageData<Refund>  findPlatPage(PageWrap<Refund> pageWrap);
    List<RefundPlatExportVO>  findPlatExportPage(  Refund pageWrap);
    void autoCancelRefunOrder();
}
server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java
@@ -1,5 +1,7 @@
package com.doumee.service.business.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -17,6 +19,7 @@
import com.doumee.core.utils.Utils;
import com.doumee.core.wx.WxMiniConfig;
import com.doumee.core.wx.WxMiniUtilService;
import com.doumee.core.wx.WxPayProperties;
import com.doumee.dao.business.*;
import com.doumee.dao.business.MemberRidesMapper;
import com.doumee.dao.business.join.GoodsorderJoinMapper;
@@ -38,11 +41,11 @@
import com.doumee.service.business.MemberRidesService;
import com.doumee.service.business.PricingRuleService;
import com.doumee.service.business.RefundService;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.*;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.checkerframework.checker.units.qual.A;
@@ -64,8 +67,10 @@
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
@Slf4j
public class GoodsorderServiceImpl implements GoodsorderService {
@@ -475,10 +480,22 @@
        closeGoodsorder(  goodsorder,Constants.REFUND_TYPE.PLAT_FORCE.getKey());
    }
    /**
     * å‘起退款申请
     * @param goodsorder
     * @param type
     */
    @Transactional(rollbackFor = {Exception.class,BusinessException.class})
    @Override
    public void closeGoodsorder( Goodsorder goodsorder ,int type ) {
        Refund r = refundMapper.selectOne(new QueryWrapper<Refund>().lambda()
                .eq(Refund::getObjId,goodsorder.getId())
                .eq(Refund::getIsdeleted,Constants.ZERO)
                .eq(Refund::getStatus,Constants.ZERO)
                .last("limit 1" ));
        if(r != null){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "该订单存在退款申请正在处理中,请稍后查看订单信息哦~");
        }
        List<MemberRides> memberRides = getMemberRidesForClose(goodsorder.getId());
        //默认结算为押金金额
        BigDecimal closeMoney = new BigDecimal(0.00);
@@ -487,6 +504,55 @@
            closeMoney = getCloseMoneyByRides(memberRides,true,goodsorder.getMoney()).getAmount();
            //实际结算价格,记录在最高车型记录上
            memberRides.get(0).setActualPrice(closeMoney);
        }
        int refundMoney =( Constants.formatDecimalNum(goodsorder.getMoney()).subtract(closeMoney)).intValue();//计算价格
        RefundDTO refundDTO = new RefundDTO();
        refundDTO.setOrderId(goodsorder.getId());
        refundDTO.setCanBalance(goodsorder.getMoney());
        refundDTO.setRefundAmount(new BigDecimal(refundMoney));
        refundDTO.setTotalAmount(goodsorder.getMoney());
        refundDTO.setMemberId(goodsorder.getMemberId());
        refundDTO.setReason(Constants.REFUND_TYPE.get(type).getName());
        refundDTO.setCreator(goodsorder.getEditor());
        refundDTO.setType(type);
        wxMiniUtilService.wxRefund(refundDTO);
    }
    /**
     * é€€æ¬¾æˆåŠŸå›žè°ƒ
     */
    @Transactional(rollbackFor = {Exception.class,BusinessException.class})
    @Override
    public void closeGoodsorderDone(RefundNotification param) {
        //查询退款申请订单
        Refund refund = refundMapper.selectById(param.getOutRefundNo());
        if(refund == null
                || Constants.formatIntegerNum(refund.getIsdeleted()) == Constants.ONE
                || Constants.formatIntegerNum(refund.getStatus()) == Constants.TWO){
            return;
        }
        if (!"SUCCESS".equals(param.getRefundStatus().name())) {
            // å¦‚果退款状态不正确,修改退款单状态
            refund.setStatus(Constants.ONE);
            refund.setEditDate(new Date());
            refund.setOnlineOrderid(param.getTransactionId());
            refund.setDoneDate(refund.getEditDate());
            //更新退款单状态
            refundMapper.updateById(refund);
            return;
        }
        refund.setOnlineOrderid(param.getTransactionId());
        doRefundTransactions(refund);
        Goodsorder goodsorder = goodsorderMapper.selectById(refund.getObjId());
        if(goodsorder ==null || Constants.formatIntegerNum(goodsorder.getCloseStatus()) != Constants.ZERO){
            return;
        }
        //进行订单结算业务处理
        List<MemberRides> memberRides = getMemberRidesForClose(refund.getObjId());
        //默认结算为押金金额
        if (!CollectionUtils.isEmpty(memberRides)){
            //骑行总时长
            for(MemberRides model :memberRides){
                MemberRides up = new MemberRides();
                up.setId(model.getId());
@@ -499,12 +565,15 @@
                memberRidesJoinMapper.updateById(up);
            }
        }
        BigDecimal closeMoney =( Constants.formatDecimalNum(goodsorder.getMoney()).subtract(refund.getMoney()));
        //退款乐行
        int type =Constants.formatIntegerNum(refund.getType());
        Goodsorder update = new Goodsorder();
        update.setId(goodsorder.getId());
        update.setStatus(Constants.GOODSORDER_STATUS.CLOSE.getKey());
        update.setCloseMoney(closeMoney);
        update.setCloseDate(new Date());
        update.setCloseInfo(Constants.REFUND_TYPE.get(type).getInfo());
        update.setCloseInfo(Constants.REFUND_TYPE.get(refund.getType()).getInfo());
        update.setCloseUserId(goodsorder.getEditor());
        if(Constants.REFUND_TYPE.PLAT_FORCE.getKey() == type){
            //如果是强制结算
@@ -518,21 +587,7 @@
            //如果是平台自动结算
            update.setCloseType(Constants.TWO);
        }
        int refundMoney =( Constants.formatDecimalNum(goodsorder.getMoney()).subtract(closeMoney)).intValue();//计算价格
        if(refundMoney > 0){
            //如果有退款,申请微信退款,记录退款交易流水
            RefundDTO refundDTO = new RefundDTO();
            refundDTO.setOrderId(goodsorder.getId());
            refundDTO.setCanBalance(goodsorder.getMoney());
            refundDTO.setRefundAmount(new BigDecimal(refundMoney));
            refundDTO.setTotalAmount(goodsorder.getMoney());
            refundDTO.setMemberId(goodsorder.getMemberId());
            refundDTO.setReason(Constants.REFUND_TYPE.get(type).getName());
            refundDTO.setCreator(update.getEditor());
            refundDTO.setType(type);
            Refund refund = wxMiniUtilService.wxRefund(refundDTO);
            update.setCloseId(refund.getId());
        }
        update.setCloseId(refund.getId());
        //存储 æ¶ˆè´¹äº¤æ˜“流水
        Transactions transactions = new Transactions();
        transactions.setId(Constants.getUUID());
@@ -540,7 +595,7 @@
        transactions.setCreateDate(new Date());
        transactions.setIsdeleted(Constants.ZERO);
        transactions.setOrderId(goodsorder.getId());
        transactions.setMoney(goodsorder.getMoney().subtract(new BigDecimal(refundMoney)));
        transactions.setMoney(goodsorder.getMoney().subtract(Constants.formatDecimalNum(refund.getMoney())));
        transactions.setType(Constants.TRANSACTIONS_TYPE.CONSUMPTION.getKey());
        transactions.setDoneDate(new Date());
        transactions.setTitle(Constants.TRANSACTIONS_TYPE.CONSUMPTION.getName());
@@ -551,6 +606,46 @@
        transactionsMapper.insert(transactions);
        //修改订单信息
        goodsorderMapper.updateById(update);
    }
    private void doRefundTransactions(Refund refund ) {
        //存储交易流水表
        refund.setStatus(Constants.TWO);
        refund.setEditDate(new Date());
        refund.setDoneDate(refund.getEditDate());
        //更新退款单状态
        refundMapper.updateById(refund);
        Transactions transactions = new Transactions();
        transactions.setId(Constants.getUUID());
        transactions.setMemberId(refund.getMemberId());
        transactions.setCreateDate(new Date());
        transactions.setIsdeleted(Constants.ZERO);
        transactions.setOrderId(refund.getObjId());
        transactions.setMoney(refund.getMoney());
        transactions.setPreOrderid(refund.getObjId());
        transactions.setOnlineOrderid(refund.getId());
        transactions.setDoneDate(new Date());
        if(refund.getType().equals(Constants.REFUND_TYPE.PLAT_AUTO.getKey())||refund.getType().equals(Constants.REFUND_TYPE.PLAT_FORCE.getKey())){
            //平台自动退款 æˆ– å¼ºåˆ¶é€€æ¬¾
            transactions.setType(Constants.TRANSACTIONS_TYPE.REFUND.getKey());
            transactions.setTitle(Constants.REFUND_TYPE.PLAT_AUTO.getInfo());
            transactions.setContent(Constants.REFUND_TYPE.PLAT_AUTO.getInfo());
        }else if(refund.getType().equals(Constants.REFUND_TYPE.NORMAL.getKey())){
            //用户主动退款
            transactions.setType(Constants.TRANSACTIONS_TYPE.REFUND.getKey());
            transactions.setTitle(Constants.REFUND_TYPE.NORMAL.getInfo());
            transactions.setContent(Constants.REFUND_TYPE.NORMAL.getInfo());
        }else if(refund.getType().equals(Constants.REFUND_TYPE.BACK.getKey())){
            //结算后退款
            transactions.setType(Constants.TRANSACTIONS_TYPE.REFUND.getKey());
            transactions.setTitle(Constants.REFUND_TYPE.BACK.getInfo());
            transactions.setContent(Constants.REFUND_TYPE.BACK.getInfo());
        }
        transactions.setBalance(BigDecimal.ZERO);
        transactions.setObjId(refund.getId());
        transactions.setObjType(Constants.ONE);
        transactionsMapper.insert(transactions);
    }
    private RidesDetailResponse    getCloseMoneyByRides(List<MemberRides> memberRides,boolean isClose,BigDecimal yjMoney) {
@@ -638,7 +733,8 @@
            refundDTO.setCreator(principal.getId());
            refundDTO.setReason(reason);
            refundDTO.setType(Constants.REFUND_TYPE.BACK.getKey());
            Refund refund = wxMiniUtilService.wxRefund(refundDTO);
            //发起退款申请
            wxMiniUtilService.wxRefund(refundDTO);
        }else {
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,退款金额不允许超过"+canBalance+"元");
        }
@@ -827,23 +923,43 @@
        goodsorder.setPayWay(Constants.ZERO);
        this.goodsorderMapper.insert(goodsorder);
        //调起支付
        Object response = null;
        try {
            Object response = null;
            WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
            request.setBody("骑行押金");
            request.setAttach("createGoodsOrder");
            request.setOutTradeNo(goodsorder.getId());
            request.setTotalFee(goodsorder.getMoney().intValue());
            request.setSpbillCreateIp(this.getIpAddr());
            request.setTimeStart(DateUtil.DateToString(new Date(), "yyyyMMddHHmmss"));
            request.setOpenid(member.getOpenid());
            response = WxMiniConfig.wxPayService.createOrder(request);
            return response;
        } catch (WxPayException e) {
            e.printStackTrace();
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),e.getMessage());
            response = getWxPayResponse(goodsorder,member.getOpenid());
        }  catch (Exception e) {
            throw new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"对不起,发起支付失败~");
        }
        return response;
    }
    private Object getWxPayResponse(Goodsorder goodsorder,String openid) throws Exception {
        //调起支付
            Object response = null;
        PrepayRequest request = new PrepayRequest();
        request.setAttach("createGoodsOrder");
        request.setDescription("森林公园自行车骑行押金支付");
        request.setSpMchid(WxMiniConfig.wxProperties.getMchId());
        request.setSpAppid(WxMiniConfig.wxProperties.getAppId());
        request.setSubMchid(WxMiniConfig.wxProperties.getSubMchId());
        request.setSubAppid(WxMiniConfig.wxProperties.getSubAppId());
        Payer payer = new Payer();
        payer.setSubOpenid(openid);
        request.setPayer(payer);
        request.setOutTradeNo(goodsorder.getId());
        request.setNotifyUrl(WxMiniConfig.wxProperties.getNotifyUrl());//这个回调url必须是https开头的
        Amount amount = new Amount();
        amount.setTotal(goodsorder.getMoney().intValue());
        request.setAmount(amount);
//        PrepayResponse res = WxMiniConfig.wxPayService.prepay(request);
            // è·Ÿä¹‹å‰ä¸‹å•示例一样,填充预下单参数
        PrepayWithRequestPaymentResponse resParam =  WxMiniConfig.jsapiExtService.prepayWithRequestPayment(request,WxMiniConfig.wxProperties.getSubAppId());
        response =resParam;
        return response;
    }
    /**
     * éªŒè¯è¥ä¸šæ—¶é—´
@@ -899,10 +1015,8 @@
                    s.setEditDate(date);
                    s.setEditor(null);
                    s.setCloseDate(date);
                    closeGoodsorder(s,Constants.REFUND_TYPE.PLAT_AUTO.getKey());
                }catch (BusinessException e){
                }catch (Exception e){
                }
@@ -917,10 +1031,7 @@
                .eq("status",Constants.goodsorderStatus.pay)
                .last(" limit 1 "));
        if(Objects.isNull(goodsorder)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"无骑行订单记录");
        }
        if(goodsorder == null  ){
            throw new BusinessException(ResponseStatus.DATA_EMPTY );
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"无骑行订单记录");
        }
        if(Constants.formatIntegerNum(goodsorder.getStatus()) != Constants.GOODSORDER_STATUS.HAVING_PAY.getKey() ){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,该订单当前状态不支持结算操作,请尝试刷新列表重试!" );
@@ -937,7 +1048,7 @@
    public String payNotify(String preOrderId,String paymentNo){
        Goodsorder goodsorder = this.goodsorderMapper.selectById(preOrderId);
        if(goodsorder.getStatus()==Constants.goodsorderStatus.pay){
            return WxPayNotifyResponse.success("处理成功!");
            return  ("处理成功!");
        }
        goodsorder.setOnlineOrderid(paymentNo);
        goodsorder.setPayStatus(Constants.goodsorderPayStatus.pay);
@@ -962,7 +1073,7 @@
        transactions.setObjId(goodsorder.getId());
        transactions.setObjType(Constants.ZERO);
        transactionsMapper.insert(transactions);
        return WxPayNotifyResponse.success("处理成功!");
        return  ("处理成功!");
    }
server/services/src/main/java/com/doumee/service/business/impl/RefundServiceImpl.java
@@ -5,6 +5,7 @@
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.RefundMapper;
import com.doumee.dao.business.TransactionsMapper;
import com.doumee.dao.business.join.RefundJoinMapper;
import com.doumee.dao.business.model.*;
import com.doumee.dao.business.model.RefundPlatExportVO;
@@ -16,6 +17,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -24,6 +26,7 @@
import java.math.BigDecimal;
import java.sql.Ref;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -39,6 +42,8 @@
    private RefundMapper refundMapper;
    @Autowired
    private RefundJoinMapper refundJoinMapper;
    @Autowired
    private TransactionsMapper transactionsMapper;
    @Override
    public String create(Refund refund) {
@@ -119,6 +124,17 @@
        return PageData.from(refundIPage);
    }
    @Override
    public void autoCancelRefunOrder(){
        Date date = new Date(System.currentTimeMillis()-5*60L*1000L);
        refundMapper.update(null, new UpdateWrapper<Refund>().lambda()
                    .eq(Refund::getStatus,Constants.ZERO)
                    .lt(Refund::getCreateDate,date)
                            .set(Refund::getStatus,Constants.ONE)
                            .set(Refund::getEditDate,new Date())
                            .set(Refund::getInfo,"超时未回调,自动取消")
                    );
    }
    @Override
    public List<RefundPlatExportVO>  findPlatExportPage( Refund pageWrap) {
        pageWrap.setTypeList(new ArrayList<>());
        //强制结算退款 å’Œ ç»“算后退款
server/services/src/main/java/com/doumee/service/business/impl/WxBillDetailServiceImpl.java
@@ -193,9 +193,9 @@
        queryWrapper.lambda().ge(pageWrap.getModel().getStartDate() !=null, WxBillDetail::getPid,DateUtil.getShortDateStr(pageWrap.getModel().getStartDate()));
        queryWrapper.lambda().le(pageWrap.getModel().getEndDate() !=null,WxBillDetail::getPid, DateUtil.getShortDateStr(pageWrap.getModel().getEndDate()));
        //自行车交易
        queryWrapper.lambda().eq(pageWrap.getModel().getIsBikeFee() != null&&pageWrap.getModel().getIsBikeFee().intValue() ==0, WxBillDetail::getAppid, WxMiniConfig.wxPayService.getConfig().getAppId());
        queryWrapper.lambda().eq(pageWrap.getModel().getIsBikeFee() != null&&pageWrap.getModel().getIsBikeFee().intValue() ==0, WxBillDetail::getAppid, WxMiniConfig.wxProperties.getSubAppId());
        //非自行车交易
        queryWrapper.lambda().ne(pageWrap.getModel().getIsBikeFee() != null&&pageWrap.getModel().getIsBikeFee().intValue() ==1, WxBillDetail::getAppid, WxMiniConfig.wxPayService.getConfig().getAppId());
        queryWrapper.lambda().ne(pageWrap.getModel().getIsBikeFee() != null&&pageWrap.getModel().getIsBikeFee().intValue() ==1, WxBillDetail::getAppid, WxMiniConfig.wxProperties.getSubAppId());
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
server/services/src/main/java/com/doumee/service/business/impl/WxBillServiceImpl.java
@@ -132,7 +132,7 @@
        QueryWrapper<WxBillDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().ge(param.getStartDate() !=null,WxBillDetail::getPid,DateUtil.getShortDateStr(param.getStartDate()));
        queryWrapper.lambda().le(param.getEndDate() !=null,WxBillDetail::getPid,DateUtil.getShortDateStr(param.getEndDate()));
        queryWrapper.lambda().ne(WxBillDetail::getAppid, WxMiniConfig.wxPayService.getConfig().getAppId());//非自行车收入统计
        queryWrapper.lambda().ne(WxBillDetail::getAppid, WxMiniConfig.wxPayV2Service.getConfig().getAppId());//非自行车收入统计
        queryWrapper.lambda().groupBy(WxBillDetail::getBillStatus);
        queryWrapper.select( "count(id) as sum_bill"
                ,"sum(settlement_total_fee) as settlement_total_fee"
@@ -281,7 +281,7 @@
        request.setBillType("SUCCESS");
        WxPayBillResult response = null;
        try {
            response = WxMiniConfig.wxPayService.downloadBill(request);
            response = WxMiniConfig.wxPayV2Service.downloadBill(request);
        }catch (WxPayException e){
        }
@@ -289,7 +289,7 @@
        //请求退款单交易记录汇总数据
        WxPayBillResult responseRefund = null;
        try {
            responseRefund = WxMiniConfig.wxPayService.downloadBill(request);
            responseRefund = WxMiniConfig.wxPayV2Service.downloadBill(request);
        }catch (WxPayException e){
        }
@@ -408,7 +408,7 @@
                detail.setRefundSuccessDate(DateUtil.getDateFromString2(info.getRefundSuccessTime()));//成功退款时间
                detail.setRefundApplyDate(DateUtil.getDateFromString2(info.getRefundTime())); //申请退款时间
                //计算自行车收入,匹配来自自行车小程序的所有支付成功和退款成功的金额,作为自行车收入(累计收款金额-累计退款成功金额)
                if(StringUtils.equals(detail.getAppid(), WxMiniConfig.wxPayService.getConfig().getAppId())){
                if(StringUtils.equals(detail.getAppid(), WxMiniConfig.wxPayV2Service.getConfig().getAppId())){
                    //自行车收入累计收款金额(支付成功总金额-退款总金额)
                    if(StringUtils.equals(info.getTradeState(),"SUCCESS")){
                        //如果是交易
server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java
@@ -51,8 +51,8 @@
    private SystemDictDataBiz systemDictDataBiz;
    @Value("${captcha_check}")
    private Boolean captchaCheck;
    @Value("${debug_model}")
    private Boolean debugModel;
    @Override
    public String loginByPassword(LoginDTO dto,  HttpServletRequest request) {
@@ -87,7 +87,7 @@
        loginLog.setServerIp(Utils.Server.getIP());
        if(needCheckCode){
            // æ ¡éªŒéªŒè¯ç 
            if(captchaCheck) {
            if(!debugModel) {
                try {
                    captchaService.check(dto.getUuid(), dto.getCode());
                } catch (Exception e) {
server/services/src/main/resources/application-dev.yml
@@ -29,8 +29,7 @@
    password: 111111
debug_model: true
# æ˜¯å¦éœ€è¦éªŒè¯ç 
captcha_check: false
# Swagger配置
swagger:
  host:
@@ -44,14 +43,24 @@
########################微信支付相关配置########################
wx:
  pay:
    appId: wxcd2b89fd2ff065f8
    appId: wx48fd8faa35cc8277
    mchId: 1661770902
    apiV3Key: iF3kC8pL8dZ9iU3hN5fX9zI6eF4xQ6fT
    serialNumer: 368B835A194384FD583B83B77977B84127D2F655
    notifyUrl: http://xiaopiqiu2.natapp1.cc/api/wxPayNotify
    refundNotifyUrl: http://xiaopiqiu2.natapp1.cc/api/wxRefundNotify
#    notifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxPayNotify
    keyPath: D://apiclient_cert.p12
    privateCertPath: D://apiclient_cert.pem
    privateKeyPath: D://apiclient_key.pem
    existsSub: 1
    appSecret: 1ceb7c9dff3c4330d653adc3ca55ea24
    mchId: 1229817002
    mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
#    notifyUrl: http://xiaopiqiu.natapp1.cc/api/wxPayNotify
    notifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxPayNotify
#    keyPath: D:\DouMee\config\doumeeTest\apiclient_cert.p12
    keyPath: /usr/local/apiclient_cert.p12
    subAppId: wxcd2b89fd2ff065f8
    subAppSecret: 49c4a52f9ad87ba98307972664fe33b3
    subMchId: 1661772003
    subMchKey: EVM8E15TKXE0OEMJFC0V6UFVIOZ5CSQS
    #      mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
    typeId: gybike
########################mqtt相关配置########################
mqtt:
  host: tcp://175.27.187.84:1883
server/services/src/main/resources/application-pro.yml
@@ -5,16 +5,16 @@
spring:
  # æ•°æ®æºé…ç½®
  datasource:
    url: jdbc:postgresql://175.27.187.84:5432/park_bike?stringtype=unspecified&serverTimezone=GMT%2B8
    username: postgres
    password: Doumee@168
    url: jdbc:postgresql://pgm-8vb8je6y0qbu2n1vlo.pgsql.zhangbei.rds.aliyuncs.com:3433/park_bike?stringtype=unspecified&serverTimezone=GMT%2B8
    username: parkbike
    password: parkbikeQWERT!@#$%
    driver-class-name: org.postgresql.Driver
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        #        hbm2ddl:
        #          auto: update
        #hbm2ddl:
        #auto: update
        temp:
          use_jdbc_metadata_defaults: false
  redis:
@@ -22,8 +22,8 @@
    host: localhost
    port: 6379
    password:
    #    password: r-uf6is6x17arnu44bem:tlt_2022
    timeout: 5000      # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
    # password: r-uf6is6x17arnu44bem:tlt_2022
    timeout: 5000 # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
knife4j:
  enable: true
@@ -32,9 +32,7 @@
    username: admin
    password: 111111
debug_model: true
# æ˜¯å¦éœ€è¦éªŒè¯ç 
captcha_check: false
debug_model: false
# Swagger配置
swagger:
  host:
@@ -43,3 +41,27 @@
  enabled: true
  # ç¦ç”¨swagger时的重定向地址
  redirect-uri: /
########################微信支付相关配置########################
wx:
  pay:
    appId: wxcd2b89fd2ff065f8
    appSecret: 1ceb7c9dff3c4330d653adc3ca55ea24
    mchId: 1229817002
    mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
    notifyUrl: https://bikes.yxbhlt.cn/bike_h5_api/api/wxPayNotify
    keyPath: /usr/local/apiclient_cert.p12
########################mqtt相关配置########################
mqtt:
  host: tcp://39.100.125.239:1883
  username: parkbike
  password: parkbike@168
  version: 003
tencent:
  map:
    remoteHost: https://apis.map.qq.com
    appKey: 3AYBZ-I5R3V-2BVP3-UWBDQ-ETBM5-B2BBQ
server/services/src/main/resources/application-test.yml
@@ -40,19 +40,27 @@
  # ç¦ç”¨swagger时的重定向地址
  redirect-uri: /
########################微信支付相关配置########################
wx:
  pay:
    appId: wxcd2b89fd2ff065f8
    appSecret: 1ceb7c9dff3c4330d653adc3ca55ea24
    mchId: 1229817002
    mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM
    #    notifyUrl: http://xiaopiqiu.natapp1.cc/api/wxPayNotify
    appId: wx48fd8faa35cc8277
    mchId: 1661770902
    apiV3Key: iF3kC8pL8dZ9iU3hN5fX9zI6eF4xQ6fT
    serialNumer: 368B835A194384FD583B83B77977B84127D2F655
    notifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxPayNotify
    #    keyPath: D:\DouMee\config\doumeeTest\apiclient_cert.p12
    refundNotifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxRefundNotify
    keyPath: /usr/local/apiclient_cert.p12
    privateCertPath: /usr/local/apiclient_cert.pem
    privateKeyPath: /usr/local/apiclient_key.pem
    existsSub: 1
    appSecret: 1ceb7c9dff3c4330d653adc3ca55ea24
    subAppId: wxcd2b89fd2ff065f8
    subAppSecret: 49c4a52f9ad87ba98307972664fe33b3
    subMchId: 1661772003
    subMchKey: EVM8E15TKXE0OEMJFC0V6UFVIOZ5CSQS
    typeId: gybike
########################mqtt相关配置########################
mqtt:
  host: tcp://175.27.187.84:1883
  username: doumee1
server/web/pom.xml
@@ -27,7 +27,7 @@
    </dependencies>
    <build>
        <finalName>web</finalName>
        <finalName>bike_h5_api</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
server/web/src/main/java/com/doumee/api/web/PaymentCallback.java
@@ -2,17 +2,27 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.doumee.core.model.ApiResponse;
import com.doumee.core.wx.WxMiniConfig;
import com.doumee.service.business.GoodsorderService;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.doumee.service.business.RefundService;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
 * Created by IntelliJ IDEA.
@@ -31,21 +41,50 @@
    /**
     * ã€å¾®ä¿¡æ”¯ä»˜ã€‘异步通知
     *
     * @param xmlResult
     * @return
     */
    @PostMapping("/api/wxPayNotify")
    public String wxPay_notify(@RequestBody String xmlResult) {
        log.info(xmlResult);
        if (StringUtils.isBlank(xmlResult)) return null;
    public ApiResponse wxPay_notify(HttpServletRequest request) {
        try {
            WxPayOrderNotifyResult result = WxMiniConfig.wxPayService.parseOrderNotifyResult(xmlResult);
            ServletInputStream inputStream = request.getInputStream();
            StringBuffer stringBuffer = new StringBuffer();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String s;
            //读取回调请求体
            while ((s = bufferedReader.readLine()) != null) {
                stringBuffer.append(s);
            }
            String body = stringBuffer.toString();
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            String nonce = request.getHeader("Wechatpay-Nonce");
            String signType = request.getHeader("Wechatpay-Signature-Type");
            String serialNo = request.getHeader("wechatpay-Serial");
            String signature = request.getHeader("Wechatpay-Signature");
            RequestParam requestParam = new RequestParam.Builder()
                    .serialNumber(serialNo)
                    .nonce(nonce)
                    .signType(signType)
                    .signature(signature)
                    .timestamp(String.valueOf(timestamp))
                    .body(body)
                    .build();
            NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(WxMiniConfig.wxProperties.getMchId())
                    .privateKeyFromPath(WxMiniConfig.wxProperties.getPrivateKeyPath())
                    .merchantSerialNumber(WxMiniConfig.wxProperties.getSerialNumer())
                    .apiV3Key(WxMiniConfig.wxProperties.getApiV3Key())
                    .build();
            NotificationParser parser = new NotificationParser(config);
            Transaction result = parser.parse(requestParam, Transaction.class);
            //自定义订单号
            String outTradeNo = result.getOutTradeNo();
            //微信订单号
            String paymentNo = result.getTransactionId();
            if ("SUCCESS".equals(result.getReturnCode())) {
                // æ”¯ä»˜æˆåŠŸ
            if ("SUCCESS".equals(result.getTradeState().name())) {
                // æ”¯ä»˜æˆåŠŸge
                switch (result.getAttach()) {
                    //支付订单回调
                    case "createGoodsOrder": {
@@ -57,17 +96,62 @@
                // æ”¯ä»˜å¤±è´¥
                switch (result.getAttach()) {
                    case "createGoodsOrder": {
                        break;
                    }
                }
                return WxPayNotifyResponse.fail(result.getReturnMsg());
            }
            return WxPayNotifyResponse.success("处理成功!");
            return ApiResponse.success("处理成功!");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("微信回调结果异常,异常原因{}", e.getLocalizedMessage());
            return WxPayNotifyResponse.fail(e.getMessage());
            return ApiResponse.failed("");
        }
    }
    @PostMapping("/api/wxRefundNotify")
    public ApiResponse wxRefundNotify(HttpServletRequest request) {
        try {
            ServletInputStream inputStream = request.getInputStream();
            StringBuffer stringBuffer = new StringBuffer();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String s;
            //读取回调请求体
            while ((s = bufferedReader.readLine()) != null) {
                stringBuffer.append(s);
            }
            String body = stringBuffer.toString();
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            String nonce = request.getHeader("Wechatpay-Nonce");
            String signType = request.getHeader("Wechatpay-Signature-Type");
            String serialNo = request.getHeader("wechatpay-Serial");
            String signature = request.getHeader("Wechatpay-Signature");
            RequestParam requestParam = new RequestParam.Builder()
                    .serialNumber(serialNo)
                    .nonce(nonce)
                    .signType(signType)
                    .signature(signature)
                    .timestamp(String.valueOf(timestamp))
                    .body(body)
                    .build();
            NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(WxMiniConfig.wxProperties.getMchId())
                    .privateKeyFromPath(WxMiniConfig.wxProperties.getPrivateKeyPath())
                    .merchantSerialNumber(WxMiniConfig.wxProperties.getSerialNumer())
                    .apiV3Key(WxMiniConfig.wxProperties.getApiV3Key())
                    .build();
            NotificationParser parser = new NotificationParser(config);
            RefundNotification result = parser.parse(requestParam, RefundNotification.class);
//            if ("SUCCESS".equals(result.getRefundStatus().name())) {
                // æ”¯ä»˜æˆåŠŸge
                     goodsorderService.closeGoodsorderDone(result);
//            }
            return ApiResponse.success("处理成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("微信回调结果异常,异常原因{}", e.getLocalizedMessage());
            return ApiResponse.failed("");
        }
    }
server/web/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java
ÎļþÒÑɾ³ý
server/web/src/main/java/com/doumee/config/shiro/ShiroCache.java
ÎļþÒÑɾ³ý
server/web/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java
ÎļþÒÑɾ³ý
server/web/src/main/java/com/doumee/config/shiro/ShiroConfig.java
ÎļþÒÑɾ³ý
server/web/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java
ÎļþÒÑɾ³ý
server/web/src/main/java/com/doumee/config/shiro/ShiroRealm.java
ÎļþÒÑɾ³ý
server/web/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java
ÎļþÒÑɾ³ý
server/web/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java
ÎļþÒÑɾ³ý
server/web/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java
ÎļþÒÑɾ³ý
server/web/src/main/resources/application.yml
@@ -63,4 +63,4 @@
   port: 10025
mqtt:
  clientid: doumeetestweb
  clientid: doumeeweb