配置、记录请求、支付
This commit is contained in:
parent
d70bfbc605
commit
5249cc2cc8
11
src/main/java/com/ycwl/basic/annotation/RequestToFile.java
Normal file
11
src/main/java/com/ycwl/basic/annotation/RequestToFile.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package com.ycwl.basic.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value = {ElementType.METHOD})
|
||||||
|
public @interface RequestToFile {
|
||||||
|
}
|
63
src/main/java/com/ycwl/basic/aspectj/HttpSaver.java
Normal file
63
src/main/java/com/ycwl/basic/aspectj/HttpSaver.java
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package com.ycwl.basic.aspectj;
|
||||||
|
|
||||||
|
import com.ycwl.basic.annotation.RequestToFile;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.After;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class HttpSaver {
|
||||||
|
|
||||||
|
@Pointcut("@annotation(com.ycwl.basic.annotation.RequestToFile)")
|
||||||
|
public void requestToFilePointCut() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@After("requestToFilePointCut()")
|
||||||
|
public void requestToFile() throws Throwable {
|
||||||
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
if (attributes == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HttpServletRequest request = attributes.getRequest();
|
||||||
|
StringBuilder rawReq = new StringBuilder();
|
||||||
|
rawReq.append(request.getMethod()).append(" ").append(request.getRequestURL());
|
||||||
|
String queryString = request.getQueryString();
|
||||||
|
if (queryString != null) {
|
||||||
|
rawReq.append("?").append(queryString);
|
||||||
|
}
|
||||||
|
rawReq.append("\r\n");
|
||||||
|
Enumeration<String> headerNames = request.getHeaderNames();
|
||||||
|
while (headerNames.hasMoreElements()) {
|
||||||
|
String headerName = headerNames.nextElement();
|
||||||
|
rawReq.append(headerName).append(": ").append(request.getHeader(headerName)).append("\r\n");
|
||||||
|
}
|
||||||
|
rawReq.append("\r\n");
|
||||||
|
// 获取body
|
||||||
|
rawReq.append(request.getReader().lines().collect(Collectors.joining("\r\n")));
|
||||||
|
rawReq.append("\r\n");
|
||||||
|
// 写入文件
|
||||||
|
File file = new File("./request/"+System.currentTimeMillis()+".http");
|
||||||
|
if (!file.getParentFile().exists()) {
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
|
if (!file.exists()) {
|
||||||
|
file.createNewFile();
|
||||||
|
}
|
||||||
|
try (java.io.FileWriter writer = new java.io.FileWriter(file, true)) {
|
||||||
|
writer.write(rawReq.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@ package com.ycwl.basic.controller.mobile;
|
|||||||
|
|
||||||
|
|
||||||
import com.ycwl.basic.annotation.IgnoreToken;
|
import com.ycwl.basic.annotation.IgnoreToken;
|
||||||
|
import com.ycwl.basic.annotation.RequestToFile;
|
||||||
|
import com.ycwl.basic.aspectj.HttpSaver;
|
||||||
import com.ycwl.basic.enums.BizCodeEnum;
|
import com.ycwl.basic.enums.BizCodeEnum;
|
||||||
import com.ycwl.basic.model.wx.WXPayOrderReqVO;
|
import com.ycwl.basic.model.wx.WXPayOrderReqVO;
|
||||||
import com.ycwl.basic.model.wx.WxPayRespVO;
|
import com.ycwl.basic.model.wx.WxPayRespVO;
|
||||||
@ -42,6 +44,7 @@ public class AppWxPayController {
|
|||||||
@ApiOperation(value = "微信支付回调", notes = "微信支付回调")
|
@ApiOperation(value = "微信支付回调", notes = "微信支付回调")
|
||||||
@PostMapping("/payNotify")
|
@PostMapping("/payNotify")
|
||||||
@IgnoreToken
|
@IgnoreToken
|
||||||
|
@RequestToFile
|
||||||
public ApiResponse<?> payNotify(HttpServletRequest request) {
|
public ApiResponse<?> payNotify(HttpServletRequest request) {
|
||||||
wxPayService.payNotify(request);
|
wxPayService.payNotify(request);
|
||||||
return ApiResponse.success(BizCodeEnum.REQUEST_OK);
|
return ApiResponse.success(BizCodeEnum.REQUEST_OK);
|
||||||
@ -58,6 +61,7 @@ public class AppWxPayController {
|
|||||||
@ApiOperation(value = "微信支付退款回调", notes = "微信支付退款回调")
|
@ApiOperation(value = "微信支付退款回调", notes = "微信支付退款回调")
|
||||||
@PostMapping("/refundNotify")
|
@PostMapping("/refundNotify")
|
||||||
@IgnoreToken
|
@IgnoreToken
|
||||||
|
@RequestToFile
|
||||||
public ApiResponse<?> refundNotify(@RequestBody String refundResult) throws GeneralSecurityException, IOException {
|
public ApiResponse<?> refundNotify(@RequestBody String refundResult) throws GeneralSecurityException, IOException {
|
||||||
return ApiResponse.buildResult(wxPayService.refundNotify(refundResult) ?
|
return ApiResponse.buildResult(wxPayService.refundNotify(refundResult) ?
|
||||||
BizCodeEnum.SUCCESS :
|
BizCodeEnum.SUCCESS :
|
||||||
|
@ -26,4 +26,6 @@ public class WXPayOrderReqVO {
|
|||||||
|
|
||||||
@ApiModelProperty(value = "商品订单号",required = true)
|
@ApiModelProperty(value = "商品订单号",required = true)
|
||||||
private Long orderSn;
|
private Long orderSn;
|
||||||
|
|
||||||
|
private String description;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.ycwl.basic.service.impl.mobile;
|
package com.ycwl.basic.service.impl.mobile;
|
||||||
|
|
||||||
|
import com.ycwl.basic.constant.BaseContextHandler;
|
||||||
import com.ycwl.basic.mapper.*;
|
import com.ycwl.basic.mapper.*;
|
||||||
import com.ycwl.basic.model.jwt.JwtInfo;
|
import com.ycwl.basic.model.jwt.JwtInfo;
|
||||||
import com.ycwl.basic.model.mobile.goods.*;
|
import com.ycwl.basic.model.mobile.goods.*;
|
||||||
@ -43,14 +44,13 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
private FaceMapper faceMapper;
|
private FaceMapper faceMapper;
|
||||||
|
|
||||||
public ApiResponse<List<GoodsPageVO>> goodsList(GoodsReqQuery query) {
|
public ApiResponse<List<GoodsPageVO>> goodsList(GoodsReqQuery query) {
|
||||||
JwtInfo worker = JwtTokenUtil.getWorker();
|
|
||||||
//查询原素材
|
//查询原素材
|
||||||
List<GoodsPageVO> goodsList = new ArrayList<>();
|
List<GoodsPageVO> goodsList = new ArrayList<>();
|
||||||
|
|
||||||
VideoReqQuery videoReqQuery = new VideoReqQuery();
|
VideoReqQuery videoReqQuery = new VideoReqQuery();
|
||||||
videoReqQuery.setScenicId(query.getScenicId());
|
videoReqQuery.setScenicId(query.getScenicId());
|
||||||
videoReqQuery.setIsBuy(query.getIsBuy());
|
videoReqQuery.setIsBuy(query.getIsBuy());
|
||||||
videoReqQuery.setMemberId(worker.getUserId());
|
videoReqQuery.setMemberId(Long.valueOf(BaseContextHandler.getUserId()));
|
||||||
//查询成片vlog
|
//查询成片vlog
|
||||||
List<VideoRespVO> videoList = videoMapper.list(videoReqQuery);
|
List<VideoRespVO> videoList = videoMapper.list(videoReqQuery);
|
||||||
videoList.forEach(videoRespVO -> {
|
videoList.forEach(videoRespVO -> {
|
||||||
|
@ -90,13 +90,14 @@ public class WxPayServiceImpl implements WxPayService {
|
|||||||
// request.setXxx(val)设置所需参数,具体参数可见Request定义
|
// request.setXxx(val)设置所需参数,具体参数可见Request定义
|
||||||
PrepayRequest request = new PrepayRequest();
|
PrepayRequest request = new PrepayRequest();
|
||||||
Amount amount = new Amount();
|
Amount amount = new Amount();
|
||||||
amount.setTotal(req.getTotalPrice());
|
amount.setTotal(1);
|
||||||
request.setAmount(amount);
|
request.setAmount(amount);
|
||||||
request.setAppid(wechatConfig.getAppId());
|
request.setAppid(wechatConfig.getMiniProgramAppId());
|
||||||
request.setMchid(wechatConfig.getMchId());
|
request.setMchid(wechatConfig.getMchId());
|
||||||
request.setDescription(req.getGoodsName());
|
request.setDescription(req.getGoodsName());
|
||||||
request.setNotifyUrl(wechatConfig.getPayNotifyUrl());
|
request.setNotifyUrl(wechatConfig.getPayNotifyUrl());
|
||||||
request.setOutTradeNo(req.getOrderSn().toString());
|
request.setOutTradeNo(req.getOrderSn().toString());
|
||||||
|
request.setDescription(req.getDescription());
|
||||||
|
|
||||||
Payer payer = new Payer();
|
Payer payer = new Payer();
|
||||||
payer.setOpenid(req.getOpenId());
|
payer.setOpenid(req.getOpenId());
|
||||||
@ -109,7 +110,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|||||||
vo.setTimeStamp(timeStamp);
|
vo.setTimeStamp(timeStamp);
|
||||||
String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
|
String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
|
||||||
vo.setNonceStr(substring);
|
vo.setNonceStr(substring);
|
||||||
String signatureStr = Stream.of(wechatConfig.getAppId(), String.valueOf(timeStamp), substring, "prepay_id=" + response.getPrepayId())
|
String signatureStr = Stream.of(wechatConfig.getMiniProgramAppId(), String.valueOf(timeStamp), substring, "prepay_id=" + response.getPrepayId())
|
||||||
.collect(Collectors.joining("\n", "", "\n"));
|
.collect(Collectors.joining("\n", "", "\n"));
|
||||||
String sign = WXPayUtil.getSign(signatureStr, wechatConfig.getKeyPath());
|
String sign = WXPayUtil.getSign(signatureStr, wechatConfig.getKeyPath());
|
||||||
vo.setPaySign(sign);
|
vo.setPaySign(sign);
|
||||||
@ -137,6 +138,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|||||||
stringBuffer.append(s);
|
stringBuffer.append(s);
|
||||||
}
|
}
|
||||||
String s1 = stringBuffer.toString();
|
String s1 = stringBuffer.toString();
|
||||||
|
log.warn("微信支付回调:{}", s1);
|
||||||
String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
|
String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
|
||||||
String nonce = request.getHeader(WECHAT_PAY_NONCE);
|
String nonce = request.getHeader(WECHAT_PAY_NONCE);
|
||||||
String signType = request.getHeader(WeiXinConstant.WECHATPAY_SIGNATURE_TYPE);
|
String signType = request.getHeader(WeiXinConstant.WECHATPAY_SIGNATURE_TYPE);
|
||||||
@ -145,7 +147,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|||||||
|
|
||||||
NotificationConfig config = new RSAAutoCertificateConfig.Builder()
|
NotificationConfig config = new RSAAutoCertificateConfig.Builder()
|
||||||
.merchantId(wechatConfig.getMchId())
|
.merchantId(wechatConfig.getMchId())
|
||||||
.privateKeyFromPath(wechatConfig.getKeyPath())
|
.privateKey(wechatConfig.getKeyPath())
|
||||||
.merchantSerialNumber(wechatConfig.getMchSerialNo())
|
.merchantSerialNumber(wechatConfig.getMchSerialNo())
|
||||||
.apiV3Key(wechatConfig.getApiV3())
|
.apiV3Key(wechatConfig.getApiV3())
|
||||||
.build();
|
.build();
|
||||||
@ -401,7 +403,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|||||||
// 对参数进行加密
|
// 对参数进行加密
|
||||||
byte[] bytes = parameter.getBytes(String.valueOf(StandardCharsets.UTF_8));
|
byte[] bytes = parameter.getBytes(String.valueOf(StandardCharsets.UTF_8));
|
||||||
Signature sign = Signature.getInstance("SHA256withRSA");
|
Signature sign = Signature.getInstance("SHA256withRSA");
|
||||||
PrivateKey privateKey = PemUtil.loadPrivateKeyFromPath(wechatConfig.getKeyPath()); // privateKeyPath是商户证书密钥的位置apiclient_key.pem
|
PrivateKey privateKey = PemUtil.loadPrivateKeyFromString(wechatConfig.getKeyPath()); // privateKeyPath是商户证书密钥的位置apiclient_key.pem
|
||||||
sign.initSign(privateKey); // 商户密钥文件路径
|
sign.initSign(privateKey); // 商户密钥文件路径
|
||||||
sign.update(bytes);
|
sign.update(bytes);
|
||||||
String signature = Base64.getEncoder().encodeToString(sign.sign());
|
String signature = Base64.getEncoder().encodeToString(sign.sign());
|
||||||
@ -425,7 +427,7 @@ public class WxPayServiceImpl implements WxPayService {
|
|||||||
static void init(WechatConfig wechatConfig) {
|
static void init(WechatConfig wechatConfig) {
|
||||||
instance = new RSAAutoCertificateConfig.Builder()
|
instance = new RSAAutoCertificateConfig.Builder()
|
||||||
.merchantId(wechatConfig.getMchId())
|
.merchantId(wechatConfig.getMchId())
|
||||||
.privateKeyFromPath(wechatConfig.getKeyPath())
|
.privateKey(wechatConfig.getKeyPath())
|
||||||
.merchantSerialNumber(wechatConfig.getMchSerialNo())
|
.merchantSerialNumber(wechatConfig.getMchSerialNo())
|
||||||
.apiV3Key(wechatConfig.getApiV3())
|
.apiV3Key(wechatConfig.getApiV3())
|
||||||
.build();
|
.build();
|
||||||
|
@ -130,17 +130,17 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
orderItems.add(orderItemEntity);
|
orderItems.add(orderItemEntity);
|
||||||
|
|
||||||
//修改商品状态
|
//修改商品状态
|
||||||
if (Objects.equals(goodsType, GoodsTypeEnum.VIDEO.code)) {
|
// if (Objects.equals(goodsType, GoodsTypeEnum.VIDEO.code)) {
|
||||||
VideoEntity videoEntity = new VideoEntity();
|
// VideoEntity videoEntity = new VideoEntity();
|
||||||
videoEntity.setId(goodsId);
|
// videoEntity.setId(goodsId);
|
||||||
videoEntity.setIsBuy(1);
|
// videoEntity.setIsBuy(1);
|
||||||
videoMapper.update(videoEntity);
|
// videoMapper.update(videoEntity);
|
||||||
}else if (Objects.equals(goodsType, GoodsTypeEnum.SOURCE.code)) {
|
// }else if (Objects.equals(goodsType, GoodsTypeEnum.SOURCE.code)) {
|
||||||
SourceEntity sourceEntity = new SourceEntity();
|
// SourceEntity sourceEntity = new SourceEntity();
|
||||||
sourceEntity.setId(goodsId);
|
// sourceEntity.setId(goodsId);
|
||||||
sourceEntity.setIsBuy(1);
|
// sourceEntity.setIsBuy(1);
|
||||||
sourceMapper.update(sourceEntity);
|
// sourceMapper.update(sourceEntity);
|
||||||
}
|
// }
|
||||||
});
|
});
|
||||||
int addOrderItems = orderMapper.addOrderItems(orderItems);
|
int addOrderItems = orderMapper.addOrderItems(orderItems);
|
||||||
if (addOrderItems == NumberConstant.ZERO) {
|
if (addOrderItems == NumberConstant.ZERO) {
|
||||||
@ -157,12 +157,10 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
statisticsMapper.addStatisticsRecord(statisticsRecordAddReq);
|
statisticsMapper.addStatisticsRecord(statisticsRecordAddReq);
|
||||||
|
|
||||||
|
|
||||||
//TODO 封装微信支付请求
|
WxPayRespVO wxPayRespVO = initiatePayment(order, goodsDetailVO);
|
||||||
// WxPayRespVO wxPayRespVO = initiatePayment(order, goodsDetailVO);
|
return ApiResponse.success(wxPayRespVO);
|
||||||
// return ApiResponse.success(wxPayRespVO);
|
|
||||||
|
|
||||||
|
|
||||||
return ApiResponse.success(null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +185,8 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
wxPayOrderReqVO.setOpenId(order.getOpenid())
|
wxPayOrderReqVO.setOpenId(order.getOpenid())
|
||||||
.setOrderSn(order.getId())
|
.setOrderSn(order.getId())
|
||||||
.setTotalPrice(BigDecimalUtil.convertToCents(order.getPrice()))
|
.setTotalPrice(BigDecimalUtil.convertToCents(order.getPrice()))
|
||||||
.setGoodsName(goodsName);
|
.setGoodsName(goodsName)
|
||||||
|
.setDescription("VLOG视频支付");
|
||||||
|
|
||||||
return wxPayService.createOrder(wxPayOrderReqVO);
|
return wxPayService.createOrder(wxPayOrderReqVO);
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ public interface WxPayService {
|
|||||||
/**
|
/**
|
||||||
* 微信支付回调
|
* 微信支付回调
|
||||||
*/
|
*/
|
||||||
void payNotify(HttpServletRequest request);
|
void payNotify(HttpServletRequest xml);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付结果查询
|
* 微信支付结果查询
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.ycwl.basic.utils;
|
package com.ycwl.basic.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.util.XmlUtil;
|
||||||
import com.wechat.pay.java.core.util.PemUtil;
|
import com.wechat.pay.java.core.util.PemUtil;
|
||||||
import org.springframework.util.Base64Utils;
|
import org.springframework.util.Base64Utils;
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ import java.io.IOException;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +28,7 @@ public class WXPayUtil {
|
|||||||
public static String getSign(String signatureStr,String privateKey) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IOException, URISyntaxException {
|
public static String getSign(String signatureStr,String privateKey) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IOException, URISyntaxException {
|
||||||
//replace 根据实际情况,不一定都需要
|
//replace 根据实际情况,不一定都需要
|
||||||
String replace = privateKey.replace("\\n", "\n");
|
String replace = privateKey.replace("\\n", "\n");
|
||||||
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromPath(replace);
|
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromString(replace);
|
||||||
Signature sign = Signature.getInstance("SHA256withRSA");
|
Signature sign = Signature.getInstance("SHA256withRSA");
|
||||||
sign.initSign(merchantPrivateKey);
|
sign.initSign(merchantPrivateKey);
|
||||||
sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||||
@ -46,4 +48,7 @@ public class WXPayUtil {
|
|||||||
return new String(nonceChars);
|
return new String(nonceChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> xmlToMap(String xmlData) {
|
||||||
|
return XmlUtil.xmlToMap(xmlData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,34 @@ wx:
|
|||||||
# 退款回调接口地址
|
# 退款回调接口地址
|
||||||
refundNotifyUrl: https://zhentuai.com/api/mobile/wx/pay/v1/refundNotify
|
refundNotifyUrl: https://zhentuai.com/api/mobile/wx/pay/v1/refundNotify
|
||||||
# 商户API私钥路径
|
# 商户API私钥路径
|
||||||
keyPath: module-app/src/main/resources/cert/apiclient_key.pem
|
keyPath: "-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHwDoab8iRX4vn
|
||||||
|
Ta3a+gh5Z3wcyTM3VkWhkAPJGNJhaNgzOBI9b4v1x+uSZ4To2uXhQE5hvcxWSfNZ
|
||||||
|
F7H6yp+6estADeZLpdXLBDBvPDOjEGhG7YUHJjWnFh5eY2Rtnx4/7x+xCsRS+Mtq
|
||||||
|
Mx6KMrb4UZYNIq14peTQgfICkDBdqnUIkFjDmChUy0LlsSFW8AyJIqrBec5VZWf/
|
||||||
|
QqsIBf9vsTVxrqlX+5owYZuPYoFOIQJFUW8dfU20qk//BxiDjPFZBLNa02aIEbNF
|
||||||
|
SXZE2TlKD7zD0Qv/w95Hf1V+a/cxP2B6LNtqwioIdHbU6Axu7uHkr0RSPXPsvOWY
|
||||||
|
eUIpGP4bAgMBAAECggEBALm34w3TYtKu2D/tfDh9gkWGTuHgu6q2nrTxVmOxnWEN
|
||||||
|
/v3YIzVVsfaJs2ACuZNaeqNsi7PaqNKNnSD3o/X+UHYsVy8t/THWdSl1sqapfYUd
|
||||||
|
6yYPDkEwaG/6Y6/0j1pQt+pPpNKRpSlTwqTx9HIfZvkHuhBqbokfDNhECUQS1bUu
|
||||||
|
8pmyALIkuXu38B/xCs/EH+Lp1N69IA0mwalT/2zi9ZJhGNg5OWBzNbkMKf2Tck+9
|
||||||
|
SnS6s+pAT6YxB9qYhg645H3dRKXdeSYbjI+uiIe/7cJvTxfQDLD/oDap2TJQH3iM
|
||||||
|
SVbSfNFbR1tH6PiYx9eXeElEg2QXEPztbf8NcUlGOGkCgYEA8PewLVzUdHD20KkX
|
||||||
|
tZP+JCvSTy2f0kPHTc3+BU+MOlG8uZzsK06efo+X5BGkMRj8P+MPp9rJQr5IJqJl
|
||||||
|
GpeA1XpF54v2DIcNcjrQHIJ9XWoWirZjMWRVn4D5laQTI+FEV8pyFfJJOLIgBe9b
|
||||||
|
c6hBHNnAB4Y6JZ/s+US4ymK4wQ0CgYEA1DZMcuyiUgjnprUsOIokpg8RxGLIvB5+
|
||||||
|
2FyCffa/CikMRU8bRtHdpJLguArrR9rEILU6fICPARdlCg8r0XMrvniiAaS3YlDj
|
||||||
|
tSxbfrrS6xySvVFdNusv/j3i5/76IedsSArJLeQpIZMZ3n6q/dmq4kbWh+bT/5z+
|
||||||
|
MVpjWixpYccCgYBtaEh5kDh2VgP6YYv+SZ+OVMc8Y/64vUV0sh6v0ppcsFf7/p/M
|
||||||
|
WfnkhNX2G3xtPmbpqvKkx9WxlCu2Pu2g0UERrF6o7wdcUMVuI/3xs92v2Ec72+vV
|
||||||
|
tTSbIzgvFTwLgnBBXA3IoSVVtKqNh0wCi1Zk/wkNYYhtJNu3odg1K/Wu0QKBgBOv
|
||||||
|
IbI7TucrGkm1Xm+0KKgal7xOqW4BqiRpmFUU0S2hFxlKuC3+g3+jfCK2KJLWsQCT
|
||||||
|
ruQjjKA+Skn/lEHuW+1kBSr/217MQALrJWWA8NWMJfRXmrzgXehIV0bLuOnyLHIW
|
||||||
|
Rgjys/oAShMATt4TFa29gmLCv4FjT5TGXJbdrby7AoGBAOqER71Vi90UV84sYLWx
|
||||||
|
DSW/3q5/QrndmeeaQALslA6sidnTZWqlhMsNPl8dfBKl6xnrCdcaeY5xk/xmVOqP
|
||||||
|
0KedJgT+IjLwY1yJ9QOBd02ejAY3qNlKt2NiSWv2GBY1cZxqhkHNaI/UWI9CAyH5
|
||||||
|
YfkdFNxtYLdVAwuylMoV3fKI
|
||||||
|
-----END PRIVATE KEY-----"
|
||||||
# 商户APIV3密钥
|
# 商户APIV3密钥
|
||||||
apiV3: ZHENTUAIzhentuaiZHENTUAIzhentuai
|
apiV3: ZHENTUAIzhentuaiZHENTUAIzhentuai
|
||||||
|
|
||||||
|
@ -55,11 +55,9 @@ mybatis-plus:
|
|||||||
# 开启驼峰命名法
|
# 开启驼峰命名法
|
||||||
map-underscore-to-camel-case: true
|
map-underscore-to-camel-case: true
|
||||||
use-generated-keys: true
|
use-generated-keys: true
|
||||||
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
|
|
||||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
|
||||||
# 指定使用的日志配置文件
|
# 指定使用的日志配置文件
|
||||||
logging:
|
logging:
|
||||||
config: classpath:logback-spring.xml
|
config: classpath:logback-spring-prod.xml
|
||||||
# 微信小程序相关配置
|
# 微信小程序相关配置
|
||||||
wx:
|
wx:
|
||||||
# 公众号的appId
|
# 公众号的appId
|
||||||
@ -84,7 +82,34 @@ wx:
|
|||||||
# 退款回调接口地址
|
# 退款回调接口地址
|
||||||
refundNotifyUrl: https://zhentuai.com/api/mobile/wx/pay/v1/refundNotify
|
refundNotifyUrl: https://zhentuai.com/api/mobile/wx/pay/v1/refundNotify
|
||||||
# 商户API私钥路径
|
# 商户API私钥路径
|
||||||
keyPath: module-app/src/main/resources/cert/apiclient_key.pem
|
keyPath: "-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHwDoab8iRX4vn
|
||||||
|
Ta3a+gh5Z3wcyTM3VkWhkAPJGNJhaNgzOBI9b4v1x+uSZ4To2uXhQE5hvcxWSfNZ
|
||||||
|
F7H6yp+6estADeZLpdXLBDBvPDOjEGhG7YUHJjWnFh5eY2Rtnx4/7x+xCsRS+Mtq
|
||||||
|
Mx6KMrb4UZYNIq14peTQgfICkDBdqnUIkFjDmChUy0LlsSFW8AyJIqrBec5VZWf/
|
||||||
|
QqsIBf9vsTVxrqlX+5owYZuPYoFOIQJFUW8dfU20qk//BxiDjPFZBLNa02aIEbNF
|
||||||
|
SXZE2TlKD7zD0Qv/w95Hf1V+a/cxP2B6LNtqwioIdHbU6Axu7uHkr0RSPXPsvOWY
|
||||||
|
eUIpGP4bAgMBAAECggEBALm34w3TYtKu2D/tfDh9gkWGTuHgu6q2nrTxVmOxnWEN
|
||||||
|
/v3YIzVVsfaJs2ACuZNaeqNsi7PaqNKNnSD3o/X+UHYsVy8t/THWdSl1sqapfYUd
|
||||||
|
6yYPDkEwaG/6Y6/0j1pQt+pPpNKRpSlTwqTx9HIfZvkHuhBqbokfDNhECUQS1bUu
|
||||||
|
8pmyALIkuXu38B/xCs/EH+Lp1N69IA0mwalT/2zi9ZJhGNg5OWBzNbkMKf2Tck+9
|
||||||
|
SnS6s+pAT6YxB9qYhg645H3dRKXdeSYbjI+uiIe/7cJvTxfQDLD/oDap2TJQH3iM
|
||||||
|
SVbSfNFbR1tH6PiYx9eXeElEg2QXEPztbf8NcUlGOGkCgYEA8PewLVzUdHD20KkX
|
||||||
|
tZP+JCvSTy2f0kPHTc3+BU+MOlG8uZzsK06efo+X5BGkMRj8P+MPp9rJQr5IJqJl
|
||||||
|
GpeA1XpF54v2DIcNcjrQHIJ9XWoWirZjMWRVn4D5laQTI+FEV8pyFfJJOLIgBe9b
|
||||||
|
c6hBHNnAB4Y6JZ/s+US4ymK4wQ0CgYEA1DZMcuyiUgjnprUsOIokpg8RxGLIvB5+
|
||||||
|
2FyCffa/CikMRU8bRtHdpJLguArrR9rEILU6fICPARdlCg8r0XMrvniiAaS3YlDj
|
||||||
|
tSxbfrrS6xySvVFdNusv/j3i5/76IedsSArJLeQpIZMZ3n6q/dmq4kbWh+bT/5z+
|
||||||
|
MVpjWixpYccCgYBtaEh5kDh2VgP6YYv+SZ+OVMc8Y/64vUV0sh6v0ppcsFf7/p/M
|
||||||
|
WfnkhNX2G3xtPmbpqvKkx9WxlCu2Pu2g0UERrF6o7wdcUMVuI/3xs92v2Ec72+vV
|
||||||
|
tTSbIzgvFTwLgnBBXA3IoSVVtKqNh0wCi1Zk/wkNYYhtJNu3odg1K/Wu0QKBgBOv
|
||||||
|
IbI7TucrGkm1Xm+0KKgal7xOqW4BqiRpmFUU0S2hFxlKuC3+g3+jfCK2KJLWsQCT
|
||||||
|
ruQjjKA+Skn/lEHuW+1kBSr/217MQALrJWWA8NWMJfRXmrzgXehIV0bLuOnyLHIW
|
||||||
|
Rgjys/oAShMATt4TFa29gmLCv4FjT5TGXJbdrby7AoGBAOqER71Vi90UV84sYLWx
|
||||||
|
DSW/3q5/QrndmeeaQALslA6sidnTZWqlhMsNPl8dfBKl6xnrCdcaeY5xk/xmVOqP
|
||||||
|
0KedJgT+IjLwY1yJ9QOBd02ejAY3qNlKt2NiSWv2GBY1cZxqhkHNaI/UWI9CAyH5
|
||||||
|
YfkdFNxtYLdVAwuylMoV3fKI
|
||||||
|
-----END PRIVATE KEY-----"
|
||||||
# 商户APIV3密钥
|
# 商户APIV3密钥
|
||||||
apiV3: ZHENTUAIzhentuaiZHENTUAIzhentuai
|
apiV3: ZHENTUAIzhentuaiZHENTUAIzhentuai
|
||||||
|
|
||||||
|
142
src/main/resources/logback-spring-prod.xml
Normal file
142
src/main/resources/logback-spring-prod.xml
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration debug="false">
|
||||||
|
|
||||||
|
<!-- appender是configuration的子节点,是负责写日志的组件。 -->
|
||||||
|
<!-- ConsoleAppender:把日志输出到控制台 -->
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<!-- 默认情况下,每个日志事件都会立即刷新到基础输出流。 这种默认方法更安全,因为如果应用程序在没有正确关闭appender的情况下退出,则日志事件不会丢失。
|
||||||
|
但是,为了显着增加日志记录吞吐量,您可能希望将immediateFlush属性设置为false -->
|
||||||
|
<!--<immediateFlush>true</immediateFlush>-->
|
||||||
|
<encoder>
|
||||||
|
<!-- %37():如果字符没有37个字符长度,则左侧用空格补齐 -->
|
||||||
|
<!-- %-37():如果字符没有37个字符长度,则右侧用空格补齐 -->
|
||||||
|
<!-- %15.15():如果记录的线程字符长度小于15(第一个)则用空格在左侧补齐,如果字符长度大于15(第二个),则从开头开始截断多余的字符 -->
|
||||||
|
<!-- %-40.40():如果记录的logger字符长度小于40(第一个)则用空格在右侧补齐,如果字符长度大于40(第二个),则从开头开始截断多余的字符 -->
|
||||||
|
<!-- %msg:日志打印详情 -->
|
||||||
|
<!-- %n:换行符 -->
|
||||||
|
<!-- %highlight():转换说明符以粗体红色显示其级别为ERROR的事件,红色为WARN,BLUE为INFO,以及其他级别的默认颜色。 -->
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n</pattern>
|
||||||
|
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
|
||||||
|
<charset>UTF-8</charset>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- info 日志-->
|
||||||
|
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
|
||||||
|
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_info.log -->
|
||||||
|
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
|
||||||
|
<appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<!--日志文件路径和名称-->
|
||||||
|
<File>logs/project_info.log</File>
|
||||||
|
<!--是否追加到文件末尾,默认为true-->
|
||||||
|
<append>true</append>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<level>ERROR</level>
|
||||||
|
<onMatch>DENY</onMatch><!-- 如果命中ERROR就禁止这条日志 -->
|
||||||
|
<onMismatch>ACCEPT</onMismatch><!-- 如果没有命中就使用这条规则 -->
|
||||||
|
</filter>
|
||||||
|
<!--有两个与RollingFileAppender交互的重要子组件。 第一个RollingFileAppender子组件,即RollingPolicy:负责执行翻转所需的操作。
|
||||||
|
RollingFileAppender的第二个子组件,即TriggeringPolicy:将确定是否以及何时发生翻转。 因此,RollingPolicy负责什么和TriggeringPolicy负责什么时候.
|
||||||
|
作为任何用途,RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy,但是,如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者。-->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
|
||||||
|
<!-- 文件名:logs/project_info.2017-12-05.0.log -->
|
||||||
|
<!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 -->
|
||||||
|
<fileNamePattern>logs/project_info.%d.%i.log</fileNamePattern>
|
||||||
|
<!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天
|
||||||
|
如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
|
||||||
|
<maxHistory>30</maxHistory>
|
||||||
|
<!-- 每个日志文件到10mb的时候开始切分,最多保留30天,但最大到20GB,哪怕没到30天也要删除多余的日志 -->
|
||||||
|
<totalSizeCap>20GB</totalSizeCap>
|
||||||
|
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成5KB看效果 -->
|
||||||
|
<maxFileSize>10MB</maxFileSize>
|
||||||
|
</rollingPolicy>
|
||||||
|
<!--编码器-->
|
||||||
|
<encoder>
|
||||||
|
<!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern>
|
||||||
|
<!-- 记录日志的编码:此处设置字符集 - -->
|
||||||
|
<charset>UTF-8</charset>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- error 日志-->
|
||||||
|
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
|
||||||
|
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_error.log -->
|
||||||
|
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
|
||||||
|
<appender name="error_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<!--日志文件路径和名称-->
|
||||||
|
<File>logs/project_error.log</File>
|
||||||
|
<!--是否追加到文件末尾,默认为true-->
|
||||||
|
<append>true</append>
|
||||||
|
<!-- ThresholdFilter过滤低于指定阈值的事件。 对于等于或高于阈值的事件,ThresholdFilter将在调用其decision()方法时响应NEUTRAL。 但是,将拒绝级别低于阈值的事件 -->
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<level>ERROR</level><!-- 低于ERROR级别的日志(debug,info)将被拒绝,等于或者高于ERROR的级别将相应NEUTRAL -->
|
||||||
|
</filter>
|
||||||
|
<!--有两个与RollingFileAppender交互的重要子组件。 第一个RollingFileAppender子组件,即RollingPolicy:负责执行翻转所需的操作。
|
||||||
|
RollingFileAppender的第二个子组件,即TriggeringPolicy:将确定是否以及何时发生翻转。 因此,RollingPolicy负责什么和TriggeringPolicy负责什么时候.
|
||||||
|
作为任何用途,RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy,但是,如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者。-->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
|
<!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
|
||||||
|
<!-- 文件名:logs/project_error.2017-12-05.0.log -->
|
||||||
|
<!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 -->
|
||||||
|
<fileNamePattern>logs/project_error.%d.%i.log</fileNamePattern>
|
||||||
|
<!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天
|
||||||
|
如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
|
||||||
|
<maxHistory>30</maxHistory>
|
||||||
|
<!-- 每个日志文件到10mb的时候开始切分,最多保留30天,但最大到20GB,哪怕没到30天也要删除多余的日志 -->
|
||||||
|
<totalSizeCap>20GB</totalSizeCap>
|
||||||
|
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成5KB看效果 -->
|
||||||
|
<maxFileSize>10MB</maxFileSize>
|
||||||
|
</rollingPolicy>
|
||||||
|
<!--编码器-->
|
||||||
|
<encoder>
|
||||||
|
<!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern>
|
||||||
|
<!-- 记录日志的编码:此处设置字符集 - -->
|
||||||
|
<charset>UTF-8</charset>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="sql_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<File>logs/project_sql.log</File>
|
||||||
|
<append>true</append>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<level>DEBUG</level>
|
||||||
|
</filter>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
|
<fileNamePattern>logs/project_sql.%d.%i.log</fileNamePattern>
|
||||||
|
<maxHistory>30</maxHistory>
|
||||||
|
<totalSizeCap>20GB</totalSizeCap>
|
||||||
|
<maxFileSize>10MB</maxFileSize>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern>
|
||||||
|
<charset>UTF-8</charset>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!--给定记录器的每个启用的日志记录请求都将转发到该记录器中的所有appender以及层次结构中较高的appender(不用在意level值)。
|
||||||
|
换句话说,appender是从记录器层次结构中附加地继承的。
|
||||||
|
例如,如果将控制台appender添加到根记录器,则所有启用的日志记录请求将至少在控制台上打印。
|
||||||
|
如果另外将文件追加器添加到记录器(例如L),则对L和L'子项启用的记录请求将打印在文件和控制台上。
|
||||||
|
通过将记录器的additivity标志设置为false,可以覆盖此默认行为,以便不再添加appender累积-->
|
||||||
|
<!-- configuration中最多允许一个root,别的logger如果没有设置级别则从父级别root继承 -->
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
|
||||||
|
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
|
||||||
|
<logger name="com.ycwl.basic" level="INFO">
|
||||||
|
<appender-ref ref="info_log" />
|
||||||
|
<appender-ref ref="error_log" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<!-- 利用logback输入mybatis的sql日志,
|
||||||
|
注意:如果不加 additivity="false" 则此logger会将输出转发到自身以及祖先的logger中,就会出现日志文件中sql重复打印-->
|
||||||
|
<logger name="com.ycwl.basic.mapper" level="DEBUG" additivity="false">
|
||||||
|
<appender-ref ref="sql_log" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
</configuration>
|
Loading…
x
Reference in New Issue
Block a user