This commit is contained in:
徐唯轩
2023-11-14 16:32:59 +08:00
parent 441dad9ef6
commit 751ed76e37
298 changed files with 10073 additions and 3527 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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())

View File

@ -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;
}

View File

@ -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;

View File

@ -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")

View File

@ -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() {

View File

@ -6,7 +6,7 @@ import java.time.Duration;
import java.time.LocalDateTime;
/**
* 时间工具类,用于 {@link java.time.LocalDateTime}
* 时间工具类,用于 {@link LocalDateTime}
*
* @author yshop
*/

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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));
}
}

View File

@ -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", "华为云"),
;
/**

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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() 获取用户信息");
}
}
}

View File

@ -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()}

View File

@ -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);

View File

@ -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

View File

@ -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 安全问题
*/