微信支付、回调、订单查询;
微信用户登录、用户信息查询、修改用户信息、同意用户协议; 文件OSS上传、删除接口;
This commit is contained in:
parent
4822174c5e
commit
ffc9fcb95c
7
pom.xml
7
pom.xml
@ -33,7 +33,12 @@
|
|||||||
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- 微信支付-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||||
|
<artifactId>wechatpay-java</artifactId>
|
||||||
|
<version>0.2.12</version>
|
||||||
|
</dependency>
|
||||||
<!-- 引入aop相关 -->
|
<!-- 引入aop相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
29
src/main/java/com/ycwl/basic/config/OssConfig.java
Normal file
29
src/main/java/com/ycwl/basic/config/OssConfig.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.ycwl.basic.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云OSS配置
|
||||||
|
*
|
||||||
|
* @author songmingsong
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
public class OssConfig {
|
||||||
|
@Value("${aliYunOss.endpoint}")
|
||||||
|
private String endPoint;
|
||||||
|
@Value("${aliYunOss.accessKeyId}")
|
||||||
|
private String accessKeyId;
|
||||||
|
@Value("${aliYunOss.accessKeySecret}")
|
||||||
|
private String accessKeySecret;
|
||||||
|
@Value("${aliYunOss.bucketName}")
|
||||||
|
private String bucketName;
|
||||||
|
@Value("${aliYunOss.objectName}")
|
||||||
|
private String objectName;
|
||||||
|
@Value("${aliYunOss.url}")
|
||||||
|
private String url;
|
||||||
|
@Value("${aliYunOss.region}")
|
||||||
|
private String region;
|
||||||
|
}
|
74
src/main/java/com/ycwl/basic/config/WechatConfig.java
Normal file
74
src/main/java/com/ycwl/basic/config/WechatConfig.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package com.ycwl.basic.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信小程序配置
|
||||||
|
*
|
||||||
|
* @author songmingsong
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "wx")
|
||||||
|
public class WechatConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号的appId
|
||||||
|
*/
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号的密钥
|
||||||
|
*/
|
||||||
|
private String appSecret;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送模板
|
||||||
|
*/
|
||||||
|
@Value("${wx.push.templateId}")
|
||||||
|
private String templateId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序的AppId
|
||||||
|
*/
|
||||||
|
private String miniProgramAppId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序的secret
|
||||||
|
*/
|
||||||
|
private String miniProgramSecret;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请openid授权
|
||||||
|
*/
|
||||||
|
private String grandType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户号
|
||||||
|
*/
|
||||||
|
private String mchId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户证书序列号
|
||||||
|
*/
|
||||||
|
private String mchSerialNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调接口地址
|
||||||
|
*/
|
||||||
|
private String notifyUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户API私钥路径
|
||||||
|
*/
|
||||||
|
private String keyPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户APIV3密钥
|
||||||
|
*/
|
||||||
|
private String apiV3;
|
||||||
|
|
||||||
|
}
|
62
src/main/java/com/ycwl/basic/constant/NumberConstant.java
Normal file
62
src/main/java/com/ycwl/basic/constant/NumberConstant.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package com.ycwl.basic.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>数字常量类</p>
|
||||||
|
*
|
||||||
|
* @author songmingsong
|
||||||
|
* @Description 数字常量类
|
||||||
|
*/
|
||||||
|
public interface NumberConstant {
|
||||||
|
|
||||||
|
int NEGATIVE_ONE = -1;
|
||||||
|
int NEGATIVE_TWO = -2;
|
||||||
|
|
||||||
|
int ZERO = 0;
|
||||||
|
|
||||||
|
int ONE = 1;
|
||||||
|
|
||||||
|
double ONE_DOUBLE = 1.0;
|
||||||
|
|
||||||
|
int TWO = 2;
|
||||||
|
|
||||||
|
int THREE = 3;
|
||||||
|
|
||||||
|
int FOUR = 4;
|
||||||
|
|
||||||
|
int FIVE = 5;
|
||||||
|
|
||||||
|
int SIX = 6;
|
||||||
|
|
||||||
|
int SEVEN = 7;
|
||||||
|
|
||||||
|
int TEN = 10;
|
||||||
|
|
||||||
|
int ELEVEN = 11;
|
||||||
|
|
||||||
|
int SIXTEEN = 16;
|
||||||
|
|
||||||
|
int SEVENTEEN = 17;
|
||||||
|
|
||||||
|
int EIGHTEEN = 18;
|
||||||
|
|
||||||
|
int NINETEEN = 19;
|
||||||
|
|
||||||
|
int TWENTY = 20;
|
||||||
|
|
||||||
|
int TWENTY_FOUR = 24;
|
||||||
|
|
||||||
|
int TWENTY_FIVE = 25;
|
||||||
|
|
||||||
|
int THIRTY = 30;
|
||||||
|
|
||||||
|
int FORTY = 40;
|
||||||
|
|
||||||
|
int SIXTY = 60;
|
||||||
|
|
||||||
|
int HUNDRED = 100;
|
||||||
|
|
||||||
|
int THOUSAND = 1000;
|
||||||
|
|
||||||
|
int MILLION = 1000000;
|
||||||
|
|
||||||
|
}
|
82
src/main/java/com/ycwl/basic/constant/WeiXinConstant.java
Normal file
82
src/main/java/com/ycwl/basic/constant/WeiXinConstant.java
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package com.ycwl.basic.constant;
|
||||||
|
|
||||||
|
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>@description: 微信常量 </p>
|
||||||
|
* <p>@author: songmingsong </p>
|
||||||
|
**/
|
||||||
|
public class WeiXinConstant {
|
||||||
|
|
||||||
|
private static final Map<Transaction.TradeStateEnum, String> STATE_DESCRIPTION_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
STATE_DESCRIPTION_MAP.put(com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum.SUCCESS, "SUCCESS");
|
||||||
|
STATE_DESCRIPTION_MAP.put(com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum.REFUND, "REFUND");
|
||||||
|
STATE_DESCRIPTION_MAP.put(com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum.NOTPAY, "NOTPAY");
|
||||||
|
STATE_DESCRIPTION_MAP.put(com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum.CLOSED, "CLOSED");
|
||||||
|
STATE_DESCRIPTION_MAP.put(com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum.REVOKED, "REVOKED");
|
||||||
|
STATE_DESCRIPTION_MAP.put(com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum.USERPAYING, "USERPAYING");
|
||||||
|
STATE_DESCRIPTION_MAP.put(com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum.PAYERROR, "PAYERROR");
|
||||||
|
STATE_DESCRIPTION_MAP.put(com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum.ACCEPT, "ACCEPT");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescriptionState(com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum state) {
|
||||||
|
return STATE_DESCRIPTION_MAP.getOrDefault(state, "未知状态");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<com.wechat.pay.java.service.payments.model.Transaction.TradeTypeEnum, String> STATE_DESCRIPTION_MAP_TYPE = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
STATE_DESCRIPTION_MAP_TYPE.put(Transaction.TradeTypeEnum.JSAPI, "JSAPI");
|
||||||
|
STATE_DESCRIPTION_MAP_TYPE.put(Transaction.TradeTypeEnum.NATIVE, "NATIVE");
|
||||||
|
STATE_DESCRIPTION_MAP_TYPE.put(Transaction.TradeTypeEnum.APP, "APP");
|
||||||
|
STATE_DESCRIPTION_MAP_TYPE.put(Transaction.TradeTypeEnum.MICROPAY, "MICROPAY");
|
||||||
|
STATE_DESCRIPTION_MAP_TYPE.put(Transaction.TradeTypeEnum.MWEB, "MWEB");
|
||||||
|
STATE_DESCRIPTION_MAP_TYPE.put(Transaction.TradeTypeEnum.FACEPAY, "FACEPAY");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescriptionType(Transaction.TradeTypeEnum type) {
|
||||||
|
return STATE_DESCRIPTION_MAP_TYPE.getOrDefault(type, "未知类型");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号模板地址
|
||||||
|
*/
|
||||||
|
public static final String PUBLIC_ACCOUNT_TEMPLATE =
|
||||||
|
"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";
|
||||||
|
/**
|
||||||
|
* 获取微信用户基本信息地址
|
||||||
|
*/
|
||||||
|
public static final String WECHAT_OAUTH_ACCESS_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token";
|
||||||
|
/**
|
||||||
|
* 获取ACCESS_TOKEN
|
||||||
|
*/
|
||||||
|
public static final String ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token";
|
||||||
|
/**
|
||||||
|
* 登录凭证校验
|
||||||
|
*/
|
||||||
|
public static final String GET_OPEN_ID = "https://api.weixin.qq.com/sns/jscode2session";
|
||||||
|
/**
|
||||||
|
* 获取小程序地址
|
||||||
|
*/
|
||||||
|
public static final String GET_MINI_QRCODE = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
|
||||||
|
/**
|
||||||
|
* 获取用户基本信息
|
||||||
|
*/
|
||||||
|
public static final String GET_USER_BASIC_INFO = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";
|
||||||
|
/**
|
||||||
|
* 获取包含请求参数ACCESS_TOKEN
|
||||||
|
*/
|
||||||
|
public static final String ACCESS_TOKEN_WITH_PARAM = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
||||||
|
/**
|
||||||
|
* 获取小程序 URL Link
|
||||||
|
*/
|
||||||
|
public static final String GENERATE_URL_LINK = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=%s";
|
||||||
|
|
||||||
|
public static final String WECHATPAY_SIGNATURE_TYPE = "Wechatpay-Signature-Type";
|
||||||
|
}
|
50
src/main/java/com/ycwl/basic/controller/FileController.java
Normal file
50
src/main/java/com/ycwl/basic/controller/FileController.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package com.ycwl.basic.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import com.ycwl.basic.annotation.IgnoreToken;
|
||||||
|
import com.ycwl.basic.enums.BizCodeEnum;
|
||||||
|
import com.ycwl.basic.service.FileService;
|
||||||
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 文件接口
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/file/v1")
|
||||||
|
@Slf4j
|
||||||
|
@Api(tags = "文件接口")
|
||||||
|
public class FileController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FileService fileService;
|
||||||
|
|
||||||
|
@ApiOperation(value = "上传文件")
|
||||||
|
@PostMapping("/upload")
|
||||||
|
@IgnoreToken
|
||||||
|
public ApiResponse<?> upload(@RequestParam(value = "file") MultipartFile file) throws IOException {
|
||||||
|
String url = fileService.uploadFile(file);
|
||||||
|
return ApiResponse.success(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "删除文件")
|
||||||
|
@PostMapping("/delete")
|
||||||
|
@IgnoreToken
|
||||||
|
public ApiResponse<?> delete(@RequestParam(value = "fileName") String fileName) throws IOException {
|
||||||
|
Boolean flag = fileService.delete(fileName);
|
||||||
|
return flag ? ApiResponse.success(BizCodeEnum.REQUEST_OK) : ApiResponse.fail(BizCodeEnum.FAIL.getMessage());
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,8 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/mobile/face/v1")
|
@RequestMapping("/api/mobile/face/v1")
|
||||||
@Api(tags = "用户人脸相关接口")
|
@Api(tags = "用户人脸相关接口")
|
||||||
public class AppFaceController {
|
public class
|
||||||
|
AppFaceController {
|
||||||
|
|
||||||
|
|
||||||
@ApiOperation("人脸有效性校验")
|
@ApiOperation("人脸有效性校验")
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package com.ycwl.basic.controller.mobile;
|
package com.ycwl.basic.controller.mobile;
|
||||||
|
|
||||||
|
import com.ycwl.basic.annotation.IgnoreToken;
|
||||||
|
import com.ycwl.basic.model.mobile.DTO.WeChatUserInfoDTO;
|
||||||
|
import com.ycwl.basic.model.mobile.DTO.WeChatUserInfoUpdateDTO;
|
||||||
|
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
|
||||||
|
import com.ycwl.basic.service.mobile.AppMemberService;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author:longbinbin
|
* @Author:longbinbin
|
||||||
@ -15,26 +19,63 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/mobile/member/v1")
|
@RequestMapping("/api/mobile/member/v1")
|
||||||
@Api(tags = "用户相关接口")
|
@Api(tags = "用户相关接口")
|
||||||
|
@Slf4j
|
||||||
public class AppMemberController {
|
public class AppMemberController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AppMemberService memberService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* @param userInfoDTO
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@ApiOperation("登录")
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public ApiResponse login() {
|
@IgnoreToken
|
||||||
//TODO 登录逻辑
|
public ApiResponse<?> login(@RequestParam(value = "code", required = false) String code,
|
||||||
return ApiResponse.success("");
|
@RequestParam(value = "userInfoDTO", required = false) WeChatUserInfoDTO userInfoDTO) throws Exception {
|
||||||
}
|
return memberService.login(code, userInfoDTO);
|
||||||
|
|
||||||
@PostMapping("/register")
|
|
||||||
public ApiResponse register() {
|
|
||||||
//TODO 注册逻辑
|
|
||||||
return ApiResponse.success("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户信息
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ApiOperation("获取用户信息")
|
||||||
@GetMapping("/getUserInfo")
|
@GetMapping("/getUserInfo")
|
||||||
public ApiResponse getUserInfo() {
|
public ApiResponse<MemberRespVO> getUserInfo() {
|
||||||
//TODO 获取用户信息逻辑
|
return memberService.getUserInfo();
|
||||||
return ApiResponse.success("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改用户信息
|
||||||
|
*
|
||||||
|
* @param userInfoUpdateDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ApiOperation("修改用户信息")
|
||||||
|
@PostMapping("/update")
|
||||||
|
public ApiResponse<?> update(@RequestBody WeChatUserInfoUpdateDTO userInfoUpdateDTO) {
|
||||||
|
return memberService.update(userInfoUpdateDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同意用户协议
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ApiOperation("同意用户协议")
|
||||||
|
@GetMapping("/agreement")
|
||||||
|
public ApiResponse<?> agreement() {
|
||||||
|
return memberService.agreement();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ApiOperation("是否首次获取视频")
|
@ApiOperation("是否首次获取视频")
|
||||||
@GetMapping("/isFirstObtainVideo")
|
@GetMapping("/isFirstObtainVideo")
|
||||||
public ApiResponse isFirstTimeObtainingVideo() {
|
public ApiResponse isFirstTimeObtainingVideo() {
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.ycwl.basic.controller.mobile;
|
||||||
|
|
||||||
|
|
||||||
|
import com.ycwl.basic.annotation.IgnoreToken;
|
||||||
|
import com.ycwl.basic.enums.BizCodeEnum;
|
||||||
|
import com.ycwl.basic.model.wxPay.WXPayOrderReqVO;
|
||||||
|
import com.ycwl.basic.model.wxPay.WxPayRespVO;
|
||||||
|
import com.ycwl.basic.service.mobile.WxPayService;
|
||||||
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 微信支付
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/mobile/wx/v1")
|
||||||
|
@Api(tags = "微信支付相关接口")
|
||||||
|
public class AppWxPayController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WxPayService wxPayService;
|
||||||
|
|
||||||
|
@ApiOperation(value = "微信预支付", notes = "微信预支付")
|
||||||
|
@PostMapping("/createOrder")
|
||||||
|
public ApiResponse<WxPayRespVO> createOrder(@RequestBody @Validated WXPayOrderReqVO req) throws Exception {
|
||||||
|
return ApiResponse.success(wxPayService.createOrder(req));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "微信支付回调", notes = "微信支付回调")
|
||||||
|
@PostMapping("/payNotify")
|
||||||
|
@IgnoreToken
|
||||||
|
public ApiResponse<?> payNotify(HttpServletRequest request) {
|
||||||
|
wxPayService.payNotify(request);
|
||||||
|
return ApiResponse.success(BizCodeEnum.REQUEST_OK);
|
||||||
|
}
|
||||||
|
}
|
20
src/main/java/com/ycwl/basic/enums/AgreementEnum.java
Normal file
20
src/main/java/com/ycwl/basic/enums/AgreementEnum.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package com.ycwl.basic.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否同意用户协议枚举
|
||||||
|
*
|
||||||
|
* @author songmingsong
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum AgreementEnum {
|
||||||
|
AGREE(1, "同意"),
|
||||||
|
NOT_AGREE(0, "未同意");
|
||||||
|
private int type;
|
||||||
|
private String remark;
|
||||||
|
}
|
@ -1,36 +0,0 @@
|
|||||||
package com.ycwl.basic.enums;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author songmingsong
|
|
||||||
* @since 2022-11-23
|
|
||||||
* 状态码定义
|
|
||||||
*/
|
|
||||||
public enum AppStatesCodeEnum {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通用操作码
|
|
||||||
*/
|
|
||||||
USER_STATES_CODE(1),
|
|
||||||
UNKNOWN_MISTAKE(500, "未知错误"),
|
|
||||||
NO_STAFFINFO_ERROR(411, "员工信息不存在"),
|
|
||||||
;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public int code;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public String message;
|
|
||||||
|
|
||||||
AppStatesCodeEnum(int code, String message) {
|
|
||||||
this.code = code;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppStatesCodeEnum(Integer statesCode) {
|
|
||||||
this.code = statesCode;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +1,437 @@
|
|||||||
package com.ycwl.basic.enums;
|
package com.ycwl.basic.enums;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author wenshijia
|
* @author songmingsong
|
||||||
* @date 2021年05月25日 22:29
|
* @since 2022-11-23
|
||||||
* 状态码定义约束,共6位数,前三位代表服务,后4位代表接口
|
* 状态码定义
|
||||||
* 比如 商品服务210,购物车是220、用户服务230,403代表权限
|
|
||||||
*/
|
*/
|
||||||
|
@Getter
|
||||||
public enum BizCodeEnum {
|
public enum BizCodeEnum {
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 0:成功 1:失败 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用操作码
|
* 成功
|
||||||
*/
|
*/
|
||||||
UNKNOWN_MISTAKE(500, "未知错误"),
|
SUCCESS(0, "成功"),
|
||||||
|
|
||||||
VERIFY_CODE_ERROR(600, "验证码错误"),
|
/**
|
||||||
|
* 失败
|
||||||
|
*/
|
||||||
|
FAIL(1, "失败"),
|
||||||
|
/**
|
||||||
|
* 异常
|
||||||
|
*/
|
||||||
|
ERROR(-1, "异常"),
|
||||||
|
|
||||||
NO_VERIFY_CODE_AUTH(700, "未进行授权"),
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 200-550 服务器相关 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/**
|
||||||
|
* 无效请求
|
||||||
|
*/
|
||||||
|
REQUEST_OK(200, "请求成功"),
|
||||||
|
/**
|
||||||
|
* 无效请求
|
||||||
|
*/
|
||||||
|
BAD_REQUEST(400, "无效请求"),
|
||||||
|
|
||||||
TOLL_MACHINE_BIND_APPLICATION_SITE(1000, "当前收费机已经绑定了应用场所"),
|
/**
|
||||||
TOLL_MACHINE_EXIST(1001, "当前收费机编号已经存在"),
|
* 参数错误
|
||||||
APPLICATION_SITE_EXIST(1002, "当前应用场所已经存在"),
|
*/
|
||||||
|
PARAM_ERROR(400, "参数错误,缺少必要参数"),
|
||||||
|
|
||||||
CONFERENCE_DEVICE_EXIST(2001, "当前会议设设备已经存在"),
|
/**
|
||||||
|
* 无效鉴权信息
|
||||||
|
*/
|
||||||
|
UNAUTHORIZED(401, "无效授权信息"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登陆失效
|
||||||
|
*/
|
||||||
|
TOKEN_INVALID(401, "登录失效,请重新登录"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无权访问此资源
|
||||||
|
*/
|
||||||
|
FORBIDDEN(403, "无权访问此资源"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无效的访问地址
|
||||||
|
*/
|
||||||
|
INVALID_URL(404, "无效的访问地址"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不支持的请求方式
|
||||||
|
*/
|
||||||
|
NOT_SUPPORTED(405, "不支持的请求方式"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网络异常
|
||||||
|
*/
|
||||||
|
REQUEST_TIMEOUT(408, "请求超时"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据完整性异常 数据过长 过短
|
||||||
|
*/
|
||||||
|
LENGTH_REQUIRED(411, "数据完整性异常"),
|
||||||
|
/**
|
||||||
|
* 数据约束性异常
|
||||||
|
*/
|
||||||
|
CONSTRAINT_EXCEPTION(412, "重复提交或者数据已存在"),
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据格式错误
|
||||||
|
*/
|
||||||
|
DATA_FORMAT_ERROR(415, "数据格式错误"),
|
||||||
|
/**
|
||||||
|
* 此地址暂不可使用
|
||||||
|
*/
|
||||||
|
METHOD_FAILURE(420, "此地址暂不可使用"),
|
||||||
|
/**
|
||||||
|
* 账户已锁定
|
||||||
|
*/
|
||||||
|
LOCKED(423, "账户已锁定,请联系客服"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求过于频繁
|
||||||
|
*/
|
||||||
|
TOO_MANY_REQUESTS(429, "请求过于频繁"),
|
||||||
|
/**
|
||||||
|
* 远程访问异常
|
||||||
|
*/
|
||||||
|
REMOTE_ACCESS_EXCEPTION(430, " 访问远程主机时发生了异常"),
|
||||||
|
/**
|
||||||
|
* 错误的服务API
|
||||||
|
*/
|
||||||
|
ERROR_SERVER_API(431, "错误的服务API"),
|
||||||
|
/**
|
||||||
|
* 错误的签名
|
||||||
|
*/
|
||||||
|
ERROR_SIGN_ACCESS(432, "Access Sign Error"),
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无效鉴权信息
|
||||||
|
*/
|
||||||
|
INVALID_REFRESH(433, "无效刷新信息"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器内部错误
|
||||||
|
*/
|
||||||
|
SERVER_INTERNAL_ERROR(500, "服务器内部错误"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未知错误
|
||||||
|
*/
|
||||||
|
SERVER_UNKONWN_ERROR(500, "未知错误"),
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暂不可服务
|
||||||
|
*/
|
||||||
|
SERVICE_UNAVAILABLE(503, "暂不可服务"),
|
||||||
|
/**
|
||||||
|
* 需要认证
|
||||||
|
*/
|
||||||
|
AUTHENTICATION_REQUIRED(511, "需要认证"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无数据
|
||||||
|
*/
|
||||||
|
NO_DATA(512, "无数据"),
|
||||||
|
/**
|
||||||
|
* 存在关联数据
|
||||||
|
*/
|
||||||
|
DATA_RELATION(513, "存在关联数据"),
|
||||||
|
/**
|
||||||
|
* 该数据已填写
|
||||||
|
*/
|
||||||
|
DATA_COMPLETED(514, "该数据已填写"),
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 600-619 登录相关业务码 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账号不存在
|
||||||
|
*/
|
||||||
|
ACCOUNT_NON_EXISTENT(601, "账号不存在"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账号已存在
|
||||||
|
*/
|
||||||
|
ACCOUNT_EXISTENT(602, "账号已存在"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账户密码错误
|
||||||
|
*/
|
||||||
|
ACCOUNT_PASSWORD_ERROR(603, "用户名或密码不正确"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绵阳授权码错误
|
||||||
|
*/
|
||||||
|
MYang_AUTHORIZATION_CODE_ERROR(6031, "授权码不正确"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号已绑定
|
||||||
|
*/
|
||||||
|
TEL_IS_BIND(604, "手机号已绑定"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未绑定手机号
|
||||||
|
*/
|
||||||
|
TEL_IS_NOT_BIND(605, "尚未绑定手机号,请先绑定手机号"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无效的登录类型
|
||||||
|
*/
|
||||||
|
ERROR_LOGIN_CHANNEL(606, "无效的登录类型"),
|
||||||
|
/**
|
||||||
|
* token已过期
|
||||||
|
*/
|
||||||
|
TOKEN_EXPIRED(608, "token已过期"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账户在其他地方登录
|
||||||
|
*/
|
||||||
|
ACCOUNTS_IS_LOGGED_IN_ELSEWHERE(609, "登录失效,账号已在其他设备登录。"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第三方登录失败
|
||||||
|
*/
|
||||||
|
THIRD_LOGIN_ERROR(610, "第三方登录失败"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不支持的登录方式
|
||||||
|
*/
|
||||||
|
NOT_SUPPORT_LOGIN_CHANNEL(611, "暂不支持的登录方式"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要登录后操作
|
||||||
|
*/
|
||||||
|
NEED_LOGIN(612, "需要登录后操作"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 尚未设置密码
|
||||||
|
*/
|
||||||
|
LOGIN_PASSWORD_HAS_NOT_BEEN_SET(613, "账号或密码错误,请重新输入"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册失败
|
||||||
|
*/
|
||||||
|
REGISTER_FAIL(614, "注册失败"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连续登录错误达到阈值,请稍后再试
|
||||||
|
*/
|
||||||
|
CONTINUOUS_LOGIN_ERROR(615, "错误密码输入次数过多,请%s分钟后再试"),
|
||||||
|
|
||||||
|
APP_CONTINUOUS_LOGIN_ERROR(616, "错误密码输入次数过多,请%s分钟后再试"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* refreshToken已过期
|
||||||
|
*/
|
||||||
|
REFRESH_TOKEN_EXPIRE(618, "refreshToken已过期"),
|
||||||
|
|
||||||
|
CHANNEL_ERROR(619, "渠道错误"),
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 620-639 验证码相关业务码 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码获取失败
|
||||||
|
*/
|
||||||
|
VERIFY_CODE_FAIL(621, "验证码获取失败"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无效验证码
|
||||||
|
*/
|
||||||
|
INVALID_VERIFY_CODE(622, "无效验证码"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码已使用
|
||||||
|
*/
|
||||||
|
USED_VERIFY_CODE(623, "验证码已使用"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码已过期
|
||||||
|
*/
|
||||||
|
EXPIRE_VERIFY_CODE(624, "验证码已失效,请重新输入"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 没有输入验证码
|
||||||
|
*/
|
||||||
|
NOT_HAS_VERIFY_CODE(625, "没有输入验证码"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误的验证码
|
||||||
|
*/
|
||||||
|
ERROR_VERIFY_CODE(626, "验证码错误,请重新输入"),
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 640-659 角色相关业务码 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色已存在
|
||||||
|
*/
|
||||||
|
ROLE_EXIST(640, "角色已存在"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色不存在
|
||||||
|
*/
|
||||||
|
ROLE_NOT_EXIST(641, "角色不存在"),
|
||||||
|
|
||||||
|
HAS_NOT_ROLE(642, "当前登录人没有角色"),
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 660-679 文件相关业务码 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件过大
|
||||||
|
*/
|
||||||
|
FILE_TOO_LARGE(660, "文件过大"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不支持的文件类型
|
||||||
|
*/
|
||||||
|
UNSUPPORTED_FILE_TYPE(661, "不支持的文件类型"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件不存在
|
||||||
|
*/
|
||||||
|
FILE_NOT_EXIST(662, "文件不存在"),
|
||||||
|
/**
|
||||||
|
* 文件上传失败
|
||||||
|
*/
|
||||||
|
UPLOAD_FAILED(663, "文件上传失败"),
|
||||||
|
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 7** 其他业务码 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间不能大于结束时间
|
||||||
|
*/
|
||||||
|
TIME_FAIL(704, "%s开始时间需小于结束时间"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 二维码获取失败
|
||||||
|
*/
|
||||||
|
QR_CODE_GET_FAIL(705, "二维码获取失败"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有尚未完成的任务
|
||||||
|
*/
|
||||||
|
TASK_IS_NOT_OVER(706, "有尚未完成的任务"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该记录已经审核
|
||||||
|
*/
|
||||||
|
REMARK_IS_EXAMINE(707, "该记录已经审核"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 只有管理员才能操作
|
||||||
|
*/
|
||||||
|
SHOP_ONLY_MANAGER_HANDLE(708, "只有管理员才能操作"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群主不能被删除
|
||||||
|
*/
|
||||||
|
EMCHAT_GROUP_DELETE_ERROR(709, "群主不能被删除"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存在重复数据
|
||||||
|
*/
|
||||||
|
EMCHAT_REPEAT_ERROR(710, "存在重复数据"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 姓名或手机号不能为空
|
||||||
|
*/
|
||||||
|
NAME_PHONE_NOT_NULL(801, "姓名或手机号不能为空"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该手机号用户已存在
|
||||||
|
*/
|
||||||
|
PHONE_EXIST(802, "该手机号用户已存在"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出失败
|
||||||
|
*/
|
||||||
|
EXPORT_FAIL(804, "导出失败"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前资源路径已被占用
|
||||||
|
*/
|
||||||
|
PATH_ALREADY_EXIST(805, "当前资源路径已被占用"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 功能不能使用已有的菜单路径
|
||||||
|
*/
|
||||||
|
FUNCTION_NOT_MAKE_MENU(806, "功能不能使用已有的菜单路径"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内置角色不能删除
|
||||||
|
*/
|
||||||
|
BUILT_IN_ROLE_NOT_DELETE(807, "内置角色不能删除"),
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 901-999 角色相关业务码 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
USER_ORGANIZATION(901, "该手机号不属于有效账号,请重新输入"),
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 1000-1019 账号密码相关业务码 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
OLD_PSW_ERROR(1000, "原密码错误,请重新输入"),
|
||||||
|
|
||||||
|
/* -------------------------------------*/
|
||||||
|
/* */
|
||||||
|
/* 2000-2019 微信支付相关业务码 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------*/
|
||||||
|
ADVANCE_PAYMENT_FAILED(2001, "预支付失败"),
|
||||||
|
ADVANCE_PAYMENT_CALLBACK_FAILED(2002, "预支付回调失败"),
|
||||||
;
|
;
|
||||||
|
|
||||||
@Getter
|
|
||||||
public int code;
|
|
||||||
|
|
||||||
@Getter
|
BizCodeEnum(Integer code, String message) {
|
||||||
@Setter
|
|
||||||
public String message;
|
|
||||||
|
|
||||||
BizCodeEnum(int code, String message) {
|
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
private String message;
|
||||||
}
|
}
|
||||||
|
25
src/main/java/com/ycwl/basic/enums/OrderStateEnum.java
Normal file
25
src/main/java/com/ycwl/basic/enums/OrderStateEnum.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package com.ycwl.basic.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态枚举
|
||||||
|
*
|
||||||
|
* @author songmingsong
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum OrderStateEnum {
|
||||||
|
NOT_PRESENTED(0, "未提出",1),
|
||||||
|
PASSED(1, "已通过",1),
|
||||||
|
UNPAID(0, "未支付",2),
|
||||||
|
PAID(1, "已支付",2),
|
||||||
|
REFUNDED(2, "已退款",2),
|
||||||
|
CANCELED(9, "已取消",2);
|
||||||
|
private int state;
|
||||||
|
private String remark;
|
||||||
|
private int type; // 1-退款 2-支付
|
||||||
|
}
|
47
src/main/java/com/ycwl/basic/enums/WechatErrorCodeEnum.java
Normal file
47
src/main/java/com/ycwl/basic/enums/WechatErrorCodeEnum.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package com.ycwl.basic.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>@AUTHOR: songmingsong</p>
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum WechatErrorCodeEnum {
|
||||||
|
/**
|
||||||
|
* 无效的预登陆code
|
||||||
|
*/
|
||||||
|
INVALID_CODE("40029", "无效的预登陆code"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预登陆code已经使用
|
||||||
|
*/
|
||||||
|
CODE_IS_USED("40163", "预登陆code已经使用"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无效的AppSecret
|
||||||
|
*/
|
||||||
|
INVALID_APP_SECRET("40125", "无效的AppSecret"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未知的微信错误
|
||||||
|
*/
|
||||||
|
UNKNOWN_ERROR_CODE("50000", "未知的微信错误");
|
||||||
|
|
||||||
|
WechatErrorCodeEnum(String code, String detail) {
|
||||||
|
this.code = code;
|
||||||
|
this.detail = detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
private String detail;
|
||||||
|
|
||||||
|
public static WechatErrorCodeEnum getErrorCode(String code) {
|
||||||
|
for (WechatErrorCodeEnum wechatErrorCodeEnum : WechatErrorCodeEnum.values()) {
|
||||||
|
if (wechatErrorCodeEnum.code.equals(code)) {
|
||||||
|
return wechatErrorCodeEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UNKNOWN_ERROR_CODE;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package com.ycwl.basic.exception;
|
package com.ycwl.basic.exception;
|
||||||
|
|
||||||
import com.ycwl.basic.enums.AppStatesCodeEnum;
|
import com.ycwl.basic.enums.BizCodeEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,9 +19,14 @@ public class AppException extends RuntimeException {
|
|||||||
this.msg = message;
|
this.msg = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppException(AppStatesCodeEnum mobileCodeEnum) {
|
public AppException(BizCodeEnum mobileCodeEnum) {
|
||||||
super(mobileCodeEnum.getMessage());
|
super(mobileCodeEnum.getMessage());
|
||||||
this.code = mobileCodeEnum.getCode();
|
this.code = mobileCodeEnum.getCode();
|
||||||
this.msg = mobileCodeEnum.getMessage();
|
this.msg = mobileCodeEnum.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AppException(BizCodeEnum mobileCodeEnum, String msg) {
|
||||||
|
this.code = mobileCodeEnum.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class CustomExceptionHandle {
|
|||||||
@ExceptionHandler(value = Exception.class)
|
@ExceptionHandler(value = Exception.class)
|
||||||
public ApiResponse<String> handle(Exception e) {
|
public ApiResponse<String> handle(Exception e) {
|
||||||
LOGGER.error("系统异常 -> {}", e.getMessage(), e);
|
LOGGER.error("系统异常 -> {}", e.getMessage(), e);
|
||||||
return ApiResponse.buildResult(BizCodeEnum.UNKNOWN_MISTAKE);
|
return ApiResponse.buildResult(BizCodeEnum.SERVER_UNKONWN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +39,7 @@ public class JwtInfo implements Serializable {
|
|||||||
* 用户账号
|
* 用户账号
|
||||||
*/
|
*/
|
||||||
private String account;
|
private String account;
|
||||||
|
|
||||||
private String phone;
|
private String phone;
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.ycwl.basic.model.mobile.DTO;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 微信用户信息
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WeChatUserInfoDTO {
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatarUrl;
|
||||||
|
/**
|
||||||
|
* 微信昵称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
|
/**
|
||||||
|
* 是否同意用户协议,1同意0未同意
|
||||||
|
*/
|
||||||
|
private Integer agreement;
|
||||||
|
/**
|
||||||
|
* 电话号码
|
||||||
|
*/
|
||||||
|
private String phone;
|
||||||
|
/**
|
||||||
|
* 国家
|
||||||
|
*/
|
||||||
|
private String country;
|
||||||
|
/**
|
||||||
|
* 省份
|
||||||
|
*/
|
||||||
|
private String province;
|
||||||
|
/**
|
||||||
|
* 城市
|
||||||
|
*/
|
||||||
|
private String city;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.ycwl.basic.model.mobile.DTO;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 修改微信用户信息
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WeChatUserInfoUpdateDTO {
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatarUrl;
|
||||||
|
/**
|
||||||
|
* 微信昵称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
|
/**
|
||||||
|
* 是否同意用户协议,1同意0未同意
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.ycwl.basic.model.mobile;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 微信用户信息
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WeChatUserInfoModel {
|
||||||
|
/**
|
||||||
|
* 微信openid
|
||||||
|
*/
|
||||||
|
private String openId;
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
private String id;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatarUrl;
|
||||||
|
/**
|
||||||
|
* 微信昵称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
|
/**
|
||||||
|
* 真实名称
|
||||||
|
*/
|
||||||
|
private String realName;
|
||||||
|
}
|
@ -23,6 +23,10 @@ public class MemberEntity {
|
|||||||
* 微信昵称
|
* 微信昵称
|
||||||
*/
|
*/
|
||||||
private String nickname;
|
private String nickname;
|
||||||
|
/**
|
||||||
|
* 微信头像
|
||||||
|
*/
|
||||||
|
private String avatarUrl;
|
||||||
/**
|
/**
|
||||||
* 真实姓名
|
* 真实姓名
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.ycwl.basic.model.wxPay;
|
||||||
|
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 预支付请求类
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class WXPayOrderReqVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "总金额(单位:分)",required = true)
|
||||||
|
private Integer totalPrice;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品名称",required = true)
|
||||||
|
private String goodsName;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "openid",required = true)
|
||||||
|
private String openId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品订单号",required = true)
|
||||||
|
private Long orderSn;
|
||||||
|
}
|
41
src/main/java/com/ycwl/basic/model/wxPay/WxPayRespVO.java
Normal file
41
src/main/java/com/ycwl/basic/model/wxPay/WxPayRespVO.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package com.ycwl.basic.model.wxPay;
|
||||||
|
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 支付返回类
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class WxPayRespVO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 预支付交易会话标识小程序下单接口返回的prepay_id参数值
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("预支付交易会话标识小程序下单接口返回的prepay_id参数值")
|
||||||
|
private String prepayId;
|
||||||
|
/**
|
||||||
|
* 随机字符串
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("随机字符串")
|
||||||
|
private String nonceStr;
|
||||||
|
/**
|
||||||
|
* 时间戳
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("时间戳")
|
||||||
|
private Long timeStamp;
|
||||||
|
/**
|
||||||
|
* 签名
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("签名")
|
||||||
|
private String paySign;
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.ycwl.basic.model.wxPay;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 微信订单查询结果
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Slf4j
|
||||||
|
public class WxchatCallbackSuccessData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户订单号
|
||||||
|
*/
|
||||||
|
private String orderId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交易状态
|
||||||
|
* SUCCESS:支付成功
|
||||||
|
* REFUND:转入退款
|
||||||
|
* NOTPAY:未支付
|
||||||
|
* CLOSED:已关闭
|
||||||
|
* REVOKED:已撤销(付款码支付)
|
||||||
|
* USERPAYING:用户支付中(付款码支付)
|
||||||
|
* PAYERROR:支付失败(其他原因,如银行返回失败)
|
||||||
|
*/
|
||||||
|
private String tradestate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付完成时间
|
||||||
|
*/
|
||||||
|
private Date successTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交易类型
|
||||||
|
* JSAPI:公众号支付
|
||||||
|
* NATIVE:扫码支付
|
||||||
|
* APP:APP支付
|
||||||
|
* MICROPAY:付款码支付
|
||||||
|
* MWEB:H5支付
|
||||||
|
* FACEPAY:刷脸支付
|
||||||
|
*/
|
||||||
|
private String tradetype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单总金额
|
||||||
|
*/
|
||||||
|
private BigDecimal totalMoney;
|
||||||
|
|
||||||
|
|
||||||
|
public Date getSuccessTime() {
|
||||||
|
return successTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuccessTime(String successTime) {
|
||||||
|
// Hutool工具包的方法,自动识别一些常用格式的日期字符串
|
||||||
|
this.successTime = DateUtil.parse(successTime);
|
||||||
|
}
|
||||||
|
}
|
29
src/main/java/com/ycwl/basic/service/FileService.java
Normal file
29
src/main/java/com/ycwl/basic/service/FileService.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.ycwl.basic.service;
|
||||||
|
|
||||||
|
import com.ycwl.basic.utils.OssUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file请求服务
|
||||||
|
*
|
||||||
|
* @author songmingsong
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class FileService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OssUtil ossUtil;
|
||||||
|
|
||||||
|
public String uploadFile(MultipartFile file) throws IOException {
|
||||||
|
return ossUtil.uploadFile(file.getInputStream(), Objects.requireNonNull(file.getOriginalFilename()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean delete(String fileName) {
|
||||||
|
return ossUtil.deleteFile(fileName);
|
||||||
|
}
|
||||||
|
}
|
121
src/main/java/com/ycwl/basic/service/HttpService.java
Normal file
121
src/main/java/com/ycwl/basic/service/HttpService.java
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package com.ycwl.basic.service;
|
||||||
|
|
||||||
|
import com.ycwl.basic.utils.HttpServiceUtil;
|
||||||
|
import com.ycwl.basic.utils.SslUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.StatusLine;
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http请求服务
|
||||||
|
*
|
||||||
|
* @author songmingsong
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class HttpService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param requestUrl
|
||||||
|
* 请求地址
|
||||||
|
* @param params
|
||||||
|
* 参数
|
||||||
|
* @param encoding
|
||||||
|
* 编码
|
||||||
|
* @return String
|
||||||
|
* @throws Exception
|
||||||
|
* 抛出的异常新
|
||||||
|
*/
|
||||||
|
public String doHttpsPost(String requestUrl, Map<String, String> params, String encoding) throws Exception {
|
||||||
|
String result = HttpServiceUtil.REQUEST_NO_RESULT;
|
||||||
|
// build client 对象
|
||||||
|
CloseableHttpClient httpClient = null;
|
||||||
|
try {
|
||||||
|
httpClient = SslUtil.sslHttpClientBuild();
|
||||||
|
requestUrl = requestUrl.replaceAll("\\s*", "");
|
||||||
|
HttpPost post = new HttpPost(requestUrl);
|
||||||
|
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
|
||||||
|
.setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();
|
||||||
|
post.setConfig(requestConfig);
|
||||||
|
// 请求首部--可选的,User-Agent对于一些服务器必选,不加可能不会返回正确结果
|
||||||
|
post.setHeader("User-Agent",
|
||||||
|
"Mozilla/5.0 (Linux; U; Android 5.0.2; zh-cn; PLK-UL00 Build/HONORPLK-UL00) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025483 Mobile Safari/533.1 MicroMessenger/6.3.8.56_re6b2553.680 NetType/");
|
||||||
|
List<NameValuePair> parasList = new ArrayList<NameValuePair>();
|
||||||
|
if (null != params && params.size() > 0) {
|
||||||
|
for (String key : params.keySet()) {
|
||||||
|
NameValuePair param = new BasicNameValuePair(key, params.get(key));
|
||||||
|
parasList.add(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Exec Request
|
||||||
|
HttpEntity paramsEntity = new UrlEncodedFormEntity(parasList, encoding);
|
||||||
|
post.setEntity(paramsEntity);
|
||||||
|
CloseableHttpResponse resp = httpClient.execute(post);
|
||||||
|
|
||||||
|
// 获得起始行
|
||||||
|
StatusLine status = resp.getStatusLine();
|
||||||
|
// 获取实体
|
||||||
|
if (HttpServiceUtil.success(status)) {
|
||||||
|
// 获取实体
|
||||||
|
HttpEntity entity = resp.getEntity();
|
||||||
|
// 编码格式
|
||||||
|
result = EntityUtils.toString(entity, encoding);
|
||||||
|
// 释放实体 response.close();//关闭响应
|
||||||
|
EntityUtils.consume(entity);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("doHttpsPost", e);
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
if (httpClient != null) {
|
||||||
|
httpClient.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String doGet(String requestUrl, String encoding) throws Exception {
|
||||||
|
String result = HttpServiceUtil.REQUEST_NO_RESULT;
|
||||||
|
// build client 对象
|
||||||
|
CloseableHttpClient httpClient = null;
|
||||||
|
try {
|
||||||
|
httpClient = SslUtil.sslHttpClientBuild();
|
||||||
|
requestUrl = requestUrl.replaceAll("\\s*", "");
|
||||||
|
HttpGet get = new HttpGet(requestUrl);
|
||||||
|
// 请求首部--可选的,User-Agent对于一些服务器必选,不加可能不会返回正确结果
|
||||||
|
get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64;rv:39.0) Gecko/20100101 Firefox/39.0");
|
||||||
|
// Exec Request
|
||||||
|
CloseableHttpResponse resp = httpClient.execute(get);
|
||||||
|
// 获得起始行
|
||||||
|
StatusLine status = resp.getStatusLine();
|
||||||
|
if (HttpServiceUtil.success(status)) {
|
||||||
|
// 获取实体
|
||||||
|
HttpEntity entity = resp.getEntity();
|
||||||
|
// 编码格式
|
||||||
|
result = EntityUtils.toString(entity, encoding);
|
||||||
|
// 释放实体 response.close();//关闭响应
|
||||||
|
EntityUtils.consume(entity);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (httpClient != null) {
|
||||||
|
httpClient.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
package com.ycwl.basic.service.impl.mobile;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.ycwl.basic.config.WechatConfig;
|
||||||
|
import com.ycwl.basic.constant.BaseContextHandler;
|
||||||
|
import com.ycwl.basic.constant.NumberConstant;
|
||||||
|
import com.ycwl.basic.constant.WeiXinConstant;
|
||||||
|
import com.ycwl.basic.enums.AgreementEnum;
|
||||||
|
import com.ycwl.basic.enums.BizCodeEnum;
|
||||||
|
import com.ycwl.basic.enums.WechatErrorCodeEnum;
|
||||||
|
import com.ycwl.basic.exception.AppException;
|
||||||
|
import com.ycwl.basic.mapper.pc.MemberMapper;
|
||||||
|
import com.ycwl.basic.model.jwt.JwtInfo;
|
||||||
|
import com.ycwl.basic.model.mobile.DTO.WeChatUserInfoDTO;
|
||||||
|
import com.ycwl.basic.model.mobile.DTO.WeChatUserInfoUpdateDTO;
|
||||||
|
import com.ycwl.basic.model.pc.member.entity.MemberEntity;
|
||||||
|
import com.ycwl.basic.model.pc.member.req.MemberReqQuery;
|
||||||
|
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
|
||||||
|
import com.ycwl.basic.service.HttpService;
|
||||||
|
import com.ycwl.basic.service.mobile.AppMemberService;
|
||||||
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
|
import com.ycwl.basic.utils.BeanCopierUtils;
|
||||||
|
import com.ycwl.basic.utils.JwtTokenUtil;
|
||||||
|
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:songmingsong
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class AppMemberServiceImpl implements AppMemberService {
|
||||||
|
@Autowired
|
||||||
|
private WechatConfig config;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HttpService httpService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MemberMapper memberMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JwtTokenUtil jwtTokenUtil;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getOpenId(String code) {
|
||||||
|
Map<String, String> paramMap = new HashMap<>(NumberConstant.FOUR);
|
||||||
|
paramMap.put("appid", config.getMiniProgramAppId());
|
||||||
|
paramMap.put("secret", config.getMiniProgramSecret());
|
||||||
|
paramMap.put("js_code", code);
|
||||||
|
paramMap.put("grant_type", config.getGrandType());
|
||||||
|
try {
|
||||||
|
String response = httpService.doHttpsPost(WeiXinConstant.GET_OPEN_ID, paramMap, "UTF-8");
|
||||||
|
if (StringUtils.isBlank(response)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
return mapper.readValue(response, Map.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("getOpenId", e);
|
||||||
|
throw new AppException(BizCodeEnum.SERVER_INTERNAL_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse login(String code, WeChatUserInfoDTO userInfoDTO) throws Exception {
|
||||||
|
Map<String, Object> weixinResponse = this.getOpenId(code);
|
||||||
|
if (CollectionUtils.isEmpty(weixinResponse)) {
|
||||||
|
throw new AppException(BizCodeEnum.SERVER_INTERNAL_ERROR);
|
||||||
|
}
|
||||||
|
Object errcode = weixinResponse.get("errcode");
|
||||||
|
if (errcode != null) {
|
||||||
|
WechatErrorCodeEnum errorCode = WechatErrorCodeEnum.getErrorCode(errcode.toString());
|
||||||
|
throw new AppException(BizCodeEnum.PARAM_ERROR.getCode(), errorCode.getDetail());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取openId
|
||||||
|
Object openId = weixinResponse.get("openid");
|
||||||
|
if (openId == null) {
|
||||||
|
log.warn("warning={}", "未获取到当前用户openId");
|
||||||
|
throw new AppException(BizCodeEnum.SERVER_UNKONWN_ERROR, "未获取到当前用户openId");
|
||||||
|
}
|
||||||
|
|
||||||
|
MemberRespVO memberRespVO = new MemberRespVO();
|
||||||
|
JwtInfo jwtInfo = new JwtInfo();
|
||||||
|
// 根据返回的openId,判断用户是否是新用户,是的话,将用户信息存到数据库;
|
||||||
|
MemberReqQuery memberReqQuery = new MemberReqQuery();
|
||||||
|
memberReqQuery.setOpenId(openId.toString());
|
||||||
|
List<MemberRespVO> list = memberMapper.list(memberReqQuery);
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
MemberEntity memberEntity = new MemberEntity();
|
||||||
|
memberEntity.setId(SnowFlakeUtil.getLongId());
|
||||||
|
BeanCopierUtils.copyProperties(userInfoDTO, memberEntity);
|
||||||
|
memberMapper.add(memberEntity);
|
||||||
|
BeanCopierUtils.copyProperties(memberEntity, memberRespVO);
|
||||||
|
} else {
|
||||||
|
BeanCopierUtils.copyProperties(list.get(NumberConstant.ZERO), memberRespVO);
|
||||||
|
}
|
||||||
|
jwtInfo.setUserId(memberRespVO.getId().toString());
|
||||||
|
jwtInfo.setName(memberRespVO.getNickname());
|
||||||
|
jwtInfo.setPhone(memberRespVO.getPhone());
|
||||||
|
|
||||||
|
String jwt = jwtTokenUtil.generateToken(jwtInfo);
|
||||||
|
Map<String, Object> resMap = new HashMap<>();
|
||||||
|
resMap.put("token", jwt);
|
||||||
|
resMap.put("user", memberRespVO);
|
||||||
|
|
||||||
|
return ApiResponse.success(resMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<MemberRespVO> getUserInfo() {
|
||||||
|
MemberRespVO respVO = memberMapper.getById(Long.parseLong(BaseContextHandler.getUserId()));
|
||||||
|
return ApiResponse.success(respVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<?> update(WeChatUserInfoUpdateDTO userInfoUpdateDTO) {
|
||||||
|
MemberEntity memberEntity = new MemberEntity();
|
||||||
|
memberEntity.setId(Long.parseLong(BaseContextHandler.getUserId()));
|
||||||
|
BeanCopierUtils.copyProperties(userInfoUpdateDTO, memberEntity);
|
||||||
|
return ApiResponse.success(memberMapper.update(memberEntity));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<?> agreement() {
|
||||||
|
MemberEntity memberEntity = new MemberEntity();
|
||||||
|
memberEntity.setId(Long.parseLong(BaseContextHandler.getUserId()));
|
||||||
|
memberEntity.setAgreement(AgreementEnum.AGREE.getType());
|
||||||
|
return ApiResponse.success(memberMapper.update(memberEntity));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,201 @@
|
|||||||
|
package com.ycwl.basic.service.impl.mobile;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.wechat.pay.java.core.Config;
|
||||||
|
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||||||
|
import com.wechat.pay.java.core.exception.ServiceException;
|
||||||
|
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.payments.jsapi.JsapiService;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.*;
|
||||||
|
import com.wechat.pay.java.service.payments.model.TransactionAmount;
|
||||||
|
import com.ycwl.basic.config.WechatConfig;
|
||||||
|
import com.ycwl.basic.constant.WeiXinConstant;
|
||||||
|
import com.ycwl.basic.enums.BizCodeEnum;
|
||||||
|
import com.ycwl.basic.enums.OrderStateEnum;
|
||||||
|
import com.ycwl.basic.exception.AppException;
|
||||||
|
import com.ycwl.basic.mapper.pc.OrderMapper;
|
||||||
|
import com.ycwl.basic.model.wxPay.WXPayOrderReqVO;
|
||||||
|
import com.ycwl.basic.model.wxPay.WxPayRespVO;
|
||||||
|
import com.ycwl.basic.model.wxPay.WxchatCallbackSuccessData;
|
||||||
|
import com.ycwl.basic.service.mobile.WxPayService;
|
||||||
|
import com.ycwl.basic.service.pc.OrderService;
|
||||||
|
import com.ycwl.basic.utils.WXPayUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.wechat.pay.java.core.http.Constant.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 微信支付实现
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class WxPayServiceImpl implements WxPayService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WechatConfig wechatConfig;
|
||||||
|
@Autowired
|
||||||
|
private OrderMapper orderMapper;
|
||||||
|
@Autowired
|
||||||
|
private OrderService orderService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxPayRespVO createOrder(WXPayOrderReqVO req) {
|
||||||
|
try {
|
||||||
|
// 使用自动更新平台证书的RSA配置
|
||||||
|
// 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
|
||||||
|
Config config =
|
||||||
|
new RSAAutoCertificateConfig.Builder()
|
||||||
|
.merchantId(wechatConfig.getMchId())
|
||||||
|
.privateKeyFromPath(wechatConfig.getKeyPath())
|
||||||
|
.merchantSerialNumber(wechatConfig.getMchSerialNo())
|
||||||
|
.apiV3Key(wechatConfig.getApiV3())
|
||||||
|
.build();
|
||||||
|
// 构建service
|
||||||
|
JsapiService service = new JsapiService.Builder().config(config).build();
|
||||||
|
|
||||||
|
// request.setXxx(val)设置所需参数,具体参数可见Request定义
|
||||||
|
PrepayRequest request = new PrepayRequest();
|
||||||
|
Amount amount = new Amount();
|
||||||
|
amount.setTotal(req.getTotalPrice());
|
||||||
|
request.setAmount(amount);
|
||||||
|
request.setAppid(wechatConfig.getAppId());
|
||||||
|
request.setMchid(wechatConfig.getMchId());
|
||||||
|
request.setDescription(req.getGoodsName());
|
||||||
|
request.setNotifyUrl(wechatConfig.getNotifyUrl());
|
||||||
|
request.setOutTradeNo(req.getOrderSn().toString());
|
||||||
|
|
||||||
|
Payer payer = new Payer();
|
||||||
|
payer.setOpenid(req.getOpenId());
|
||||||
|
request.setPayer(payer);
|
||||||
|
|
||||||
|
// 调用下单方法,得到应答
|
||||||
|
PrepayResponse response = service.prepay(request);
|
||||||
|
WxPayRespVO vo = new WxPayRespVO();
|
||||||
|
Long timeStamp = System.currentTimeMillis() / 1000;
|
||||||
|
vo.setTimeStamp(timeStamp);
|
||||||
|
String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
|
||||||
|
vo.setNonceStr(substring);
|
||||||
|
String signatureStr = Stream.of(wechatConfig.getAppId(), String.valueOf(timeStamp), substring, "prepay_id=" + response.getPrepayId())
|
||||||
|
.collect(Collectors.joining("\n", "", "\n"));
|
||||||
|
String sign = WXPayUtil.getSign(signatureStr, wechatConfig.getKeyPath());
|
||||||
|
vo.setPaySign(sign);
|
||||||
|
vo.setPrepayId("prepay_id=" + response.getPrepayId());
|
||||||
|
return vo;
|
||||||
|
} catch (ServiceException e) {
|
||||||
|
JSONObject parse = JSONObject.parseObject(e.getResponseBody());
|
||||||
|
throw new AppException(BizCodeEnum.ADVANCE_PAYMENT_FAILED, parse.getString("message"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new AppException(BizCodeEnum.ADVANCE_PAYMENT_FAILED, e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void payNotify(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 s1 = stringBuffer.toString();
|
||||||
|
String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
|
||||||
|
String nonce = request.getHeader(WECHAT_PAY_NONCE);
|
||||||
|
String signType = request.getHeader(WeiXinConstant.WECHATPAY_SIGNATURE_TYPE);
|
||||||
|
String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
|
||||||
|
String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
|
||||||
|
|
||||||
|
NotificationConfig config = new RSAAutoCertificateConfig.Builder()
|
||||||
|
.merchantId(wechatConfig.getMchId())
|
||||||
|
.privateKeyFromPath(wechatConfig.getKeyPath())
|
||||||
|
.merchantSerialNumber(wechatConfig.getMchSerialNo())
|
||||||
|
.apiV3Key(wechatConfig.getApiV3())
|
||||||
|
.build();
|
||||||
|
// 初始化 NotificationParser
|
||||||
|
NotificationParser parser = new NotificationParser(config);
|
||||||
|
RequestParam requestParam = new RequestParam.Builder()
|
||||||
|
.serialNumber(serialNo)
|
||||||
|
.nonce(nonce)
|
||||||
|
.signature(signature)
|
||||||
|
.timestamp(timestamp)
|
||||||
|
// 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
|
||||||
|
.signType(signType)
|
||||||
|
.body(s1)
|
||||||
|
.build();
|
||||||
|
Transaction parse = parser.parse(requestParam, Transaction.class);
|
||||||
|
log.info("[微信支付]parse = {}", parse);
|
||||||
|
|
||||||
|
// 更新订单信息
|
||||||
|
new Thread(() -> {
|
||||||
|
Transaction.TradeStateEnum tradeState = parse.getTradeState();
|
||||||
|
OrderStateEnum OrderStateEnum = null;
|
||||||
|
if (Transaction.TradeStateEnum.SUCCESS == tradeState) {
|
||||||
|
OrderStateEnum = OrderStateEnum.PAID;
|
||||||
|
}
|
||||||
|
if (Objects.nonNull(OrderStateEnum)) {
|
||||||
|
orderService.updateOrderState(Long.parseLong(parse.getOutTradeNo()), OrderStateEnum, null);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new AppException(BizCodeEnum.ADVANCE_PAYMENT_CALLBACK_FAILED, e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxchatCallbackSuccessData queryPay(Long orderId) {
|
||||||
|
WxchatCallbackSuccessData wxchatCallbackSuccessData = new WxchatCallbackSuccessData();
|
||||||
|
QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
|
||||||
|
queryRequest.setMchid(wechatConfig.getMchId());
|
||||||
|
queryRequest.setOutTradeNo(orderId.toString());
|
||||||
|
// 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
|
||||||
|
Config config =
|
||||||
|
new RSAAutoCertificateConfig.Builder()
|
||||||
|
.merchantId(wechatConfig.getMchId())
|
||||||
|
.privateKeyFromPath(wechatConfig.getKeyPath())
|
||||||
|
.merchantSerialNumber(wechatConfig.getMchSerialNo())
|
||||||
|
.apiV3Key(wechatConfig.getApiV3())
|
||||||
|
.build();
|
||||||
|
// 构建service
|
||||||
|
JsapiService service = new JsapiService.Builder().config(config).build();
|
||||||
|
try {
|
||||||
|
com.wechat.pay.java.service.payments.model.Transaction transaction = service.queryOrderByOutTradeNo(queryRequest);
|
||||||
|
String successTime = transaction.getSuccessTime();
|
||||||
|
|
||||||
|
|
||||||
|
wxchatCallbackSuccessData.setOrderId(orderId.toString());
|
||||||
|
wxchatCallbackSuccessData.setSuccessTime(successTime);
|
||||||
|
wxchatCallbackSuccessData.setTradetype(WeiXinConstant.getDescriptionType(transaction.getTradeType()));
|
||||||
|
wxchatCallbackSuccessData.setTradestate(WeiXinConstant.getDescriptionState(transaction.getTradeState()));
|
||||||
|
TransactionAmount amount = transaction.getAmount();
|
||||||
|
Integer total = amount.getTotal();
|
||||||
|
wxchatCallbackSuccessData.setTotalMoney(new BigDecimal(total).movePointLeft(2));
|
||||||
|
} catch (ServiceException e) {
|
||||||
|
// API返回失败, 例如ORDER_NOT_EXISTS
|
||||||
|
log.error("code={}, message={}", e.getErrorCode(), e.getErrorMessage());
|
||||||
|
log.error("reponse body={}", e.getResponseBody());
|
||||||
|
}
|
||||||
|
return wxchatCallbackSuccessData;
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,8 @@ package com.ycwl.basic.service.impl.pc;
|
|||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
|
import com.ycwl.basic.constant.NumberConstant;
|
||||||
|
import com.ycwl.basic.enums.OrderStateEnum;
|
||||||
import com.ycwl.basic.mapper.pc.OrderMapper;
|
import com.ycwl.basic.mapper.pc.OrderMapper;
|
||||||
import com.ycwl.basic.model.pc.order.entity.OrderItemEntity;
|
import com.ycwl.basic.model.pc.order.entity.OrderItemEntity;
|
||||||
import com.ycwl.basic.model.pc.order.req.OrderAddOrUpdateReq;
|
import com.ycwl.basic.model.pc.order.req.OrderAddOrUpdateReq;
|
||||||
@ -18,6 +20,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,4 +85,28 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
}
|
}
|
||||||
return ApiResponse.success(update);
|
return ApiResponse.success(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新订单支付状态
|
||||||
|
*
|
||||||
|
* @param orderSn 订单编号也就是订单的ID
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void updateOrderState(Long orderSn, OrderStateEnum orderStateEnum, String refundReason) {
|
||||||
|
OrderAddOrUpdateReq orderAddOrUpdateReq = new OrderAddOrUpdateReq();
|
||||||
|
orderAddOrUpdateReq.setId(orderSn);
|
||||||
|
if (orderStateEnum.getType() == NumberConstant.ONE) {
|
||||||
|
orderAddOrUpdateReq.setRefundStatus(orderStateEnum.getState());
|
||||||
|
orderAddOrUpdateReq.setRefundAt(new Date());
|
||||||
|
orderAddOrUpdateReq.setRefundReason(refundReason);
|
||||||
|
} else if (orderStateEnum.getType() == NumberConstant.TWO) {
|
||||||
|
int state = orderStateEnum.getState();
|
||||||
|
orderAddOrUpdateReq.setPayAt(new Date());
|
||||||
|
orderAddOrUpdateReq.setStatus(orderStateEnum.getState());
|
||||||
|
if (state == OrderStateEnum.CANCELED.getState()) {
|
||||||
|
orderAddOrUpdateReq.setCancelAt(new Date());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
orderMapper.update(orderAddOrUpdateReq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.ycwl.basic.service.mobile;
|
||||||
|
|
||||||
|
import com.ycwl.basic.model.mobile.DTO.WeChatUserInfoDTO;
|
||||||
|
import com.ycwl.basic.model.mobile.DTO.WeChatUserInfoUpdateDTO;
|
||||||
|
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
|
||||||
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:songmingsong
|
||||||
|
*/
|
||||||
|
public interface AppMemberService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户的openId
|
||||||
|
*
|
||||||
|
* @return Map
|
||||||
|
*/
|
||||||
|
Map<String, Object> getOpenId(String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
*
|
||||||
|
* @param code 前端授权码
|
||||||
|
* @param userInfoDTO 实体信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ApiResponse login(String code, WeChatUserInfoDTO userInfoDTO) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户信息
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ApiResponse<MemberRespVO> getUserInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改信息
|
||||||
|
*
|
||||||
|
* @param userInfoUpdateDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ApiResponse<?> update(WeChatUserInfoUpdateDTO userInfoUpdateDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同意用户协议
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ApiResponse<?> agreement();
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.ycwl.basic.service.mobile;
|
||||||
|
|
||||||
|
import com.ycwl.basic.model.wxPay.WXPayOrderReqVO;
|
||||||
|
import com.ycwl.basic.model.wxPay.WxPayRespVO;
|
||||||
|
import com.ycwl.basic.model.wxPay.WxchatCallbackSuccessData;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
public interface WxPayService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信预支付
|
||||||
|
*/
|
||||||
|
WxPayRespVO createOrder(WXPayOrderReqVO req) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付回调
|
||||||
|
*/
|
||||||
|
void payNotify(HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付结果查询
|
||||||
|
*/
|
||||||
|
WxchatCallbackSuccessData queryPay(Long orderId);
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package com.ycwl.basic.service.pc;
|
package com.ycwl.basic.service.pc;
|
||||||
|
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.ycwl.basic.model.pc.order.entity.OrderEntity;
|
import com.ycwl.basic.enums.OrderStateEnum;
|
||||||
import com.ycwl.basic.model.pc.order.req.OrderAddOrUpdateReq;
|
import com.ycwl.basic.model.pc.order.req.OrderAddOrUpdateReq;
|
||||||
import com.ycwl.basic.model.pc.order.req.OrderReqQuery;
|
import com.ycwl.basic.model.pc.order.req.OrderReqQuery;
|
||||||
import com.ycwl.basic.model.pc.order.resp.OrderRespVO;
|
import com.ycwl.basic.model.pc.order.resp.OrderRespVO;
|
||||||
@ -19,4 +19,7 @@ public interface OrderService {
|
|||||||
ApiResponse<OrderRespVO> detail(Long orderId);
|
ApiResponse<OrderRespVO> detail(Long orderId);
|
||||||
ApiResponse<Integer> add(OrderAddOrUpdateReq query);
|
ApiResponse<Integer> add(OrderAddOrUpdateReq query);
|
||||||
ApiResponse<Integer> update(OrderAddOrUpdateReq query);
|
ApiResponse<Integer> update(OrderAddOrUpdateReq query);
|
||||||
|
|
||||||
|
|
||||||
|
void updateOrderState(Long orderSn, OrderStateEnum orderStateEnum, String refundReason);
|
||||||
}
|
}
|
||||||
|
@ -142,8 +142,8 @@ public class ApiResponse<T> implements Serializable {
|
|||||||
|
|
||||||
public static <T> ApiResponse<T> buildResult(BizCodeEnum bizCodeEnum) {
|
public static <T> ApiResponse<T> buildResult(BizCodeEnum bizCodeEnum) {
|
||||||
ApiResponse<T> apiResponse = new ApiResponse();
|
ApiResponse<T> apiResponse = new ApiResponse();
|
||||||
apiResponse.setCode(bizCodeEnum.code);
|
apiResponse.setCode(bizCodeEnum.getCode());
|
||||||
apiResponse.setMsg(bizCodeEnum.message);
|
apiResponse.setMsg(bizCodeEnum.getMessage());
|
||||||
|
|
||||||
return apiResponse;
|
return apiResponse;
|
||||||
}
|
}
|
||||||
|
31
src/main/java/com/ycwl/basic/utils/HttpServiceUtil.java
Normal file
31
src/main/java/com/ycwl/basic/utils/HttpServiceUtil.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package com.ycwl.basic.utils;
|
||||||
|
|
||||||
|
import org.apache.http.StatusLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http服务工具类
|
||||||
|
* @author songmingsong
|
||||||
|
*/
|
||||||
|
public class HttpServiceUtil {
|
||||||
|
/**
|
||||||
|
* 请求OK代码
|
||||||
|
*/
|
||||||
|
public static final int REQUEST_OK_CODE=200;
|
||||||
|
/**
|
||||||
|
* 无响应内容
|
||||||
|
*/
|
||||||
|
public static final String REQUEST_NO_RESULT="No_Result";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否响应成功
|
||||||
|
* @param status 响应状态
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static boolean success(StatusLine status) {
|
||||||
|
return status.getStatusCode() == REQUEST_OK_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -60,55 +60,4 @@ public class JwtTokenUtil {
|
|||||||
throw new CheckTokenException("token is invalid");
|
throw new CheckTokenException("token is invalid");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************** 测试 ***************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 测试 token
|
|
||||||
*
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
// public static void main(String[] args) throws Exception {
|
|
||||||
//
|
|
||||||
// JwtInfo jwtInfo = new JwtInfo("阿豹", "1", "role1", "yangchen", 1, LocalDateTime.now(), new HashMap<>());
|
|
||||||
//
|
|
||||||
// long a = Instant.now().toEpochMilli();
|
|
||||||
//
|
|
||||||
// JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
|
|
||||||
// String token = jwtTokenUtil.generateToken(jwtInfo);
|
|
||||||
//
|
|
||||||
// log.info("==> generate token: " + (Instant.now().toEpochMilli() - a) + " ms");
|
|
||||||
//
|
|
||||||
// System.out.println("=======");
|
|
||||||
// System.out.println();
|
|
||||||
//
|
|
||||||
// System.out.println(token);
|
|
||||||
//
|
|
||||||
// System.out.println();
|
|
||||||
// System.out.println("=======");
|
|
||||||
//
|
|
||||||
// long b = Instant.now().toEpochMilli();
|
|
||||||
//
|
|
||||||
// JwtInfo jwtInfo1 = jwtTokenUtil.parsingToken(token);
|
|
||||||
//
|
|
||||||
// log.info("==> paring token end " + (Instant.now().toEpochMilli() - b) + " ms");
|
|
||||||
//
|
|
||||||
// System.out.println();
|
|
||||||
// System.out.println();
|
|
||||||
// System.out.println();
|
|
||||||
// System.out.println(jwtInfo);
|
|
||||||
// System.out.println("=======");
|
|
||||||
// System.out.println(jwtInfo1.toString());
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
JwtInfo jwtInfo = new JwtInfo();
|
|
||||||
jwtInfo.setUserId("1");
|
|
||||||
LocalDateTime expireTime = LocalDateTime.now().plusDays(9999999);
|
|
||||||
byte[] bytes = RsaKeyUtil.toBytes(PRI_KEY);
|
|
||||||
String token = JwtAnalysisUtil.generateToken(jwtInfo, bytes, expireTime);
|
|
||||||
System.out.println(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
85
src/main/java/com/ycwl/basic/utils/OssUtil.java
Normal file
85
src/main/java/com/ycwl/basic/utils/OssUtil.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package com.ycwl.basic.utils;
|
||||||
|
|
||||||
|
import com.aliyun.oss.ClientException;
|
||||||
|
import com.aliyun.oss.OSS;
|
||||||
|
import com.aliyun.oss.OSSClientBuilder;
|
||||||
|
import com.aliyun.oss.OSSException;
|
||||||
|
import com.aliyun.oss.model.PutObjectRequest;
|
||||||
|
import com.ycwl.basic.config.OssConfig;
|
||||||
|
import com.ycwl.basic.enums.BizCodeEnum;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class OssUtil {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OssConfig ossConfig;
|
||||||
|
|
||||||
|
public String uploadFile(InputStream inputStream, String filename) {
|
||||||
|
String uploadFileName = ossConfig.getObjectName() + System.currentTimeMillis() + filename.substring(filename.lastIndexOf("."));
|
||||||
|
OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndPoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
|
||||||
|
try {
|
||||||
|
PutObjectRequest putObjectRequest = new PutObjectRequest(ossConfig.getBucketName(), uploadFileName, inputStream);
|
||||||
|
ossClient.putObject(putObjectRequest);
|
||||||
|
String fileUrl = ossConfig.getUrl() + uploadFileName;
|
||||||
|
return fileUrl;
|
||||||
|
} catch (OSSException oe) {
|
||||||
|
log.error("Caught an OSSException, which means your request made it to OSS, "
|
||||||
|
+ "but was rejected with an error response for some reason."
|
||||||
|
+ " \n Error Message:" + oe.getErrorMessage()
|
||||||
|
+ " \n Error Code:" + oe.getErrorCode()
|
||||||
|
+ " \n Request ID:" + oe.getRequestId()
|
||||||
|
+ " \n Host ID:" + oe.getHostId()
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (ClientException ce) {
|
||||||
|
log.error("Caught an ClientException, which means the client encountered "
|
||||||
|
+ "a serious internal problem while trying to communicate with OSS, "
|
||||||
|
+ "such as not being able to access the network."
|
||||||
|
+ "Error Message:" + ce.getMessage());
|
||||||
|
} finally {
|
||||||
|
if (ossClient != null) {
|
||||||
|
ossClient.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return BizCodeEnum.UPLOAD_FAILED.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean deleteFile(String filename) {
|
||||||
|
// 填写文件完整路径。文件完整路径中不能包含Bucket名称。
|
||||||
|
String objectName = filename;
|
||||||
|
|
||||||
|
OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndPoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
|
||||||
|
try {
|
||||||
|
// 删除文件或目录。如果要删除目录,目录必须为空。
|
||||||
|
ossClient.deleteObject(ossConfig.getBucketName(), objectName);
|
||||||
|
return true;
|
||||||
|
} catch (OSSException oe) {
|
||||||
|
log.error("Caught an OSSException, which means your request made it to OSS, "
|
||||||
|
+ "but was rejected with an error response for some reason."
|
||||||
|
+ " \n Error Message:" + oe.getErrorMessage()
|
||||||
|
+ " \n Error Code:" + oe.getErrorCode()
|
||||||
|
+ " \n Request ID:" + oe.getRequestId()
|
||||||
|
+ " \n Host ID:" + oe.getHostId()
|
||||||
|
);
|
||||||
|
} catch (ClientException ce) {
|
||||||
|
log.error("Caught an ClientException, which means the client encountered "
|
||||||
|
+ "a serious internal problem while trying to communicate with OSS, "
|
||||||
|
+ "such as not being able to access the network."
|
||||||
|
+ "Error Message:" + ce.getMessage());
|
||||||
|
} finally {
|
||||||
|
if (ossClient != null) {
|
||||||
|
ossClient.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
98
src/main/java/com/ycwl/basic/utils/SslUtil.java
Normal file
98
src/main/java/com/ycwl/basic/utils/SslUtil.java
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package com.ycwl.basic.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.http.config.Registry;
|
||||||
|
import org.apache.http.config.RegistryBuilder;
|
||||||
|
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSL工具类
|
||||||
|
*
|
||||||
|
* @author songmingsong
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SslUtil {
|
||||||
|
/**
|
||||||
|
* 获取HtttpClient对象
|
||||||
|
*
|
||||||
|
* @return CloseableHttpClient
|
||||||
|
*/
|
||||||
|
public static CloseableHttpClient sslHttpClientBuild() {
|
||||||
|
Registry<ConnectionSocketFactory> socketFactoryRegistry =
|
||||||
|
RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE)
|
||||||
|
.register("https", trustAllHttpsCertificates()).build();
|
||||||
|
// 创建ConnectionManager,添加Connection配置信息
|
||||||
|
PoolingHttpClientConnectionManager connectionManager =
|
||||||
|
new PoolingHttpClientConnectionManager(socketFactoryRegistry);
|
||||||
|
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 信任所有Http证书
|
||||||
|
*
|
||||||
|
* @return SSLConnectionSocketFactory
|
||||||
|
*/
|
||||||
|
private static SSLConnectionSocketFactory trustAllHttpsCertificates() {
|
||||||
|
SSLConnectionSocketFactory socketFactory = null;
|
||||||
|
TrustManager[] trustAllCerts = new TrustManager[1];
|
||||||
|
TrustManager tm = new X509TrustManager() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
// 返回受信任的X509证书数组。
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
// 该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。
|
||||||
|
// 在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。
|
||||||
|
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
try {
|
||||||
|
if (chain!=null&&chain.length>0) {
|
||||||
|
chain[0].checkValidity();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("checkServerTrusted",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
// 该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证,
|
||||||
|
// 因此我们只需要执行默认的信任管理器的这个方法。JSSE中,默认的信任管理器类为TrustManager。
|
||||||
|
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
try {
|
||||||
|
if (chain!=null&&chain.length>0) {
|
||||||
|
chain[0].checkValidity();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("checkClientTrusted",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
trustAllCerts[0] = tm;
|
||||||
|
SSLContext sc = null;
|
||||||
|
try {
|
||||||
|
sc = SSLContext.getInstance("TLSv1.2");
|
||||||
|
sc.init(null, trustAllCerts, null);
|
||||||
|
socketFactory = new SSLConnectionSocketFactory(sc, NoopHostnameVerifier.INSTANCE);
|
||||||
|
// HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("trustAllHttpsCertificates", e);
|
||||||
|
}
|
||||||
|
return socketFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
49
src/main/java/com/ycwl/basic/utils/WXPayUtil.java
Normal file
49
src/main/java/com/ycwl/basic/utils/WXPayUtil.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package com.ycwl.basic.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import com.wechat.pay.java.core.util.PemUtil;
|
||||||
|
import org.springframework.util.Base64Utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.*;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: songmingsong
|
||||||
|
* @CreateTime: 2024-12-05
|
||||||
|
* @Description: 微信支付
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
public class WXPayUtil {
|
||||||
|
|
||||||
|
private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
private static final Random RANDOM = new SecureRandom();
|
||||||
|
|
||||||
|
|
||||||
|
public static String getSign(String signatureStr,String privateKey) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IOException, URISyntaxException {
|
||||||
|
//replace 根据实际情况,不一定都需要
|
||||||
|
String replace = privateKey.replace("\\n", "\n");
|
||||||
|
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromPath(replace);
|
||||||
|
Signature sign = Signature.getInstance("SHA256withRSA");
|
||||||
|
sign.initSign(merchantPrivateKey);
|
||||||
|
sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return Base64Utils.encodeToString(sign.sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取随机字符串 Nonce Str
|
||||||
|
*
|
||||||
|
* @return String 随机字符串
|
||||||
|
*/
|
||||||
|
public static String generateNonceStr() {
|
||||||
|
char[] nonceChars = new char[32];
|
||||||
|
for (int index = 0; index < nonceChars.length; ++index) {
|
||||||
|
nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
|
||||||
|
}
|
||||||
|
return new String(nonceChars);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -60,3 +60,38 @@ mybatis-plus:
|
|||||||
# 指定使用的日志配置文件
|
# 指定使用的日志配置文件
|
||||||
logging:
|
logging:
|
||||||
config: classpath:logback-spring.xml
|
config: classpath:logback-spring.xml
|
||||||
|
# 微信小程序相关配置
|
||||||
|
wx:
|
||||||
|
# 公众号的appId
|
||||||
|
appId: fix
|
||||||
|
# 公众号的密钥
|
||||||
|
appSecret: fix
|
||||||
|
# 小程序的AppId
|
||||||
|
miniProgramAppId: 1
|
||||||
|
# 小程序的secret
|
||||||
|
miniProgramSecret: 1
|
||||||
|
# 申请openid授权
|
||||||
|
grandType: authorization_code
|
||||||
|
# 推送模板
|
||||||
|
push:
|
||||||
|
templateId: 1
|
||||||
|
# 商户号
|
||||||
|
mchId: xxxx
|
||||||
|
# 商户证书序列号
|
||||||
|
mchSerialNo: xxxxx
|
||||||
|
# 回调接口地址
|
||||||
|
notifyUrl: https://xxxx/a/biz/wxpay/payNotify
|
||||||
|
# 商户API私钥路径
|
||||||
|
keyPath: module-app/src/main/resources/cert/apiclient_key.pem
|
||||||
|
# 商户APIV3密钥
|
||||||
|
apiV3: 1
|
||||||
|
|
||||||
|
#阿里云OSS
|
||||||
|
aliYunOss:
|
||||||
|
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
|
||||||
|
accessKeyId: "LTAI5t5cydpGpHfYqf31mEJA"
|
||||||
|
accessKeySecret: "xdFzlwzmE8QPPstbcZY82tU3xj7G0R"
|
||||||
|
bucketName: "scwzzn-file"
|
||||||
|
objectName: "image/"
|
||||||
|
url: "https://scwzzn-file.oss-cn-chengdu.aliyuncs.com/"
|
||||||
|
region: "cn-hangzhou"
|
Loading…
x
Reference in New Issue
Block a user