✨ 添加新特性。灰度发布

♻️ 重构代码。 支付回调逻辑抽象
👽 由于外部API的改变而更新代码。 更新不在维护前端
This commit is contained in:
冷冷 committed 2019-07-03 21:10:03 +08:00
1 parent b8121b20a4
commit cebeb347bb
23 files changed
+232 -136

No files matched your search

@@ -19,15 +19,11 @@
package com.pig4cloud.pigx.auth.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.common.security.handler.MobileLoginSuccessHandler;
import com.pig4cloud.pigx.common.security.mobile.MobileSecurityConfigurer;
import com.pig4cloud.pigx.common.security.service.PigxUserDetailsService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
@@ -36,8 +32,6 @@ import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
/**
@@ -49,16 +43,6 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHand
@Order(90)
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private PigxUserDetailsService userDetailsService;
@Lazy
@Autowired
private AuthorizationServerTokenServices defaultAuthorizationServerTokenServices;
@Override
@SneakyThrows
protected void configure(HttpSecurity http) {
@@ -96,19 +80,12 @@ public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Bean
public AuthenticationSuccessHandler mobileLoginSuccessHandler() {
return MobileLoginSuccessHandler.builder()
.objectMapper(objectMapper)
.clientDetailsService(clientDetailsService)
.passwordEncoder(passwordEncoder())
.defaultAuthorizationServerTokenServices(defaultAuthorizationServerTokenServices).build();
return new MobileLoginSuccessHandler();
}
@Bean
public MobileSecurityConfigurer mobileSecurityConfigurer() {
MobileSecurityConfigurer mobileSecurityConfigurer = new MobileSecurityConfigurer();
mobileSecurityConfigurer.setMobileLoginSuccessHandler(mobileLoginSuccessHandler());
mobileSecurityConfigurer.setUserDetailsService(userDetailsService);
return mobileSecurityConfigurer;
return new MobileSecurityConfigurer();
}
@@ -27,7 +27,12 @@ public interface CommonConstants {
/**
* header 中租户ID
*/
String TENANT_ID = "TENANT_ID";
String TENANT_ID = "TENANT-ID";
/**
* header 中版本信息
*/
String VERSION = "VERSION";
/**
* 租户ID
@@ -17,7 +17,8 @@
package com.pig4cloud.pigx.common.gateway.configuration;
import com.pig4cloud.pigx.common.gateway.rule.DiscoveryEnabledRule;
import com.pig4cloud.pigx.common.gateway.filter.GrayLoadBalancerClientFilter;
import com.pig4cloud.pigx.common.gateway.rule.AbstractDiscoveryEnabledRule;
import com.pig4cloud.pigx.common.gateway.rule.MetadataAwareRule;
import com.pig4cloud.pigx.common.gateway.support.PigxRibbonRuleProperties;
import lombok.RequiredArgsConstructor;
@@ -28,7 +29,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@@ -50,7 +56,21 @@ public class PigxRibbonRuleAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public DiscoveryEnabledRule metadataAwareRule() {
public AbstractDiscoveryEnabledRule metadataAwareRule() {
return new MetadataAwareRule();
}
@Bean
@ConditionalOnMissingBean(LoadBalancerClient.class)
public LoadBalancerClient loadBalancerClient(SpringClientFactory springClientFactory) {
return new RibbonLoadBalancerClient(springClientFactory);
}
@Bean
@ConditionalOnMissingBean(LoadBalancerClientFilter.class)
public LoadBalancerClientFilter loadBalancerClientFilter(RibbonLoadBalancerClient client
, LoadBalancerProperties properties) {
return new GrayLoadBalancerClientFilter(client, properties);
}
}
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.common.gateway.filter;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.http.HttpHeaders;
import org.springframework.web.server.ServerWebExchange;
import java.net.URI;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
/**
* @author Spencer Gibb
* @author Tim Ysewyn
*/
public class GrayLoadBalancerClientFilter extends LoadBalancerClientFilter {
private final RibbonLoadBalancerClient loadBalancer;
public GrayLoadBalancerClientFilter(RibbonLoadBalancerClient loadBalancer, LoadBalancerProperties properties) {
super(loadBalancer, properties);
this.loadBalancer = loadBalancer;
}
@Override
protected ServiceInstance choose(ServerWebExchange exchange) {
HttpHeaders headers = exchange.getRequest().getHeaders();
return loadBalancer.choose(((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost(), headers);
}
}
@@ -20,6 +20,7 @@ package com.pig4cloud.pigx.common.gateway.predicate;
import com.netflix.loadbalancer.AbstractServerPredicate;
import com.netflix.loadbalancer.PredicateKey;
import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
/**
@@ -27,7 +28,7 @@ import org.springframework.lang.Nullable;
*
* @author L.cm
*/
public abstract class DiscoveryEnabledPredicate extends AbstractServerPredicate {
public abstract class AbstractDiscoveryEnabledPredicate extends AbstractServerPredicate {
/**
* {@inheritDoc}
@@ -35,15 +36,16 @@ public abstract class DiscoveryEnabledPredicate extends AbstractServerPredicate
@Override
public boolean apply(@Nullable PredicateKey input) {
return input != null
&& input.getServer() instanceof NacosServer
&& apply((NacosServer) input.getServer());
&& input.getServer() instanceof NacosServer
&& apply((NacosServer) input.getServer(), (HttpHeaders) input.getLoadBalancerKey());
}
/**
* Returns whether the specific {@link NacosServer} matches this predicate.
*
* @param server the discovered server
* @param server the discovered server
* @param headers 请求头
* @return whether the server matches the predicate
*/
protected abstract boolean apply(NacosServer server);
abstract boolean apply(NacosServer server, HttpHeaders headers);
}
@@ -18,39 +18,50 @@
package com.pig4cloud.pigx.common.gateway.predicate;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.gateway.support.PigxRibbonRuleProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
import org.springframework.http.HttpHeaders;
import java.util.Map;
/**
* 基于 Metadata 的服务筛选
* 基于 Metadata version 的服务筛选
*
* @author L.cm
* @author lengleng
*/
public class MetadataAwarePredicate extends DiscoveryEnabledPredicate {
@Slf4j
public class GrayMetadataAwarePredicate extends AbstractDiscoveryEnabledPredicate {
@Override
protected boolean apply(NacosServer server) {
final Map<String, String> metadata = server.getMetadata();
protected boolean apply(NacosServer server, HttpHeaders headers) {
PigxRibbonRuleProperties ribbonProperties = SpringContextHolder.getBean(PigxRibbonRuleProperties.class);
// 获取配置
PigxRibbonRuleProperties properties = SpringContextHolder.getBean(PigxRibbonRuleProperties.class);
// 服务里的配置
String localTag = properties.getTag();
if (StrUtil.isBlank(localTag)) {
if (!ribbonProperties.isGrayEnabled()) {
log.debug("gray closed,GrayMetadataAwarePredicate return true");
return true;
}
// 本地有 tag,服务没有,返回 false
String metaDataTag = metadata.get("tag");
if (StrUtil.isBlank(metaDataTag)) {
return false;
final Map<String, String> metadata = server.getMetadata();
String version = metadata.get(CommonConstants.VERSION);
// 判断Nacos服务是否有版本标签
if (StrUtil.isBlank(version)) {
log.debug("nacos server tag is blank ,GrayMetadataAwarePredicate return true");
return true;
}
return metaDataTag.equals(localTag);
// 判断请求中是否有版本
String target = headers.getFirst(CommonConstants.VERSION);
if (StrUtil.isBlank(target)) {
log.debug("request headers version is blank,GrayMetadataAwarePredicate return true");
return true;
}
log.debug("请求版本:{} ,当前服务版本:{}", target, version);
return target.equals(version);
}
}
@@ -19,7 +19,7 @@ package com.pig4cloud.pigx.common.gateway.rule;
import com.google.common.base.Optional;
import com.netflix.loadbalancer.*;
import com.pig4cloud.pigx.common.gateway.predicate.DiscoveryEnabledPredicate;
import com.pig4cloud.pigx.common.gateway.predicate.AbstractDiscoveryEnabledPredicate;
import org.springframework.util.Assert;
import java.util.List;
@@ -29,10 +29,10 @@ import java.util.List;
*
* @author L.cm
*/
public abstract class DiscoveryEnabledRule extends PredicateBasedRule {
public abstract class AbstractDiscoveryEnabledRule extends PredicateBasedRule {
private final CompositePredicate predicate;
public DiscoveryEnabledRule(DiscoveryEnabledPredicate discoveryEnabledPredicate) {
public AbstractDiscoveryEnabledRule(AbstractDiscoveryEnabledPredicate discoveryEnabledPredicate) {
Assert.notNull(discoveryEnabledPredicate, "Parameter 'discoveryEnabledPredicate' can't be null");
this.predicate = createCompositePredicate(discoveryEnabledPredicate, new AvailabilityPredicate(this, null));
}
@@ -69,8 +69,8 @@ public abstract class DiscoveryEnabledRule extends PredicateBasedRule {
*/
public abstract List<Server> filterServers(List<Server> serverList);
private CompositePredicate createCompositePredicate(DiscoveryEnabledPredicate discoveryEnabledPredicate, AvailabilityPredicate availabilityPredicate) {
private CompositePredicate createCompositePredicate(AbstractDiscoveryEnabledPredicate discoveryEnabledPredicate, AvailabilityPredicate availabilityPredicate) {
return CompositePredicate.withPredicates(discoveryEnabledPredicate, availabilityPredicate)
.build();
.build();
}
}
@@ -22,8 +22,8 @@ import cn.hutool.system.HostInfo;
import cn.hutool.system.SystemUtil;
import com.netflix.loadbalancer.Server;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.gateway.predicate.DiscoveryEnabledPredicate;
import com.pig4cloud.pigx.common.gateway.predicate.MetadataAwarePredicate;
import com.pig4cloud.pigx.common.gateway.predicate.AbstractDiscoveryEnabledPredicate;
import com.pig4cloud.pigx.common.gateway.predicate.GrayMetadataAwarePredicate;
import com.pig4cloud.pigx.common.gateway.support.PigxRibbonRuleProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.PatternMatchUtils;
@@ -38,13 +38,13 @@ import java.util.List;
* @author dream.lu
*/
@Slf4j
public class MetadataAwareRule extends DiscoveryEnabledRule {
public class MetadataAwareRule extends AbstractDiscoveryEnabledRule {
public MetadataAwareRule() {
this(new MetadataAwarePredicate());
this(new GrayMetadataAwarePredicate());
}
public MetadataAwareRule(DiscoveryEnabledPredicate predicate) {
public MetadataAwareRule(AbstractDiscoveryEnabledPredicate predicate) {
super(predicate);
}
@@ -53,6 +53,10 @@ public class MetadataAwareRule extends DiscoveryEnabledRule {
PigxRibbonRuleProperties ribbonProperties = SpringContextHolder.getBean(PigxRibbonRuleProperties.class);
List<String> priorIpPattern = ribbonProperties.getPriorIpPattern();
if (ribbonProperties.isGrayEnabled()) {
return serverList;
}
// 1. 查找是否有本机 ip
HostInfo hostInfo = SystemUtil.getHostInfo();
String hostIp = hostInfo.getAddress();
@@ -38,11 +38,11 @@ public class PigxRibbonRuleProperties {
/**
* 是否开启,默认:true
*/
private Boolean enabled = Boolean.TRUE;
private boolean enabled = Boolean.TRUE;
/**
* 服务的tag,用于灰度,匹配:nacos.discovery.metadata.tag
* 是否开启灰度路由,默认:false
*/
private String tag;
private boolean grayEnabled;
/**
* 优先的ip列表,支持通配符,例如:10.20.0.8*、10.20.0.*
*/
@@ -20,8 +20,9 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.common.security.util.AuthUtils;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
@@ -46,12 +47,16 @@ import java.io.PrintWriter;
* 手机号登录成功,返回oauth token
*/
@Slf4j
@Builder
public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler {
private static final String BASIC_ = "Basic ";
@Autowired
private ObjectMapper objectMapper;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private ClientDetailsService clientDetailsService;
@Lazy
@Autowired
private AuthorizationServerTokenServices defaultAuthorizationServerTokenServices;
/**
@@ -98,7 +103,7 @@ public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler {
printWriter.append(objectMapper.writeValueAsString(oAuth2AccessToken));
} catch (IOException e) {
throw new BadCredentialsException(
"Failed to decode basic authentication token");
"Failed to decode basic authentication token");
}
}
@@ -30,7 +30,6 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;
/**
* @author lengleng
@@ -39,13 +38,14 @@ import org.springframework.stereotype.Component;
*/
@Getter
@Setter
@Component
public class MobileSecurityConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private AuthenticationEventPublisher defaultAuthenticationEventPublisher;
@Autowired
private AuthenticationSuccessHandler mobileLoginSuccessHandler;
@Autowired
private PigxUserDetailsService userDetailsService;
@Override
@@ -59,6 +59,6 @@ public class MobileSecurityConfigurer extends SecurityConfigurerAdapter<DefaultS
MobileAuthenticationProvider mobileAuthenticationProvider = new MobileAuthenticationProvider();
mobileAuthenticationProvider.setUserDetailsService(userDetailsService);
http.authenticationProvider(mobileAuthenticationProvider)
.addFilterAfter(mobileAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
.addFilterAfter(mobileAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}
@@ -104,7 +104,6 @@
**/
handleUpdate: function (row, index, done,loading) {
putObj(row).then(data => {
this.tableData.splice(index, 1, Object.assign({}, row))
this.$message({
showClose: true,
message: '修改成功',
@@ -124,7 +123,6 @@
**/
handleSave: function (row, done,loading) {
addObj(row).then(data => {
this.tableData.push(Object.assign({}, row))
this.$message({
showClose: true,
message: '添加成功',
@@ -36,6 +36,9 @@ public abstract class AbstractPayNotifyCallbakHandler implements PayNotifyCallba
@Override
public String handle(Map<String, String> params) {
// 初始化租户
before(params);
// 去重处理
if (duplicateChecker(params)) {
return null;
@@ -46,6 +49,9 @@ public abstract class AbstractPayNotifyCallbakHandler implements PayNotifyCallba
return null;
}
return parse(params);
String result = parse(params);
// 保存处理结果
saveNotifyRecord(params, result);
return result;
}
}
@@ -19,16 +19,22 @@ package com.pig4cloud.pigx.pay.handler;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jpay.alipay.AliPayApiConfig;
import com.jpay.alipay.AliPayApiConfigKit;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
import com.pig4cloud.pigx.pay.entity.PayNotifyRecord;
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
import com.pig4cloud.pigx.pay.service.PayGoodsOrderService;
import com.pig4cloud.pigx.pay.service.PayNotifyRecordService;
import com.pig4cloud.pigx.pay.service.PayTradeOrderService;
import com.pig4cloud.pigx.pay.utils.PayConstants;
import com.pig4cloud.pigx.pay.utils.TradeStatusEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -50,6 +56,17 @@ public class AlipayPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
private final PayGoodsOrderService goodsOrderService;
private final PayNotifyRecordService recordService;
/**
* 维护租户信息
*
* @param params
*/
@Override
public void before(Map<String, String> params) {
Integer tenant = MapUtil.getInt(params, "tenant");
TenantContextHolder.setTenantId(tenant);
}
/**
* 去重处理
*
@@ -107,9 +124,21 @@ public class AlipayPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
*/
@Override
public String parse(Map<String, String> params) {
String tradeStatus = EnumUtil.fromString(TradeStatusEnum.class, params.get("trade_status")).getStatus();
goodsOrderService.updateOrder(params);
tradeOrderService.updateOrder(params);
String orderNo = params.get("out_trade_no");
PayGoodsOrder goodsOrder = goodsOrderService.getOne(Wrappers.<PayGoodsOrder>lambdaQuery()
.eq(PayGoodsOrder::getPayOrderId, orderNo));
goodsOrder.setStatus(tradeStatus);
goodsOrderService.updateById(goodsOrder);
PayTradeOrder tradeOrder = tradeOrderService.getOne(Wrappers.<PayTradeOrder>lambdaQuery()
.eq(PayTradeOrder::getOrderId, orderNo));
Long succTime = MapUtil.getLong(params, "time_end");
tradeOrder.setPaySuccTime(succTime);
tradeOrder.setStatus(TradeStatusEnum.TRADE_SUCCESS.getStatus());
tradeOrder.setChannelOrderNo(params.get("transaction_id"));
tradeOrderService.updateById(tradeOrder);
return "success";
}
@@ -27,6 +27,13 @@ import java.util.Map;
*/
public interface PayNotifyCallbakHandler {
/**
* 初始化执行
*
* @param params
*/
void before(Map<String, String> params);
/**
* 去重处理
*
@@ -4,6 +4,7 @@ import cn.hutool.extra.servlet.ServletUtil;
import com.jpay.ext.kit.PaymentKit;
import com.jpay.weixin.api.WxPayApi;
import com.jpay.weixin.api.WxPayApiConfigKit;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.pay.config.PayCommonProperties;
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
@@ -67,7 +68,7 @@ public class WeChatMpPayOrderHandler extends AbstractPayOrderHandler {
public Object pay(PayGoodsOrder goodsOrder, PayTradeOrder tradeOrder) {
String ip = ServletUtil.getClientIP(request);
Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
.setAttach(goodsOrder.getGoodsId())
.setAttach(TenantContextHolder.getTenantId().toString())
.setBody(goodsOrder.getGoodsName())
.setSpbillCreateIp(ip)
.setTotalFee(goodsOrder.getAmount())
@@ -18,10 +18,15 @@
package com.pig4cloud.pigx.pay.handler;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jpay.ext.kit.PaymentKit;
import com.jpay.weixin.api.WxPayApiConfigKit;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
import com.pig4cloud.pigx.pay.entity.PayNotifyRecord;
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
import com.pig4cloud.pigx.pay.service.PayGoodsOrderService;
import com.pig4cloud.pigx.pay.service.PayNotifyRecordService;
import com.pig4cloud.pigx.pay.service.PayTradeOrderService;
@@ -49,6 +54,17 @@ public class WeChatPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
private final PayGoodsOrderService goodsOrderService;
private final PayNotifyRecordService recordService;
/**
* 维护租户信息
*
* @param params
*/
@Override
public void before(Map<String, String> params) {
Integer tenant = MapUtil.getInt(params, "attach");
TenantContextHolder.setTenantId(tenant);
}
/**
* 去重处理
*
@@ -90,10 +106,23 @@ public class WeChatPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
*/
@Override
public String parse(Map<String, String> params) {
params.put("trade_status", TradeStatusEnum.TRADE_SUCCESS.getDescription());
String orderNo = params.get("out_trade_no");
String tradeStatus = EnumUtil.fromString(TradeStatusEnum.class, params.get("result_code")).getStatus();
goodsOrderService.updateOrder(params);
tradeOrderService.updateOrder(params);
PayGoodsOrder goodsOrder = goodsOrderService.getOne(Wrappers.<PayGoodsOrder>lambdaQuery()
.eq(PayGoodsOrder::getPayOrderId, orderNo));
goodsOrder.setStatus(tradeStatus);
goodsOrderService.updateById(goodsOrder);
PayTradeOrder tradeOrder = tradeOrderService.getOne(Wrappers.<PayTradeOrder>lambdaQuery()
.eq(PayTradeOrder::getOrderId, orderNo));
Long succTime = MapUtil.getLong(params, "time_end");
tradeOrder.setPaySuccTime(succTime);
tradeOrder.setStatus(tradeStatus);
tradeOrder.setChannelOrderNo(params.get("transaction_id"));
tradeOrder.setErrMsg(params.get("err_code_des"));
tradeOrder.setErrCode(params.get("err_code"));
tradeOrderService.updateById(tradeOrder);
Map<String, String> xml = new HashMap<>(4);
xml.put("return_code", "SUCCESS");
@@ -110,7 +139,7 @@ public class WeChatPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHand
@Override
public void saveNotifyRecord(Map<String, String> params, String result) {
PayNotifyRecord record = new PayNotifyRecord();
String notifyId = params.get("notify_id");
String notifyId = params.get("transaction_id");
record.setNotifyId(notifyId);
String orderNo = params.get("out_trade_no");
record.setOrderNo(orderNo);
@@ -38,10 +38,4 @@ public interface PayGoodsOrderService extends IService<PayGoodsOrder> {
*/
Map<String, Object> buy(PayGoodsOrder goodsOrder);
/**
* 更新订单
*
* @param params
*/
void updateOrder(Map<String, String> params);
}
@@ -20,8 +20,6 @@ package com.pig4cloud.pigx.pay.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
import java.util.Map;
/**
* 支付
*
@@ -30,10 +28,4 @@ import java.util.Map;
*/
public interface PayTradeOrderService extends IService<PayTradeOrder> {
/**
* 更新支付订单
*
* @param params
*/
void updateOrder(Map<String, String> params);
}
@@ -16,20 +16,15 @@
*/
package com.pig4cloud.pigx.pay.service.impl;
import cn.hutool.core.util.EnumUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
import com.pig4cloud.pigx.pay.handler.PayOrderHandler;
import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper;
import com.pig4cloud.pigx.pay.service.PayGoodsOrderService;
import com.pig4cloud.pigx.pay.utils.PayChannelNameEnum;
import com.pig4cloud.pigx.pay.utils.PayConstants;
import com.pig4cloud.pigx.pay.utils.TradeStatusEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -74,22 +69,4 @@ public class PayGoodsOrderServiceImpl extends ServiceImpl<PayGoodsOrderMapper, P
return result;
}
/**
* 异步更新商品订单
*
* @param params
*/
@Async
@Override
@Transactional(rollbackFor = Exception.class)
public void updateOrder(Map<String, String> params) {
PayGoodsOrder goodsOrder = new PayGoodsOrder();
String tradeStatus = EnumUtil.fromString(TradeStatusEnum.class, params.get("trade_status")).getStatus();
goodsOrder.setStatus(tradeStatus);
this.baseMapper.update(goodsOrder, Wrappers.<PayGoodsOrder>lambdaQuery()
.eq(PayGoodsOrder::getPayOrderId, params.
get(PayConstants.OUT_TRADE_NO)));
}
}
@@ -20,13 +20,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
import com.pig4cloud.pigx.pay.mapper.PayTradeOrderMapper;
import com.pig4cloud.pigx.pay.service.PayTradeOrderService;
import com.pig4cloud.pigx.pay.utils.PayConstants;
import com.pig4cloud.pigx.pay.utils.TradeStatusEnum;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
/**
* 支付
@@ -37,18 +31,4 @@ import java.util.Map;
@Service
public class PayTradeOrderServiceImpl extends ServiceImpl<PayTradeOrderMapper, PayTradeOrder> implements PayTradeOrderService {
/**
* 更新支付订单
*
* @param params
*/
@Async
@Override
@Transactional(rollbackFor = Exception.class)
public void updateOrder(Map<String, String> params) {
PayTradeOrder payTradeOrder = this.baseMapper.selectById(params.get(PayConstants.OUT_TRADE_NO));
payTradeOrder.setStatus(TradeStatusEnum.TRADE_SUCCESS.getStatus());
payTradeOrder.setChannelOrderNo(params.get("trade_no"));
this.baseMapper.updateById(payTradeOrder);
}
}
@@ -28,7 +28,17 @@ public enum TradeStatusEnum {
/**
* 交易关闭
*/
TRADE_FINISHED("TRADE_FINISHED", OrderStatusEnum.COMPLETE.getStatus());
TRADE_FINISHED("TRADE_FINISHED", OrderStatusEnum.COMPLETE.getStatus()),
/**
* 微信支付成功
*/
SUCCESS("SUCCESS", OrderStatusEnum.SUCCESS.getStatus()),
/**
* 微信支付失败
*/
FAIL("FAIL", OrderStatusEnum.FAIL.getStatus());
/**
@@ -4,7 +4,7 @@
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<meta charset="UTF-8">
<title>Title</title>
<title>Pigx Pro 支付模块</title>
</head>
<script src="//cdn.jsdelivr.net/jquery/1.12.1/jquery.min.js"></script>