提交
This commit is contained in:
@ -27,7 +27,7 @@ public interface ShopConstants {
|
||||
/**
|
||||
* redis订单收货key
|
||||
*/
|
||||
String REDIS_ORDER_OUTTIME_UNCONFIRM = "order:unconfirm:";
|
||||
String REDIS_ORDER_OUTTIME_UNCONFIRM = "order-unconfirm-queue";
|
||||
|
||||
/**
|
||||
* redis拼团key
|
||||
|
@ -0,0 +1,32 @@
|
||||
package co.yixiang.yshop.framework.common.enums;
|
||||
|
||||
import co.yixiang.yshop.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 逻辑删除枚举
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DeletedEnum {
|
||||
|
||||
NO(false, "默认"),
|
||||
YES(true, "已逻辑删除");
|
||||
|
||||
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private final Boolean status;
|
||||
/**
|
||||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
|
||||
}
|
@ -18,48 +18,51 @@ import java.util.stream.Stream;
|
||||
@AllArgsConstructor
|
||||
public enum OrderInfoEnum {
|
||||
|
||||
STATUS_NE1(-1,"申请退款"),
|
||||
STATUS_NE2(-2,"退款成功"),
|
||||
STATUS_0(0,"默认"),
|
||||
STATUS_1(1,"待收货"),
|
||||
STATUS_2(2,"已收货"),
|
||||
STATUS_3(3,"已完成"),
|
||||
STATUS_APPLY_REFUND(-1,"申请退款"),
|
||||
STATUS_REFUND_SUCCESS(-2,"退款成功"),
|
||||
STATUS_DEFAULT(0,"默认"),
|
||||
STATUS_WAIT_RECEIVED(1,"待收货"),
|
||||
STATUS_RECEIVED(2,"已收货"),
|
||||
STATUS_FINISHED(3,"已完成"),
|
||||
|
||||
PAY_STATUS_0(0,"未支付"),
|
||||
PAY_STATUS_1(1,"已支付"),
|
||||
PAY_STATUS_UNPAID(0,"未支付"),
|
||||
PAY_STATUS_HAVE_PAID(1,"已支付"),
|
||||
|
||||
REFUND_STATUS_0(0,"正常"),
|
||||
REFUND_STATUS_1(1,"退款中"),
|
||||
REFUND_STATUS_2(2,"已退款"),
|
||||
REFUND_STATUS_NORMAL(0,"正常"),
|
||||
REFUND_STATUS_BEING_REFUNDED(1,"退款中"),
|
||||
REFUND_STATUS_HAVE_REFUNDED(2,"已退款"),
|
||||
|
||||
BARGAIN_STATUS_1(1,"参与中"),
|
||||
BARGAIN_STATUS_2(2,"参与失败"),
|
||||
BARGAIN_STATUS_3(3,"参与成功"),
|
||||
BARGAIN_STATUS_ONGOING(1,"参与中"),
|
||||
BARGAIN_STATUS_FAIL(2,"参与失败"),
|
||||
BARGAIN_STATUS_SUCCESS(3,"参与成功"),
|
||||
|
||||
PINK_STATUS_1(1,"进行中"),
|
||||
PINK_STATUS_2(2,"已完成"),
|
||||
PINK_STATUS_3(3,"未完成"),
|
||||
PINK_STATUS_ONGOING(1,"进行中"),
|
||||
PINK_STATUS_FINISHED(2,"已完成"),
|
||||
PINK_STATUS_UNFINISHED(3,"未完成"),
|
||||
|
||||
PINK_REFUND_STATUS_0(0,"拼团正常"),
|
||||
PINK_REFUND_STATUS_1(1,"拼团已退款"),
|
||||
PINK_REFUND_STATUS_NORMAL(0,"拼团正常"),
|
||||
PINK_REFUND_STATUS_REFUNDED(1,"拼团已退款"),
|
||||
|
||||
CANCEL_STATUS_0(0,"正常"),
|
||||
CANCEL_STATUS_1(1,"已取消"),
|
||||
CANCEL_STATUS_NORMAL(0,"正常"),
|
||||
CANCEL_STATUS_CANCELED(1,"已取消"),
|
||||
|
||||
CONFIRM_STATUS_0(0,"正常"),
|
||||
CONFIRM_STATUS_1(1,"确认"),
|
||||
CONFIRM_STATUS_NORMAL(0,"正常"),
|
||||
CONFIRM_STATUS_CONFIRM(1,"确认"),
|
||||
|
||||
PAY_CHANNEL_0(0,"公众号/H5支付渠道"),
|
||||
PAY_CHANNEL_1(1,"小程序支付渠道"),
|
||||
PAY_CHANNEL_PUBLIC_ACCOUNT_H5(0,"公众号/H5支付渠道"),
|
||||
PAY_CHANNEL_MINI_PROGRAM(1,"小程序支付渠道"),
|
||||
|
||||
|
||||
SHIPPIING_TYPE_1(1,"快递"),
|
||||
SHIPPIING_TYPE_2(2,"门店自提");
|
||||
NO(0,"否"),
|
||||
YES(1,"是"),
|
||||
|
||||
SHIPPING_TYPE_DELIVERY(1,"快递"),
|
||||
SHIPPING_TYPE_STORE_PICKUP(2,"门店自提");
|
||||
|
||||
|
||||
|
||||
private Integer value;
|
||||
private String desc;
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
|
||||
public static OrderInfoEnum toType(int value) {
|
||||
return Stream.of(OrderInfoEnum.values())
|
||||
|
@ -1,73 +1,69 @@
|
||||
package co.yixiang.yshop.framework.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author hupeng
|
||||
* 商城常用枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ShopCommonEnum {
|
||||
|
||||
STORE_MODE_1(1,"本地存储"),
|
||||
STORE_MODE_2(2,"云存储"),
|
||||
|
||||
ENABLE_1(1,"开启"),
|
||||
ENABLE_2(2,"关闭"),
|
||||
|
||||
EXTRACT_MINUS_1(-1,"提现未通过"),
|
||||
EXTRACT_0(0,"提现审核中"),
|
||||
EXTRACT_1(1,"提现已完成"),
|
||||
|
||||
IS_FINISH_0(0,"未完成"),
|
||||
IS_FINISH_1(1,"已完成"),
|
||||
|
||||
IS_FOREVER_0(0,"不是永久"),
|
||||
IS_FOREVER_1(1,"永久"),
|
||||
|
||||
AGREE_1(1,"同意"),
|
||||
AGREE_2(2,"拒绝"),
|
||||
|
||||
IS_PERMANENT_0(0,"限制"),
|
||||
IS_PERMANENT_1(1,"不限制"),
|
||||
|
||||
IS_STATUS_0(0,"否"),
|
||||
IS_STATUS_1(1,"是"),
|
||||
|
||||
|
||||
IS_PROMOTER_0(0,"默认"),
|
||||
IS_PROMOTER_1(1,"是客服"),
|
||||
|
||||
IS_NEW_0(0,"默认"),
|
||||
IS_NEW_1(1,"新品"),
|
||||
|
||||
IS_SUB_0(0,"不单独分佣"),
|
||||
IS_SUB_1(1,"单独分佣"),
|
||||
|
||||
|
||||
GRADE_0(0,"一级推荐人"),
|
||||
GRADE_1(1,"二级推荐人"),
|
||||
|
||||
REPLY_0(0,"未回复"),
|
||||
REPLY_1(1,"已回复"),
|
||||
|
||||
ADD_1(1,"增加"),
|
||||
ADD_2(2,"减少"),
|
||||
|
||||
DELETE_0(0,"未删除"),
|
||||
DELETE_1(1,"已删除"),
|
||||
|
||||
SHOW_0(0,"不显示"),
|
||||
SHOW_1(1,"显示"),
|
||||
|
||||
DEFAULT_0(0,"不是默认"),
|
||||
DEFAULT_1(1,"默认");
|
||||
|
||||
|
||||
|
||||
|
||||
private Integer value;
|
||||
private String desc;
|
||||
}
|
||||
package co.yixiang.yshop.framework.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author hupeng
|
||||
* 商城常用枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ShopCommonEnum {
|
||||
|
||||
STORE_MODE_LOCAL(1,"本地存储"),
|
||||
STORE_MODE_CLOUD(2,"云存储"),
|
||||
|
||||
ENABLE(1,"开启"),
|
||||
DISABLE(2,"关闭"),
|
||||
|
||||
EXTRACT_MINUS_NOT_PASS(-1,"提现未通过"),
|
||||
EXTRACT_UNDER_REVIEW(0,"提现审核中"),
|
||||
EXTRACT_FINISHED(1,"提现已完成"),
|
||||
|
||||
UNFINISHED(0,"未完成"),
|
||||
FINISHED(1,"已完成"),
|
||||
|
||||
NOT_FOREVER(0,"不是永久"),
|
||||
FOREVER(1,"永久"),
|
||||
|
||||
AGREE(1,"同意"),
|
||||
REFUSED(2,"拒绝"),
|
||||
|
||||
LIMIT(0,"限制"),
|
||||
UN_LIMIT(1,"不限制"),
|
||||
|
||||
NO(0,"否"),
|
||||
YES(1,"是"),
|
||||
|
||||
DEFAULT(0,"默认"),
|
||||
NEW(1,"新品"),
|
||||
|
||||
IS_SUB_0(0,"不单独分佣"),
|
||||
IS_SUB_1(1,"单独分佣"),
|
||||
|
||||
|
||||
GRADE_ONE(0,"一级推荐人"),
|
||||
GRADE_TWO(1,"二级推荐人"),
|
||||
|
||||
UN_REPLY(0,"未回复"),
|
||||
REPLIED(1,"已回复"),
|
||||
|
||||
ADD_1(1,"增加"),
|
||||
ADD_2(2,"减少"),
|
||||
|
||||
DELETE_0(0,"未删除"),
|
||||
DELETE_1(1,"已删除"),
|
||||
|
||||
NO_SHOW(0,"不显示"),
|
||||
SHOW(1,"显示"),
|
||||
|
||||
NON_DEFAULT(0,"不是默认"),
|
||||
IS_DEFAULT(1,"默认");
|
||||
|
||||
|
||||
|
||||
|
||||
private final Integer value;
|
||||
private final String desc;
|
||||
}
|
||||
|
@ -16,16 +16,16 @@ import java.io.Serializable;
|
||||
public abstract class QueryParam implements Serializable{
|
||||
private static final long serialVersionUID = -3263921252635611410L;
|
||||
|
||||
@Schema(description = "页码,默认为1", required = true)
|
||||
@Schema(description = "页码,默认为1", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer page =1;
|
||||
|
||||
@Schema(description = "页大小,默认为10", required = true)
|
||||
@Schema(description = "页大小,默认为10", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer limit = 10;
|
||||
|
||||
@Schema(description = "搜索字符串", required = true)
|
||||
@Schema(description = "搜索字符串", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String keyword;
|
||||
|
||||
// @Schema(description = "当前第几页", required = true)
|
||||
// @Schema(description = "当前第几页", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
// public void setCurrent(Integer current) {
|
||||
// if (current == null || current <= 0){
|
||||
// this.page = 1;
|
||||
|
@ -15,12 +15,12 @@ public class PageParam implements Serializable {
|
||||
private static final Integer PAGE_NO = 1;
|
||||
private static final Integer PAGE_SIZE = 10;
|
||||
|
||||
@Schema(description = "页码,从 1 开始", required = true,example = "1")
|
||||
@Schema(description = "页码,从 1 开始", requiredMode = Schema.RequiredMode.REQUIRED,example = "1")
|
||||
@NotNull(message = "页码不能为空")
|
||||
@Min(value = 1, message = "页码最小值为 1")
|
||||
private Integer pageNo = PAGE_NO;
|
||||
|
||||
@Schema(description = "每页条数,最大值为 100", required = true, example = "10")
|
||||
@Schema(description = "每页条数,最大值为 100", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
@NotNull(message = "每页条数不能为空")
|
||||
@Min(value = 1, message = "每页条数最小值为 1")
|
||||
@Max(value = 100, message = "每页条数最大值为 100")
|
||||
|
@ -11,10 +11,10 @@ import java.util.List;
|
||||
@Data
|
||||
public final class PageResult<T> implements Serializable {
|
||||
|
||||
@Schema(description = "数据", required = true)
|
||||
@Schema(description = "数据", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<T> list;
|
||||
|
||||
@Schema(description = "总量", required = true)
|
||||
@Schema(description = "总量", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long total;
|
||||
|
||||
public PageResult() {
|
||||
|
@ -6,7 +6,7 @@ import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 时间工具类,用于 {@link java.time.LocalDateTime}
|
||||
* 时间工具类,用于 {@link LocalDateTime}
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
|
@ -7,7 +7,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* IO 工具类,用于 {@link cn.hutool.core.io.IoUtil} 缺失的方法
|
||||
* IO 工具类,用于 {@link IoUtil} 缺失的方法
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@ package co.yixiang.yshop.framework.common.util.object;
|
||||
import co.yixiang.yshop.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* {@link co.yixiang.yshop.framework.common.pojo.PageParam} 工具类
|
||||
* {@link PageParam} 工具类
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
|
@ -10,7 +10,7 @@ import org.springframework.aop.support.ComposablePointcut;
|
||||
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
|
||||
|
||||
/**
|
||||
* {@link co.yixiang.yshop.framework.datapermission.core.annotation.DataPermission} 注解的 Advisor 实现类
|
||||
* {@link DataPermission} 注解的 Advisor 实现类
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
|
@ -8,6 +8,10 @@ import co.yixiang.yshop.framework.sms.core.client.impl.tencent.TencentSmsClient;
|
||||
import co.yixiang.yshop.framework.sms.core.enums.SmsChannelEnum;
|
||||
import co.yixiang.yshop.framework.sms.core.property.SmsChannelProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Configurable;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@ -22,6 +26,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
*/
|
||||
@Validated
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SmsClientFactoryImpl implements SmsClientFactory {
|
||||
|
||||
/**
|
||||
@ -30,6 +35,12 @@ public class SmsClientFactoryImpl implements SmsClientFactory {
|
||||
*/
|
||||
private final ConcurrentMap<Long, AbstractSmsClient> channelIdClients = new ConcurrentHashMap<>();
|
||||
|
||||
@Value("${yshop.sms-code.api-key}")
|
||||
private String apiKey = "LTAI5tBBPdRd4f2YZt5UhVjF";
|
||||
|
||||
@Value("${yshop.sms-code.api-secret}")
|
||||
private String apiSecret = "iVP7EsjX309epI7MqsScziGhcrEHiT";
|
||||
|
||||
/**
|
||||
* 短信客户端 Map
|
||||
* key:渠道编码,使用 {@link SmsChannelProperties#getCode()} ()}
|
||||
@ -44,7 +55,7 @@ public class SmsClientFactoryImpl implements SmsClientFactory {
|
||||
Arrays.stream(SmsChannelEnum.values()).forEach(channel -> {
|
||||
// 创建一个空的 SmsChannelProperties 对象
|
||||
SmsChannelProperties properties = new SmsChannelProperties().setCode(channel.getCode())
|
||||
.setApiKey("default default").setApiSecret("default");
|
||||
.setApiKey(apiKey).setApiSecret(apiSecret);
|
||||
// 创建 Sms 客户端
|
||||
AbstractSmsClient smsClient = createSmsClient(properties);
|
||||
channelCodeClients.put(channel.getCode(), smsClient);
|
||||
@ -78,13 +89,15 @@ public class SmsClientFactoryImpl implements SmsClientFactory {
|
||||
Assert.notNull(channelEnum, String.format("渠道类型(%s) 为空", channelEnum));
|
||||
// 创建客户端
|
||||
switch (channelEnum) {
|
||||
case ALIYUN: return new AliyunSmsClient(properties);
|
||||
case DEBUG_DING_TALK: return new DebugDingTalkSmsClient(properties);
|
||||
case TENCENT: return new TencentSmsClient(properties);
|
||||
case ALIYUN: return new AliyunSmsClient(properties);
|
||||
// case DEBUG_DING_TALK: return new DebugDingTalkSmsClient(properties);
|
||||
// case TENCENT: return new TencentSmsClient(properties);
|
||||
default: return new AliyunSmsClient(properties);
|
||||
}
|
||||
|
||||
// 创建失败,错误日志 + 抛出异常
|
||||
log.error("[createSmsClient][配置({}) 找不到合适的客户端实现]", properties);
|
||||
throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", properties));
|
||||
// log.error("[createSmsClient][配置({}) 找不到合适的客户端实现]", properties);
|
||||
// throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", properties));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public enum SmsChannelEnum {
|
||||
DEBUG_DING_TALK("DEBUG_DING_TALK", "调试(钉钉)"),
|
||||
ALIYUN("ALIYUN", "阿里云"),
|
||||
TENCENT("TENCENT", "腾讯云"),
|
||||
// HUA_WEI("HUA_WEI", "华为云"),
|
||||
HUA_WEI("HUA_WEI", "华为云"),
|
||||
;
|
||||
|
||||
/**
|
||||
|
@ -1,36 +1,36 @@
|
||||
package co.yixiang.yshop.framework.social.config;
|
||||
|
||||
import co.yixiang.yshop.framework.social.core.YshopAuthRequestFactory;
|
||||
import com.xkcoding.http.HttpUtil;
|
||||
import com.xkcoding.http.support.hutool.HutoolImpl;
|
||||
import com.xkcoding.justauth.autoconfigure.JustAuthProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhyd.oauth.cache.AuthStateCache;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
/**
|
||||
* 社交自动装配类
|
||||
*
|
||||
* @author timfruit
|
||||
* @date 2021-10-30
|
||||
*/
|
||||
@Slf4j
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(JustAuthProperties.class)
|
||||
public class YshopSocialAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnProperty(prefix = "justauth", value = "enabled", havingValue = "true", matchIfMissing = true)
|
||||
public YshopAuthRequestFactory yshopAuthRequestFactory(JustAuthProperties properties, AuthStateCache authStateCache) {
|
||||
// 需要修改 HttpUtil 使用的实现,避免类报错
|
||||
HttpUtil.setHttp(new HutoolImpl());
|
||||
// 创建 YshopAuthRequestFactory
|
||||
return new YshopAuthRequestFactory(properties, authStateCache);
|
||||
}
|
||||
|
||||
}
|
||||
package co.yixiang.yshop.framework.social.config;
|
||||
|
||||
import co.yixiang.yshop.framework.social.core.YshopAuthRequestFactory;
|
||||
import com.xkcoding.http.HttpUtil;
|
||||
import com.xkcoding.http.support.hutool.HutoolImpl;
|
||||
import com.xkcoding.justauth.autoconfigure.JustAuthProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhyd.oauth.cache.AuthStateCache;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
/**
|
||||
* 社交自动装配类
|
||||
*
|
||||
* @author timfruit
|
||||
* @date 2021-10-30
|
||||
*/
|
||||
@Slf4j
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(JustAuthProperties.class)
|
||||
public class YshopSocialAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnProperty(prefix = "justauth", value = "enabled", havingValue = "true", matchIfMissing = true)
|
||||
public YshopAuthRequestFactory yshopAuthRequestFactory(JustAuthProperties properties, AuthStateCache authStateCache) {
|
||||
// 需要修改 HttpUtil 使用的实现,避免类报错
|
||||
HttpUtil.setHttp(new HutoolImpl());
|
||||
// 创建 YshopAuthRequestFactory
|
||||
return new YshopAuthRequestFactory(properties, authStateCache);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,85 +1,85 @@
|
||||
package co.yixiang.yshop.framework.social.core;
|
||||
|
||||
import cn.hutool.core.util.EnumUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import co.yixiang.yshop.framework.social.core.enums.AuthExtendSource;
|
||||
import co.yixiang.yshop.framework.social.core.request.AuthWeChatMiniAppRequest;
|
||||
import com.xkcoding.justauth.AuthRequestFactory;
|
||||
import com.xkcoding.justauth.autoconfigure.JustAuthProperties;
|
||||
import me.zhyd.oauth.cache.AuthStateCache;
|
||||
import me.zhyd.oauth.config.AuthConfig;
|
||||
import me.zhyd.oauth.config.AuthSource;
|
||||
import me.zhyd.oauth.request.AuthRequest;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 第三方授权拓展 request 工厂类
|
||||
* 为使得拓展配置 {@link AuthConfig} 和默认配置齐平,所以自定义本工厂类
|
||||
*
|
||||
* @author timfruit
|
||||
* @date 2021-10-31
|
||||
*/
|
||||
public class YshopAuthRequestFactory extends AuthRequestFactory {
|
||||
|
||||
protected JustAuthProperties properties;
|
||||
protected AuthStateCache authStateCache;
|
||||
|
||||
/**
|
||||
* 由于父类 configureHttpConfig 方法是 private 修饰,所以获取后,进行反射调用
|
||||
*/
|
||||
private final Method configureHttpConfigMethod = ReflectUtil.getMethod(AuthRequestFactory.class,
|
||||
"configureHttpConfig", String.class, AuthConfig.class, JustAuthProperties.JustAuthHttpConfig.class);
|
||||
|
||||
public YshopAuthRequestFactory(JustAuthProperties properties, AuthStateCache authStateCache) {
|
||||
super(properties, authStateCache);
|
||||
this.properties = properties;
|
||||
this.authStateCache = authStateCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回 AuthRequest 对象
|
||||
*
|
||||
* @param source {@link AuthSource}
|
||||
* @return {@link AuthRequest}
|
||||
*/
|
||||
@Override
|
||||
public AuthRequest get(String source) {
|
||||
// 先尝试获取自定义扩展的
|
||||
AuthRequest authRequest = getExtendRequest(source);
|
||||
// 找不到,使用默认拓展
|
||||
if (authRequest == null) {
|
||||
authRequest = super.get(source);
|
||||
}
|
||||
return authRequest;
|
||||
}
|
||||
|
||||
protected AuthRequest getExtendRequest(String source) {
|
||||
AuthExtendSource authExtendSource;
|
||||
try {
|
||||
authExtendSource = EnumUtil.fromString(AuthExtendSource.class, source.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 无自定义匹配
|
||||
return null;
|
||||
}
|
||||
|
||||
// 拓展配置和默认配置齐平,properties 放在一起
|
||||
AuthConfig config = properties.getType().get(authExtendSource.name());
|
||||
// 找不到对应关系,直接返回空
|
||||
if (config == null) {
|
||||
return null;
|
||||
}
|
||||
// 反射调用,配置 http config
|
||||
ReflectUtil.invoke(this, configureHttpConfigMethod, authExtendSource.name(), config, properties.getHttpConfig());
|
||||
|
||||
// 获得拓展的 Request
|
||||
// noinspection SwitchStatementWithTooFewBranches
|
||||
switch (authExtendSource) {
|
||||
case WECHAT_MINI_APP:
|
||||
return new AuthWeChatMiniAppRequest(config, authStateCache);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package co.yixiang.yshop.framework.social.core;
|
||||
|
||||
import cn.hutool.core.util.EnumUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import co.yixiang.yshop.framework.social.core.enums.AuthExtendSource;
|
||||
import co.yixiang.yshop.framework.social.core.request.AuthWeChatMiniAppRequest;
|
||||
import com.xkcoding.justauth.AuthRequestFactory;
|
||||
import com.xkcoding.justauth.autoconfigure.JustAuthProperties;
|
||||
import me.zhyd.oauth.cache.AuthStateCache;
|
||||
import me.zhyd.oauth.config.AuthConfig;
|
||||
import me.zhyd.oauth.config.AuthSource;
|
||||
import me.zhyd.oauth.request.AuthRequest;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 第三方授权拓展 request 工厂类
|
||||
* 为使得拓展配置 {@link AuthConfig} 和默认配置齐平,所以自定义本工厂类
|
||||
*
|
||||
* @author timfruit
|
||||
* @date 2021-10-31
|
||||
*/
|
||||
public class YshopAuthRequestFactory extends AuthRequestFactory {
|
||||
|
||||
protected JustAuthProperties properties;
|
||||
protected AuthStateCache authStateCache;
|
||||
|
||||
/**
|
||||
* 由于父类 configureHttpConfig 方法是 private 修饰,所以获取后,进行反射调用
|
||||
*/
|
||||
private final Method configureHttpConfigMethod = ReflectUtil.getMethod(AuthRequestFactory.class,
|
||||
"configureHttpConfig", String.class, AuthConfig.class, JustAuthProperties.JustAuthHttpConfig.class);
|
||||
|
||||
public YshopAuthRequestFactory(JustAuthProperties properties, AuthStateCache authStateCache) {
|
||||
super(properties, authStateCache);
|
||||
this.properties = properties;
|
||||
this.authStateCache = authStateCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回 AuthRequest 对象
|
||||
*
|
||||
* @param source {@link AuthSource}
|
||||
* @return {@link AuthRequest}
|
||||
*/
|
||||
@Override
|
||||
public AuthRequest get(String source) {
|
||||
// 先尝试获取自定义扩展的
|
||||
AuthRequest authRequest = getExtendRequest(source);
|
||||
// 找不到,使用默认拓展
|
||||
if (authRequest == null) {
|
||||
authRequest = super.get(source);
|
||||
}
|
||||
return authRequest;
|
||||
}
|
||||
|
||||
protected AuthRequest getExtendRequest(String source) {
|
||||
AuthExtendSource authExtendSource;
|
||||
try {
|
||||
authExtendSource = EnumUtil.fromString(AuthExtendSource.class, source.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 无自定义匹配
|
||||
return null;
|
||||
}
|
||||
|
||||
// 拓展配置和默认配置齐平,properties 放在一起
|
||||
AuthConfig config = properties.getType().get(authExtendSource.name());
|
||||
// 找不到对应关系,直接返回空
|
||||
if (config == null) {
|
||||
return null;
|
||||
}
|
||||
// 反射调用,配置 http config
|
||||
ReflectUtil.invoke(this, configureHttpConfigMethod, authExtendSource.name(), config, properties.getHttpConfig());
|
||||
|
||||
// 获得拓展的 Request
|
||||
// noinspection SwitchStatementWithTooFewBranches
|
||||
switch (authExtendSource) {
|
||||
case WECHAT_MINI_APP:
|
||||
return new AuthWeChatMiniAppRequest(config, authStateCache);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,39 +1,39 @@
|
||||
package co.yixiang.yshop.framework.social.core.enums;
|
||||
|
||||
import me.zhyd.oauth.config.AuthSource;
|
||||
|
||||
/**
|
||||
* 拓展 JustAuth 各 api 需要的 url, 用枚举类分平台类型管理
|
||||
*
|
||||
* 默认配置 {@link me.zhyd.oauth.config.AuthDefaultSource}
|
||||
*
|
||||
* @author timfruit
|
||||
*/
|
||||
public enum AuthExtendSource implements AuthSource {
|
||||
|
||||
/**
|
||||
* 微信小程序授权登录
|
||||
*/
|
||||
WECHAT_MINI_APP {
|
||||
|
||||
@Override
|
||||
public String authorize() {
|
||||
// 参见 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 文档
|
||||
throw new UnsupportedOperationException("不支持获取授权 url,请使用小程序内置函数 wx.login() 登录获取 code");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String accessToken() {
|
||||
// 参见 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html 文档
|
||||
// 获取 openid, unionId , session_key 等字段
|
||||
return "https://api.weixin.qq.com/sns/jscode2session";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String userInfo() {
|
||||
// 参见 https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserProfile.html 文档
|
||||
throw new UnsupportedOperationException("不支持获取用户信息 url,请使用小程序内置函数 wx.getUserProfile() 获取用户信息");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package co.yixiang.yshop.framework.social.core.enums;
|
||||
|
||||
import me.zhyd.oauth.config.AuthSource;
|
||||
|
||||
/**
|
||||
* 拓展 JustAuth 各 api 需要的 url, 用枚举类分平台类型管理
|
||||
*
|
||||
* 默认配置 {@link me.zhyd.oauth.config.AuthDefaultSource}
|
||||
*
|
||||
* @author timfruit
|
||||
*/
|
||||
public enum AuthExtendSource implements AuthSource {
|
||||
|
||||
/**
|
||||
* 微信小程序授权登录
|
||||
*/
|
||||
WECHAT_MINI_APP {
|
||||
|
||||
@Override
|
||||
public String authorize() {
|
||||
// 参见 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 文档
|
||||
throw new UnsupportedOperationException("不支持获取授权 url,请使用小程序内置函数 wx.login() 登录获取 code");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String accessToken() {
|
||||
// 参见 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html 文档
|
||||
// 获取 openid, unionId , session_key 等字段
|
||||
return "https://api.weixin.qq.com/sns/jscode2session";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String userInfo() {
|
||||
// 参见 https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserProfile.html 文档
|
||||
throw new UnsupportedOperationException("不支持获取用户信息 url,请使用小程序内置函数 wx.getUserProfile() 获取用户信息");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import co.yixiang.yshop.framework.quartz.core.handler.JobHandlerInvoker;
|
||||
import org.quartz.*;
|
||||
|
||||
/**
|
||||
* {@link org.quartz.Scheduler} 的管理器,负责创建任务
|
||||
* {@link Scheduler} 的管理器,负责创建任务
|
||||
*
|
||||
* 考虑到实现的简洁性,我们使用 jobHandlerName 作为唯一标识,即:
|
||||
* 1. Job 的 {@link JobDetail#getKey()}
|
||||
|
@ -23,7 +23,7 @@ public class DefaultStreamMessageListenerContainerX<K, V extends Record<K, ?>> e
|
||||
/**
|
||||
* 参考 {@link StreamMessageListenerContainer#create(RedisConnectionFactory, StreamMessageListenerContainerOptions)} 的实现
|
||||
*/
|
||||
public static <K, V extends Record<K, ?>> StreamMessageListenerContainer<K, V> create(RedisConnectionFactory connectionFactory, StreamMessageListenerContainer.StreamMessageListenerContainerOptions<K, V> options) {
|
||||
public static <K, V extends Record<K, ?>> StreamMessageListenerContainer<K, V> create(RedisConnectionFactory connectionFactory, StreamMessageListenerContainerOptions<K, V> options) {
|
||||
Assert.notNull(connectionFactory, "RedisConnectionFactory must not be null!");
|
||||
Assert.notNull(options, "StreamMessageListenerContainerOptions must not be null!");
|
||||
return new DefaultStreamMessageListenerContainerX<>(connectionFactory, options);
|
||||
|
@ -13,7 +13,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* 字段字段的 TypeHandler 实现类,基于 {@link cn.hutool.crypto.symmetric.AES} 实现
|
||||
* 字段字段的 TypeHandler 实现类,基于 {@link AES} 实现
|
||||
* 可通过 jasypt.encryptor.password 配置项,设置密钥
|
||||
*
|
||||
* @author yshop
|
||||
|
@ -1,11 +1,16 @@
|
||||
package co.yixiang.yshop.framework.xss.config;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import co.yixiang.yshop.framework.common.enums.WebFilterOrderEnum;
|
||||
import co.yixiang.yshop.framework.xss.core.clean.JsoupXssCleaner;
|
||||
import co.yixiang.yshop.framework.xss.core.clean.XssCleaner;
|
||||
import co.yixiang.yshop.framework.xss.core.filter.XssFilter;
|
||||
import co.yixiang.yshop.framework.xss.core.json.XssStringJsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@ -14,9 +19,14 @@ import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilde
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
import static co.yixiang.yshop.framework.web.config.YshopWebAutoConfiguration.createFilterBean;
|
||||
|
||||
@AutoConfiguration
|
||||
@ -48,6 +58,19 @@ public class YshopXssAutoConfiguration implements WebMvcConfigurer {
|
||||
return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
|
||||
//日期转字符串
|
||||
return builder -> builder.serializerByType(LocalDate.class, new LocalDateTimeSerializer(DatePattern.NORM_DATE_FORMATTER))
|
||||
.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DatePattern.NORM_DATETIME_FORMATTER))
|
||||
.serializerByType(LocalTime.class, new LocalDateTimeSerializer(DatePattern.NORM_TIME_FORMATTER))
|
||||
//字符串转日期
|
||||
.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DatePattern.NORM_DATETIME_FORMATTER))
|
||||
.deserializerByType(LocalDate.class, new LocalDateDeserializer(DatePattern.NORM_DATE_FORMATTER))
|
||||
.deserializerByType(LocalTime.class, new LocalTimeDeserializer(DatePattern.NORM_TIME_FORMATTER));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 XssFilter Bean,解决 Xss 安全问题
|
||||
*/
|
||||
|
Reference in New Issue
Block a user