From 037c144cd417410deb8137c6f3fd271a34691742 Mon Sep 17 00:00:00 2001 From: jiangping <jp@doumee.com> Date: 星期二, 12 十二月 2023 18:18:17 +0800 Subject: [PATCH] 服务商支付版本 --- server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java | 106 ++++++-- server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java | 1 server/services/src/main/java/com/doumee/service/business/RefundService.java | 3 server/platform/pom.xml | 2 server/services/src/main/java/com/doumee/service/business/impl/RefundServiceImpl.java | 16 + server/services/src/main/java/com/doumee/core/wx/pay/WxBillUtil.java | 7 server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java | 6 server/web/src/main/java/com/doumee/api/web/PaymentCallback.java | 112 ++++++++- server/services/src/main/java/com/doumee/service/business/impl/WxBillDetailServiceImpl.java | 4 server/services/src/main/java/com/doumee/service/business/GoodsorderService.java | 4 server/services/src/main/resources/application-dev.yml | 27 + server/services/src/main/java/com/doumee/core/wx/WxPayProperties.java | 18 + admin/src/views/business/wxBill.vue | 1 /dev/null | 25 -- server/platform/src/main/java/com/doumee/task/ScheduleTool.java | 22 + server/services/src/main/java/com/doumee/core/wx/WxMiniConfig.java | 64 ++++ server/services/src/main/resources/application-test.yml | 22 + server/pom.xml | 9 server/services/src/main/resources/application-pro.yml | 42 ++ server/web/pom.xml | 2 server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java | 201 +++++++++++++--- server/platform/src/main/resources/application.yml | 4 server/web/src/main/resources/application.yml | 2 server/services/src/main/java/com/doumee/service/business/impl/WxBillServiceImpl.java | 8 24 files changed, 527 insertions(+), 181 deletions(-) diff --git a/admin/src/views/business/wxBill.vue b/admin/src/views/business/wxBill.vue index ad11cba..0f5042d 100644 --- a/admin/src/views/business/wxBill.vue +++ b/admin/src/views/business/wxBill.vue @@ -107,7 +107,6 @@ startDate: '' }, sumData: { - }, pickerOptions: {} } diff --git a/server/platform/pom.xml b/server/platform/pom.xml index cd3d4e6..e6a5649 100644 --- a/server/platform/pom.xml +++ b/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> diff --git a/server/platform/src/main/java/com/doumee/task/ScheduleTool.java b/server/platform/src/main/java/com/doumee/task/ScheduleTool.java index 0345b41..b55e675 100644 --- a/server/platform/src/main/java/com/doumee/task/ScheduleTool.java +++ b/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("=====================缁撴潫 鑷嫊鍙栨秷鏈帹閫侀��娆剧姸鎬佺殑閫�娆惧崟鐘舵��======================="); + } } diff --git a/server/platform/src/main/resources/application.yml b/server/platform/src/main/resources/application.yml index 82e580e..a70c09f 100644 --- a/server/platform/src/main/resources/application.yml +++ b/server/platform/src/main/resources/application.yml @@ -61,5 +61,5 @@ port: 10026 mqtt: - clientid: doumeetestplat - subclientid: doumeetestplatSub + clientid: doumeeplat + subclientid: doumeeplatSub diff --git a/server/pom.xml b/server/pom.xml index f32a136..974927f 100644 --- a/server/pom.xml +++ b/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> diff --git a/server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java b/server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java index 4053b00..466b29f 100644 --- a/server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java +++ b/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; diff --git a/server/services/src/main/java/com/doumee/core/wx/WxMiniConfig.java b/server/services/src/main/java/com/doumee/core/wx/WxMiniConfig.java index 454c54e..d30226d 100644 --- a/server/services/src/main/java/com/doumee/core/wx/WxMiniConfig.java +++ b/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; } diff --git a/server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java b/server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java index fa41272..7439fd9 100644 --- a/server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java +++ b/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(),"閫�娆惧彂鐢熷紓甯歌鑱旂郴绠$悊鍛�"); + + } diff --git a/server/services/src/main/java/com/doumee/core/wx/WxPayProperties.java b/server/services/src/main/java/com/doumee/core/wx/WxPayProperties.java index efe67cb..43a5a49 100644 --- a/server/services/src/main/java/com/doumee/core/wx/WxPayProperties.java +++ b/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 } diff --git a/server/services/src/main/java/com/doumee/core/wx/pay/WxBillUtil.java b/server/services/src/main/java/com/doumee/core/wx/pay/WxBillUtil.java index f907810..44dba47 100644 --- a/server/services/src/main/java/com/doumee/core/wx/pay/WxBillUtil.java +++ b/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); diff --git a/server/services/src/main/java/com/doumee/service/business/GoodsorderService.java b/server/services/src/main/java/com/doumee/service/business/GoodsorderService.java index 7468652..4724ede 100644 --- a/server/services/src/main/java/com/doumee/service/business/GoodsorderService.java +++ b/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); /** diff --git a/server/services/src/main/java/com/doumee/service/business/RefundService.java b/server/services/src/main/java/com/doumee/service/business/RefundService.java index 101218f..274d923 100644 --- a/server/services/src/main/java/com/doumee/service/business/RefundService.java +++ b/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(); } diff --git a/server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java index 22043e0..566ca83 100644 --- a/server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java +++ b/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 { @@ -473,10 +478,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); @@ -485,6 +502,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())) { + // 濡傛灉閫�娆剧姸鎬佷笉姝g‘锛屼慨鏀归��娆惧崟鐘舵�� + 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()); @@ -497,12 +563,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){ //濡傛灉鏄己鍒剁粨绠� @@ -516,21 +585,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()); @@ -538,7 +593,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()); @@ -549,6 +604,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) { @@ -636,7 +731,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+"鍏�"); } @@ -825,23 +921,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蹇呴』鏄痟ttps寮�澶寸殑 + 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; + + } + /** * 楠岃瘉钀ヤ笟鏃堕棿 @@ -897,10 +1013,8 @@ s.setEditDate(date); s.setEditor(null); s.setCloseDate(date); - closeGoodsorder(s,Constants.REFUND_TYPE.PLAT_AUTO.getKey()); }catch (BusinessException e){ - }catch (Exception e){ } @@ -915,10 +1029,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(),"瀵逛笉璧凤紝璇ヨ鍗曞綋鍓嶇姸鎬佷笉鏀寔缁撶畻鎿嶄綔锛岃灏濊瘯鍒锋柊鍒楄〃閲嶈瘯锛�" ); @@ -935,7 +1046,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); @@ -960,7 +1071,7 @@ transactions.setObjId(goodsorder.getId()); transactions.setObjType(Constants.ZERO); transactionsMapper.insert(transactions); - return WxPayNotifyResponse.success("澶勭悊鎴愬姛!"); + return ("澶勭悊鎴愬姛!"); } diff --git a/server/services/src/main/java/com/doumee/service/business/impl/RefundServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/RefundServiceImpl.java index 8fac0ca..628e153 100644 --- a/server/services/src/main/java/com/doumee/service/business/impl/RefundServiceImpl.java +++ b/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<>()); //寮哄埗缁撶畻閫�娆� 鍜� 缁撶畻鍚庨��娆� diff --git a/server/services/src/main/java/com/doumee/service/business/impl/WxBillDetailServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/WxBillDetailServiceImpl.java index 71fcea8..19ee241 100644 --- a/server/services/src/main/java/com/doumee/service/business/impl/WxBillDetailServiceImpl.java +++ b/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()); diff --git a/server/services/src/main/java/com/doumee/service/business/impl/WxBillServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/WxBillServiceImpl.java index 0ffaba6..85883e9 100644 --- a/server/services/src/main/java/com/doumee/service/business/impl/WxBillServiceImpl.java +++ b/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")){ //濡傛灉鏄氦鏄� diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java index d3fd532..cf9c37f 100644 --- a/server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java +++ b/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) { diff --git a/server/services/src/main/resources/application-dev.yml b/server/services/src/main/resources/application-dev.yml index 1217ac8..980bff6 100644 --- a/server/services/src/main/resources/application-dev.yml +++ b/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 diff --git a/server/services/src/main/resources/application-pro.yml b/server/services/src/main/resources/application-pro.yml index 7c95b9d..c92867d 100644 --- a/server/services/src/main/resources/application-pro.yml +++ b/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 + + diff --git a/server/services/src/main/resources/application-test.yml b/server/services/src/main/resources/application-test.yml index 1d97529..cf74de8 100644 --- a/server/services/src/main/resources/application-test.yml +++ b/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 diff --git a/server/web/pom.xml b/server/web/pom.xml index 3943280..c288c50 100644 --- a/server/web/pom.xml +++ b/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> diff --git a/server/web/src/main/java/com/doumee/api/web/PaymentCallback.java b/server/web/src/main/java/com/doumee/api/web/PaymentCallback.java index 6c00273..3358405 100644 --- a/server/web/src/main/java/com/doumee/api/web/PaymentCallback.java +++ b/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(""); } } diff --git a/server/web/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java b/server/web/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java deleted file mode 100644 index f978edf..0000000 --- a/server/web/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.doumee.config.shiro; - -import com.alibaba.fastjson.JSON; -import com.doumee.core.model.ApiResponse; -import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; -import org.springframework.http.HttpStatus; - -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; - -/** - * Shiro璁よ瘉杩囨护鍣紝澶勭悊鏈璇佹儏鍐电殑鍝嶅簲 - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ -public class ShiroAuthFilter extends FormAuthenticationFilter { - - public ShiroAuthFilter() { - super(); - } - - @Override - protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { - HttpServletResponse servletResponse = (HttpServletResponse) response; - servletResponse.setHeader("content-type", "application/json;charset=UTF-8"); - servletResponse.getWriter().write(JSON.toJSONString(ApiResponse.failed(HttpStatus.UNAUTHORIZED.value(), "鏈櫥褰曟垨鐧诲綍淇℃伅宸茶繃鏈�"))); - return Boolean.FALSE; - } -} diff --git a/server/web/src/main/java/com/doumee/config/shiro/ShiroCache.java b/server/web/src/main/java/com/doumee/config/shiro/ShiroCache.java deleted file mode 100644 index 36cd7af..0000000 --- a/server/web/src/main/java/com/doumee/config/shiro/ShiroCache.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.doumee.config.shiro; - -import com.doumee.service.proxy.CacheProxy; -import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.cache.Cache; -import org.apache.shiro.cache.CacheException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Set; - -/** - * Shiro缂撳瓨 - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ -@Scope(value = "prototype") -@Slf4j -@Component -public class ShiroCache implements Cache<Object, Serializable> { - - private String keyPrefix = ""; - - @Autowired - private CacheProxy<Object, Serializable> cacheProxy; - - public ShiroCache () { - log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]"); - } - - public ShiroCache(String keyPrefix) { - log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]"); - this.keyPrefix = keyPrefix; - } - - @Override - public Serializable get(Object key) throws CacheException { - if (key == null) { - return null; - } - return cacheProxy.get(getKey(key)); - } - - @Override - public Serializable put(Object key, Serializable value) throws CacheException { - if (key == null) { - return null; - } - cacheProxy.put(getKey(key), value); - return value; - } - - public Serializable put(Object key, Serializable value, int timeout) throws CacheException { - if (key == null) { - return null; - } - cacheProxy.put(getKey(key), value, timeout); - return value; - } - - @Override - public void clear() throws CacheException { - Set<Object> keys = this.keys(); - cacheProxy.remove(keys); - } - - @Override - public int size() { - return this.keys().size(); - } - - @Override - public Set<Object> keys() { - Set<Object> keys = cacheProxy.keys(keyPrefix + "*"); - if (CollectionUtils.isEmpty(keys)) { - return Collections.emptySet(); - } - return keys; - } - - @Override - public Collection<Serializable> values() { - Collection<Serializable> values = new ArrayList<>(); - Set<Object> keys = this.keys(); - if (CollectionUtils.isEmpty(keys)) { - return values; - } - for (Object k : keys) { - values.add(cacheProxy.get(k)); - } - return values; - } - - @Override - public Serializable remove(Object key) throws CacheException { - if (key == null) { - return null; - } - Serializable value = this.get(getKey(key)); - cacheProxy.remove(getKey(key)); - return value; - } - - private Object getKey (Object key) { - return (key instanceof String ? (this.keyPrefix + key) : key); - } -} diff --git a/server/web/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java b/server/web/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java deleted file mode 100644 index fedcb98..0000000 --- a/server/web/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.doumee.config.shiro; - -import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.cache.Cache; -import org.apache.shiro.cache.CacheException; -import org.apache.shiro.cache.CacheManager; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * 鑷畾涔塖hiro CacheManager - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ -@Slf4j -@Component -public class ShiroCacheManager implements CacheManager { - - private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap(); - - private static ApplicationContext applicationContext; - - @Override - public <K, V> Cache<K, V> getCache(String name) throws CacheException { - log.debug("get cache, name=" + name); - Cache cache = this.caches.get(name); - if (cache == null) { - cache = applicationContext.getBean(ShiroCache.class, "shiro:cache:"); - this.caches.put(name, cache); - } - return cache; - } - - @Autowired - public void setApplicationContext (ApplicationContext applicationContext) { - if (ShiroCacheManager.applicationContext == null) { - ShiroCacheManager.applicationContext = applicationContext; - } - } -} diff --git a/server/web/src/main/java/com/doumee/config/shiro/ShiroConfig.java b/server/web/src/main/java/com/doumee/config/shiro/ShiroConfig.java deleted file mode 100644 index b8fc616..0000000 --- a/server/web/src/main/java/com/doumee/config/shiro/ShiroConfig.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.doumee.config.shiro; - -import org.apache.shiro.mgt.SecurityManager; -import org.apache.shiro.session.mgt.SessionManager; -import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; -import org.apache.shiro.spring.web.ShiroFilterFactoryBean; -import org.apache.shiro.web.mgt.DefaultWebSecurityManager; -import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.servlet.Filter; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Shiro閰嶇疆 - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ -@Configuration -public class ShiroConfig { - - @Value("${cache.session.expire}") - private int sessionExpireTime; - - @Autowired - private ShiroCredentialsMatcher shiroCredentialsMatcher; - - @Autowired - private ShiroSessionDAO shiroSessionDAO; - - @Autowired - private ShiroCacheManager shiroCacheManager; - - @Autowired - private ShiroRealm shiroRealm; - - @Bean - public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { - DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); - autoProxyCreator.setProxyTargetClass(true); - return autoProxyCreator; - } - - @Bean - public SessionManager sessionManager() { - ShiroSessionManager sessionManager = new ShiroSessionManager(); - sessionManager.setSessionDAO(shiroSessionDAO); - return sessionManager; - } - - @Bean - public SecurityManager securityManager() { - DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); - securityManager.setRealm(shiroRealm); - securityManager.setSessionManager(this.sessionManager()); - securityManager.setCacheManager(shiroCacheManager); - return securityManager; - } - - @Bean - public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { - ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); - shiroFilterFactoryBean.setSecurityManager(securityManager); - Map<String, String> map = new LinkedHashMap<>(); - // 璺緞鎷︽埅閰嶇疆 - map.put("/system/login", "anon"); - map.put("/system/logout", "anon"); - map.put("/common/captcha", "anon"); - map.put("/web/**", "anon"); - map.put("/api/wxPayNotify", "anon"); - //鏂囦欢涓婁紶鍙栨秷鎷︽埅 - map.put("/public/**", "anon"); - // - 鏀捐swagger - map.put("/doc.html", "anon"); - map.put("/webjars/**", "anon"); - map.put("/swagger-resources/**", "anon"); - map.put("/v2/api-docs/**", "anon"); - // - 鍏朵粬鎺ュ彛缁熶竴鎷︽埅 - map.put("/**", "authc"); - shiroFilterFactoryBean.setFilterChainDefinitionMap(map); - // 娣诲姞璁よ瘉杩囨护鍣� - Map<String, Filter> filters = new LinkedHashMap<>(); - filters.put("authc", new ShiroAuthFilter()); - shiroFilterFactoryBean.setFilters(filters); - return shiroFilterFactoryBean; - } - - @Bean - public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { - AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); - authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); - return authorizationAttributeSourceAdvisor; - } - - @Bean - public ShiroSessionDAO getShiroSessionDAO () { - shiroSessionDAO.setExpireTime(sessionExpireTime); - return shiroSessionDAO; - } - - @Bean - public ShiroRealm getShiroRealm () { - shiroRealm.setCredentialsMatcher(shiroCredentialsMatcher); - return shiroRealm; - } -} diff --git a/server/web/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java b/server/web/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java deleted file mode 100644 index 23b843e..0000000 --- a/server/web/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.doumee.config.shiro; - -import com.doumee.core.constants.Constants; -import com.doumee.core.utils.Utils; -import com.doumee.dao.system.model.SystemUser; -import com.doumee.service.system.SystemUserService; -import org.apache.shiro.authc.AuthenticationInfo; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authc.UsernamePasswordToken; -import org.apache.shiro.authc.credential.HashedCredentialsMatcher; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; - -/** - * Shiro瀵嗙爜姣斿澶勭悊 - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ -@Component -public class ShiroCredentialsMatcher extends HashedCredentialsMatcher { - - @Lazy - @Autowired - private SystemUserService systemUserService; - - @Override - public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { - UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; - SystemUser queryUserDto = new SystemUser(); - queryUserDto.setUsername(usernamePasswordToken.getUsername()); - queryUserDto.setDeleted(Constants.ZERO); - SystemUser systemUser = systemUserService.findOne(queryUserDto); - if (systemUser == null) { - return Boolean.FALSE; - } - // 鍔犲瘑瀵嗙爜 - String pwd = Utils.Secure.encryptPassword(new String(usernamePasswordToken.getPassword()), systemUser.getSalt()); - // 姣旇緝瀵嗙爜 - return this.equals(pwd, systemUser.getPassword()); - } -} diff --git a/server/web/src/main/java/com/doumee/config/shiro/ShiroRealm.java b/server/web/src/main/java/com/doumee/config/shiro/ShiroRealm.java deleted file mode 100644 index 0d562b0..0000000 --- a/server/web/src/main/java/com/doumee/config/shiro/ShiroRealm.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.doumee.config.shiro; - -import com.doumee.core.constants.Constants; -import com.doumee.core.model.LoginUserInfo; -import com.doumee.dao.system.model.SystemPermission; -import com.doumee.dao.system.model.SystemRole; -import com.doumee.dao.system.model.SystemUser; -import com.doumee.service.system.SystemPermissionService; -import com.doumee.service.system.SystemRoleService; -import com.doumee.service.system.SystemUserService; -import org.apache.shiro.authc.AuthenticationException; -import org.apache.shiro.authc.AuthenticationInfo; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authc.SimpleAuthenticationInfo; -import org.apache.shiro.authz.AuthorizationInfo; -import org.apache.shiro.authz.SimpleAuthorizationInfo; -import org.apache.shiro.realm.AuthorizingRealm; -import org.apache.shiro.subject.PrincipalCollection; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; - -import java.util.List; - -/** - * 鑷畾涔塕ealm锛屽鐞嗚璇佸拰鏉冮檺 - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ -@Component -public class ShiroRealm extends AuthorizingRealm { - - @Lazy - @Autowired - private SystemUserService systemUserService; - - @Lazy - @Autowired - private SystemRoleService systemRoleService; - - @Lazy - @Autowired - private SystemPermissionService systemPermissionService; - - /** - * 鏉冮檺澶勭悊 - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ - @Override - protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { - LoginUserInfo loginUserInfo = (LoginUserInfo)principalCollection.getPrimaryPrincipal(); - // 璁剧疆鐢ㄦ埛瑙掕壊鍜屾潈闄� - SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); - authorizationInfo.addRoles(loginUserInfo.getRoles()); - authorizationInfo.addStringPermissions(loginUserInfo.getPermissions()); - return authorizationInfo; - } - - /** - * 璁よ瘉澶勭悊 - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ - @Override - protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { - // 鑾峰彇鐢ㄦ埛鍚� - String username = authenticationToken.getPrincipal().toString(); - // 鏍规嵁鐢ㄦ埛鍚嶆煡璇㈢敤鎴峰璞� - SystemUser queryDto = new SystemUser(); - queryDto.setUsername(username); - queryDto.setDeleted(Constants.ZERO); - SystemUser user = systemUserService.findOne(queryDto); - if (user == null) { - return null; - } - // 鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅 - List<SystemRole> roles = systemRoleService.findByUserId(user.getId()); - List<SystemPermission> permissions = systemPermissionService.findByUserId(user.getId()); - LoginUserInfo userInfo = LoginUserInfo.from(user, roles, permissions); - // 楠岃瘉鐢ㄦ埛 - return new SimpleAuthenticationInfo(userInfo, user.getPassword(), this.getName()); - } - -} diff --git a/server/web/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java b/server/web/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java deleted file mode 100644 index 2cc6a11..0000000 --- a/server/web/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.doumee.config.shiro; - -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.session.Session; -import org.apache.shiro.session.UnknownSessionException; -import org.apache.shiro.session.mgt.SimpleSession; -import org.apache.shiro.session.mgt.eis.SessionDAO; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.io.Serializable; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -/** - * 鑷畾涔塖hiro SessionDAO锛屽皢浼氳瘽淇℃伅瀛樺叆缂撳瓨涓� - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ -@Data -@Slf4j -@Component -public class ShiroSessionDAO implements SessionDAO { - - private static final String KEY_PREFIX = "shiro:session:"; - - @Autowired - private ShiroCache shiroCache; - - private int expireTime = 1800; - - @Autowired - private ShiroTokenManager shiroTokenManager; - - @Override - public Serializable create(Session session) { - if (session == null) { - log.error("session is null"); - throw new UnknownSessionException("session is null"); - } - Serializable sessionId = shiroTokenManager.build(); - ((SimpleSession)session).setId(sessionId); - this.saveSession(session); - return sessionId; - } - - @Override - public Session readSession(Serializable sessionId) throws UnknownSessionException{ - if (sessionId == null) { - log.warn("session id is null"); - return null; - } - if (sessionId instanceof String) { - // 瀵筍essionId杩涜楠岃瘉锛堝彲鐢ㄤ簬闃叉Session鎹曡幏銆佹毚鍔涙崟鎹夌瓑涓�绯诲垪瀹夊叏闂锛屾渶缁堝畨鍏ㄦ�у彇鍐充簬check濡備綍瀹炵幇锛� - shiroTokenManager.check((String) sessionId); - } - log.debug("read session from cache"); - Session session = getSessionFromCache(sessionId); - if (session == null) { - throw new UnknownSessionException("There is no session with id [" + sessionId + "]"); - } - return session; - } - - @Override - public void update(Session session) throws UnknownSessionException { - this.saveSession(session); - } - - @Override - public void delete(Session session) { - if (session != null && session.getId() != null) { - shiroCache.remove(KEY_PREFIX + session.getId()); - } - } - - @Override - public Collection<Session> getActiveSessions() { - Set<Session> sessions = new HashSet<>(); - Set<Object> keys = shiroCache.keys(); - if (keys != null && keys.size() > 0) { - Iterator iter = keys.iterator(); - while(iter.hasNext()) { - sessions.add((Session) shiroCache.get(iter.next())); - } - } - return sessions; - } - - private void saveSession(Session session) throws UnknownSessionException { - if (session == null || session.getId() == null) { - log.error("session or session id is null"); - throw new UnknownSessionException("session or session id is null"); - } - shiroCache.put(KEY_PREFIX + session.getId(), (SimpleSession)session, expireTime); - } - - private Session getSessionFromCache (Serializable sessionId) { - Serializable object = shiroCache.get(KEY_PREFIX + sessionId); - Session session = null; - if (object != null) { - session = (Session)shiroCache.get(KEY_PREFIX + sessionId); - } - return session; - } - - public void setExpireTime (int expireTime) { - this.expireTime = expireTime; - } -} diff --git a/server/web/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java b/server/web/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java deleted file mode 100644 index ef159a7..0000000 --- a/server/web/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.doumee.config.shiro; - -import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.session.Session; -import org.apache.shiro.session.mgt.DefaultSessionManager; -import org.apache.shiro.session.mgt.SessionContext; -import org.apache.shiro.session.mgt.SessionKey; -import org.apache.shiro.web.servlet.Cookie; -import org.apache.shiro.web.servlet.ShiroHttpServletRequest; -import org.apache.shiro.web.servlet.SimpleCookie; -import org.apache.shiro.web.session.mgt.WebSessionManager; -import org.apache.shiro.web.util.WebUtils; - -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.Serializable; - -/** - * 鑷畾涔変細璇濈鐞嗗櫒 - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ -@Slf4j -public class ShiroSessionManager extends DefaultSessionManager implements WebSessionManager { - - private static final String AUTH_TOKEN = "eva-auth-token"; - - @Override - protected void onStart(Session session, SessionContext context) { - super.onStart(session, context); - if (!WebUtils.isHttp(context)) { - log.debug("SessionContext argument is not Http compatible or does not have an Http request/response pair. No session ID cookie will be set."); - return; - } - HttpServletRequest request = WebUtils.getHttpRequest(context); - HttpServletResponse response = WebUtils.getHttpResponse(context); - Serializable sessionId = session.getId(); - this.storeSessionId(sessionId, request, response); - request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE); - request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE); - } - - @Override - public Serializable getSessionId(SessionKey key) { - Serializable sessionId = super.getSessionId(key); - if (sessionId == null && WebUtils.isWeb(key)) { - ServletRequest servletRequest = WebUtils.getRequest(key); - if (!(servletRequest instanceof HttpServletRequest)) { - log.trace("Can not get sessionId from header, the request is not HttpServletRequest"); - return null; - } - HttpServletRequest request = (HttpServletRequest) servletRequest; - // 浠巆ookie涓幏鍙栬璇� - javax.servlet.http.Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (javax.servlet.http.Cookie cookie : cookies) { - if (AUTH_TOKEN.equals(cookie.getName())) { - return cookie.getValue(); - } - } - } - // 浠巋eader涓幏鍙栬璇� - return request.getHeader(AUTH_TOKEN); - } - return sessionId; - } - - @Override - public boolean isServletContainerSessions() { - return false; - } - - private void storeSessionId(Serializable currentId, HttpServletRequest request, HttpServletResponse response) { - if (currentId == null) { - String msg = "sessionId cannot be null when persisting for subsequent requests."; - throw new IllegalArgumentException(msg); - } - Cookie cookie = new SimpleCookie(AUTH_TOKEN); - cookie.setHttpOnly(false); - String idString = currentId.toString(); - cookie.setValue(idString); - cookie.saveTo(request, response); - log.trace("Set session ID cookie for session with id {}", idString); - } -} diff --git a/server/web/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java b/server/web/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java deleted file mode 100644 index 1ba1679..0000000 --- a/server/web/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.doumee.config.shiro; - -import com.doumee.core.exception.UnSafeSessionException; -import org.springframework.stereotype.Component; - -import java.util.UUID; - -/** - * 榛樿Token绠$悊鍣� - * @author Eva.Caesar Liu - * @date 2023/03/21 14:49 - */ -@Component -public class ShiroTokenManager { - - String build() { - return UUID.randomUUID().toString(); - } - - void check(String token) throws UnSafeSessionException { - if (token == null || token.length() != 36) { - throw new UnSafeSessionException(); - } - } -} diff --git a/server/web/src/main/resources/application.yml b/server/web/src/main/resources/application.yml index 05e2417..ea1f0e8 100644 --- a/server/web/src/main/resources/application.yml +++ b/server/web/src/main/resources/application.yml @@ -63,4 +63,4 @@ port: 10025 mqtt: - clientid: doumeetestweb + clientid: doumeeweb -- Gitblit v1.9.3