feat:优化
@@ -0,0 +1,31 @@
|
||||
package cn.odboy.config;
|
||||
|
||||
import cn.odboy.config.model.ContentRsaEncodeSettingModel;
|
||||
import cn.odboy.config.model.FileUploadSettingModel;
|
||||
import cn.odboy.config.model.JwtAuthSettingModel;
|
||||
import cn.odboy.config.model.QuartzTaskThreadPoolSettingModel;
|
||||
import cn.odboy.config.model.SwaggerApiDocSettingModel;
|
||||
import cn.odboy.config.model.UserLoginSettingModel;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 应用配置
|
||||
*
|
||||
* @author odboy
|
||||
* @date 2025-04-13
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "app")
|
||||
public class AppProperties {
|
||||
private FileUploadSettingModel file;
|
||||
private ContentRsaEncodeSettingModel rsa;
|
||||
private JwtAuthSettingModel jwt;
|
||||
private UserLoginSettingModel login;
|
||||
private SwaggerApiDocSettingModel swagger;
|
||||
private QuartzTaskThreadPoolSettingModel asyncTaskPool;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.odboy.config.model;
|
||||
|
||||
import lombok.Data;
|
||||
/**
|
||||
* 密码加密传输,前端公钥加密,后端私钥解密
|
||||
*/
|
||||
@Data
|
||||
public class ContentRsaEncodeSettingModel {
|
||||
public String privateKey;
|
||||
}
|
||||
@@ -1,20 +1,17 @@
|
||||
package cn.odboy.properties;
|
||||
package cn.odboy.config.model;
|
||||
|
||||
import cn.odboy.constant.SystemConst;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 文件上传配置
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "file")
|
||||
public class FileProperties {
|
||||
|
||||
public class FileUploadSettingModel {
|
||||
/**
|
||||
* 文件大小限制
|
||||
*/
|
||||
private Long maxSize;
|
||||
|
||||
private Long fileMaxSize;
|
||||
/**
|
||||
* 头像大小限制
|
||||
*/
|
||||
@@ -1,16 +1,12 @@
|
||||
package cn.odboy.application.core.config;
|
||||
package cn.odboy.config.model;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Jwt参数配置
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "jwt")
|
||||
public class SecurityProperties {
|
||||
public class JwtAuthSettingModel {
|
||||
/**
|
||||
* 必须使用最少88位的Base64对该令牌进行编码
|
||||
*/
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.odboy.config.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 定时任务线程池 配置
|
||||
*
|
||||
* @author odboy
|
||||
* @date 2025-04-13
|
||||
*/
|
||||
@Data
|
||||
public class QuartzTaskThreadPoolSettingModel {
|
||||
/**
|
||||
* 核心线程池大小
|
||||
*/
|
||||
private int corePoolSize;
|
||||
/**
|
||||
* 最大线程数
|
||||
*/
|
||||
private int maxPoolSize;
|
||||
/**
|
||||
* 活跃时间
|
||||
*/
|
||||
private int keepAliveSeconds;
|
||||
/**
|
||||
* 队列容量
|
||||
*/
|
||||
private int queueCapacity;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package cn.odboy.config.model;
|
||||
|
||||
import lombok.Data;
|
||||
/**
|
||||
*
|
||||
* @author odboy
|
||||
* @date 2025-04-13
|
||||
*/
|
||||
@Data
|
||||
public class SwaggerApiDocSettingModel {
|
||||
private boolean enabled;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.odboy.application.core.config;
|
||||
package cn.odboy.config.model;
|
||||
|
||||
import cn.odboy.application.core.constant.LoginCodeEnum;
|
||||
import cn.odboy.constant.LoginCodeEnum;
|
||||
import cn.odboy.exception.BadRequestException;
|
||||
import cn.odboy.util.StringUtil;
|
||||
import com.wf.captcha.ArithmeticCaptcha;
|
||||
@@ -10,22 +10,13 @@ import com.wf.captcha.GifCaptcha;
|
||||
import com.wf.captcha.SpecCaptcha;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* 登录验证码配置信息
|
||||
* 验证码配置
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "login.code")
|
||||
public class CaptchaProperties {
|
||||
/**
|
||||
* 验证码配置
|
||||
*/
|
||||
@Getter
|
||||
public class UserLoginCaptchaSettingModel {
|
||||
private LoginCodeEnum codeType;
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.odboy.config.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 登录配置
|
||||
*/
|
||||
@Data
|
||||
public class UserLoginSettingModel {
|
||||
/**
|
||||
* 账号单用户 登录
|
||||
*/
|
||||
private boolean single = false;
|
||||
private UserLoginCaptchaSettingModel captchaSetting;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.odboy.constant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 验证码业务场景
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CaptchaBizEnum {
|
||||
|
||||
/* 通过手机号码重置邮箱 */
|
||||
PHONE_RESET_EMAIL_CODE("10000", "phone_reset_email_code_", "通过手机号码重置邮箱"),
|
||||
|
||||
/* 通过旧邮箱重置邮箱 */
|
||||
EMAIL_RESET_EMAIL_CODE("10001", "email_reset_email_code_", "通过旧邮箱重置邮箱"),
|
||||
|
||||
/* 通过手机号码重置密码 */
|
||||
PHONE_RESET_PWD_CODE("10002", "phone_reset_pwd_code_", "通过手机号码重置密码"),
|
||||
|
||||
/* 通过邮箱重置密码 */
|
||||
EMAIL_RESET_PWD_CODE("10003", "email_reset_pwd_code_", "通过邮箱重置密码");
|
||||
|
||||
/**
|
||||
* 业务编码
|
||||
*/
|
||||
private final String bizCode;
|
||||
/**
|
||||
* redis中的key
|
||||
*/
|
||||
private final String redisKey;
|
||||
/**
|
||||
* 业务描述
|
||||
*/
|
||||
private final String description;
|
||||
|
||||
public static CaptchaBizEnum getByBizCode(String bizCode) {
|
||||
for (CaptchaBizEnum value : CaptchaBizEnum.values()) {
|
||||
if (value.getBizCode().equals(bizCode)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package cn.odboy.constant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 验证码业务场景
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CodeBiEnum {
|
||||
|
||||
/* 旧邮箱修改邮箱 */
|
||||
ONE(1, "旧邮箱修改邮箱"),
|
||||
|
||||
/* 通过邮箱修改密码 */
|
||||
TWO(2, "通过邮箱修改密码");
|
||||
|
||||
private final Integer code;
|
||||
private final String description;
|
||||
|
||||
public static CodeBiEnum find(Integer code) {
|
||||
for (CodeBiEnum value : CodeBiEnum.values()) {
|
||||
if (value.getCode().equals(code)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package cn.odboy.constant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 验证码业务场景对应的 Redis 中的 key
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CodeEnum {
|
||||
|
||||
/* 通过手机号码重置邮箱 */
|
||||
PHONE_RESET_EMAIL_CODE("phone_reset_email_code_", "通过手机号码重置邮箱"),
|
||||
|
||||
/* 通过旧邮箱重置邮箱 */
|
||||
EMAIL_RESET_EMAIL_CODE("email_reset_email_code_", "通过旧邮箱重置邮箱"),
|
||||
|
||||
/* 通过手机号码重置密码 */
|
||||
PHONE_RESET_PWD_CODE("phone_reset_pwd_code_", "通过手机号码重置密码"),
|
||||
|
||||
/* 通过邮箱重置密码 */
|
||||
EMAIL_RESET_PWD_CODE("email_reset_pwd_code_", "通过邮箱重置密码");
|
||||
|
||||
private final String key;
|
||||
private final String description;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.odboy.application.core.constant;
|
||||
package cn.odboy.constant;
|
||||
|
||||
/**
|
||||
* 验证码配置枚举
|
||||
@@ -23,11 +23,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -60,22 +56,6 @@ public interface EasyMapper<E> extends BaseMapper<E> {
|
||||
*/
|
||||
int alwaysUpdateSomeColumnById(@Param("et") E entity);
|
||||
|
||||
default QueryChainWrapper<E> select() {
|
||||
return ChainWrappers.queryChain(this);
|
||||
}
|
||||
|
||||
default UpdateChainWrapper<E> update() {
|
||||
return ChainWrappers.updateChain(this);
|
||||
}
|
||||
|
||||
default LambdaQueryChainWrapper<E> lambdaSelect() {
|
||||
return ChainWrappers.lambdaQueryChain(this);
|
||||
}
|
||||
|
||||
default LambdaUpdateChainWrapper<E> lambdaUpdate() {
|
||||
return ChainWrappers.lambdaUpdateChain(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典
|
||||
*
|
||||
@@ -84,7 +64,7 @@ public interface EasyMapper<E> extends BaseMapper<E> {
|
||||
* @param valueName 值对应的列名称
|
||||
* @return Map<String, Object>
|
||||
*/
|
||||
default Map<String, Object> selectMap(LambdaQueryWrapper<E> wrapper, String keyName, String valueName) {
|
||||
default Map<String, Object> getMapWithKv(LambdaQueryWrapper<E> wrapper, String keyName, String valueName) {
|
||||
Map<String, Object> result = new ConcurrentHashMap<>(1);
|
||||
List<E> list = this.selectList(wrapper);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
@@ -123,7 +103,7 @@ public interface EasyMapper<E> extends BaseMapper<E> {
|
||||
* @param clazz 期望的对象类型
|
||||
* @return List<T>
|
||||
*/
|
||||
default <T> List<T> selectList(LambdaQueryWrapper<E> wrapper, Class<T> clazz) {
|
||||
default <T> List<T> queryFeatureClazzList(LambdaQueryWrapper<E> wrapper, Class<T> clazz) {
|
||||
List<E> list = this.selectList(wrapper);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return new ArrayList<>();
|
||||
@@ -138,7 +118,7 @@ public interface EasyMapper<E> extends BaseMapper<E> {
|
||||
* @param clazz 期望的对象类型
|
||||
* @return List<T>
|
||||
*/
|
||||
default <T> List<T> selectList(LambdaQueryChainWrapper<E> wrapper, Class<T> clazz) {
|
||||
default <T> List<T> queryFeatureClazzList(LambdaQueryChainWrapper<E> wrapper, Class<T> clazz) {
|
||||
List<E> list = wrapper.list();
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return new ArrayList<>();
|
||||
@@ -154,7 +134,7 @@ public interface EasyMapper<E> extends BaseMapper<E> {
|
||||
* @param clazz 期望的对象类型
|
||||
* @return IPage<T>
|
||||
*/
|
||||
default <T> PageResult<T> selectPage(Pageable pageable, LambdaQueryWrapper<E> wrapper, Class<T> clazz) {
|
||||
default <T> PageResult<T> queryFeatureClazzPage(Pageable pageable, LambdaQueryWrapper<E> wrapper, Class<T> clazz) {
|
||||
int pageNumber = pageable.getPageNumber();
|
||||
int pageSize = pageable.getPageSize();
|
||||
pageNumber = pageNumber <= 0 ? 1 : pageNumber;
|
||||
@@ -174,7 +154,7 @@ public interface EasyMapper<E> extends BaseMapper<E> {
|
||||
* @param clazz 期望的对象类型
|
||||
* @return IPage<T>
|
||||
*/
|
||||
default <T> PageResult<T> selectPage(Pageable pageable, LambdaQueryChainWrapper<E> wrapper, Class<T> clazz) {
|
||||
default <T> PageResult<T> queryFeatureClazzPage(Pageable pageable, LambdaQueryChainWrapper<E> wrapper, Class<T> clazz) {
|
||||
int pageNumber = pageable.getPageNumber();
|
||||
int pageSize = pageable.getPageSize();
|
||||
pageNumber = pageNumber <= 0 ? 1 : pageNumber;
|
||||
@@ -193,7 +173,7 @@ public interface EasyMapper<E> extends BaseMapper<E> {
|
||||
* @param clazz 期望的对象类型
|
||||
* @return T
|
||||
*/
|
||||
default <T> T selectOne(LambdaQueryChainWrapper<E> wrapper, Class<T> clazz) {
|
||||
default <T> T getFeatureClazz(LambdaQueryChainWrapper<E> wrapper, Class<T> clazz) {
|
||||
E e = this.selectOne(wrapper);
|
||||
if (e == null) {
|
||||
return null;
|
||||
|
||||
@@ -31,41 +31,39 @@ import java.util.List;
|
||||
* @date 2022-04-03
|
||||
*/
|
||||
public interface EasyService<T> extends IService<T> {
|
||||
LambdaQueryWrapper<T> quick();
|
||||
<G> int saveFeatureClazz(G resources);
|
||||
|
||||
<G> int quickSave(G resources);
|
||||
<G> int saveFeatureClazzList(List<G> resources);
|
||||
|
||||
<G> int quickSaveBatch(List<G> resources);
|
||||
<G> int modifyFeatureClazzById(G resources);
|
||||
|
||||
<G> int quickModifyById(G resources);
|
||||
<G> boolean modifyFeatureClazzListById(Collection<G> resources, int batchSize);
|
||||
|
||||
<G> boolean quickModifyBatchById(Collection<G> resources, int batchSize);
|
||||
<G> G describeFeatureClazzById(Serializable id, Class<G> targetClazz);
|
||||
|
||||
<G> G quickGetOneById(Serializable id, Class<G> targetClazz);
|
||||
T describeClazzByArgs(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn);
|
||||
|
||||
T quickGetOne(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn);
|
||||
<G> G describeFeatureClazzByArgs(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn, Class<G> clazz);
|
||||
|
||||
<G> G quickGetOne(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn, Class<G> clazz);
|
||||
<G> List<G> describeFeatureClazzListByIds(List<Serializable> ids, Class<G> targetClazz);
|
||||
|
||||
<G> List<G> quickListByIds(List<Serializable> ids, Class<G> targetClazz);
|
||||
<Q> List<T> describeClazzListByArgs(Q criteria);
|
||||
|
||||
<Q> List<T> quickList(Q criteria);
|
||||
List<T> describeClazzListByArgs(LambdaQueryWrapper<T> wrapper);
|
||||
|
||||
List<T> quickList(LambdaQueryWrapper<T> wrapper);
|
||||
<G, Q> List<G> describeFeatureClazzListByArgs(Q criteria, Class<G> targetClazz);
|
||||
|
||||
<G, Q> List<G> quickList(Q criteria, Class<G> targetClazz);
|
||||
<G> List<G> describeFeatureClazzListByArgs(LambdaQueryWrapper<T> wrapper, Class<G> targetClazz);
|
||||
|
||||
<G> List<G> quickList(LambdaQueryWrapper<T> wrapper, Class<G> targetClazz);
|
||||
PageResult<T> describeClazzPageByArgs(LambdaQueryWrapper<T> wrapper, IPage<T> pageable);
|
||||
|
||||
PageResult<T> quickPage(LambdaQueryWrapper<T> wrapper, IPage<T> pageable);
|
||||
<G> PageResult<G> describeFeatureClazzPageByArgs(LambdaQueryWrapper<T> wrapper, IPage<T> pageable, Class<G> targetClazz);
|
||||
|
||||
<G> PageResult<G> quickPage(LambdaQueryWrapper<T> wrapper, IPage<T> pageable, Class<G> targetClazz);
|
||||
<G, Q> PageResult<G> describeFeatureClazzPageByArgs(Q criteria, IPage<T> pageable, Class<G> targetClazz);
|
||||
|
||||
<G, Q> PageResult<G> quickPage(Q criteria, IPage<T> pageable, Class<G> targetClazz);
|
||||
<Q> PageResult<T> describeClazzPageByArgs(Q criteria, IPage<T> pageable);
|
||||
|
||||
<Q> PageResult<T> quickPage(Q criteria, IPage<T> pageable);
|
||||
int modifyClazzByArgs(LambdaQueryWrapper<T> wrapper, T entity);
|
||||
|
||||
int quickUpdate(LambdaQueryWrapper<T> wrapper, T entity);
|
||||
|
||||
int quickDelete(LambdaQueryWrapper<T> wrapper);
|
||||
int removeClazzByArgs(LambdaQueryWrapper<T> wrapper);
|
||||
}
|
||||
|
||||
@@ -39,16 +39,12 @@ import java.util.List;
|
||||
* @date 2022-04-03
|
||||
*/
|
||||
public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M, T> {
|
||||
public LambdaQueryWrapper<T> quick() {
|
||||
return new LambdaQueryWrapper<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速插入
|
||||
*
|
||||
* @param resources /
|
||||
*/
|
||||
public <G> int quickSave(G resources) {
|
||||
public <G> int saveFeatureClazz(G resources) {
|
||||
return getBaseMapper().insert(BeanUtil.copyProperties(resources, this.getEntityClass()));
|
||||
}
|
||||
|
||||
@@ -57,7 +53,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
*
|
||||
* @param resources /
|
||||
*/
|
||||
public <G> int quickSaveBatch(List<G> resources) {
|
||||
public <G> int saveFeatureClazzList(List<G> resources) {
|
||||
return getBaseMapper().insertBatchSomeColumn(BeanUtil.copyToList(resources, this.getEntityClass()));
|
||||
}
|
||||
|
||||
@@ -66,7 +62,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
*
|
||||
* @param resources /
|
||||
*/
|
||||
public <G> int quickModifyById(G resources) {
|
||||
public <G> int modifyFeatureClazzById(G resources) {
|
||||
return getBaseMapper().updateById(BeanUtil.copyProperties(resources, this.getEntityClass()));
|
||||
}
|
||||
|
||||
@@ -76,7 +72,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
* @param resources /
|
||||
* @param batchSize 每批数量
|
||||
*/
|
||||
public <G> boolean quickModifyBatchById(Collection<G> resources, int batchSize) {
|
||||
public <G> boolean modifyFeatureClazzListById(Collection<G> resources, int batchSize) {
|
||||
String sqlStatement = this.getSqlStatement(SqlMethod.UPDATE_BY_ID);
|
||||
return this.executeBatch(resources, batchSize, (sqlSession, entity) -> {
|
||||
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||
@@ -91,7 +87,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
* @param id /
|
||||
* @param targetClazz 目标类型
|
||||
*/
|
||||
public <G> G quickGetOneById(Serializable id, Class<G> targetClazz) {
|
||||
public <G> G describeFeatureClazzById(Serializable id, Class<G> targetClazz) {
|
||||
T entity = this.getById(id);
|
||||
return entity == null ? null : BeanUtil.copyProperties(entity, targetClazz);
|
||||
}
|
||||
@@ -101,7 +97,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
*
|
||||
* @param wrapper 制造条件
|
||||
*/
|
||||
public T quickGetOne(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn) {
|
||||
public T describeClazzByArgs(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn) {
|
||||
if (orderColumn == null) {
|
||||
throw new BadRequestException("参数orderColumn(排序的列)必填");
|
||||
}
|
||||
@@ -117,7 +113,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
return ts.stream().findFirst().get();
|
||||
}
|
||||
|
||||
public <G> G quickGetOne(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn, Class<G> clazz) {
|
||||
public <G> G describeFeatureClazzByArgs(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> orderColumn, Class<G> clazz) {
|
||||
if (orderColumn == null) {
|
||||
throw new BadRequestException("参数orderColumn(排序的列)必填");
|
||||
}
|
||||
@@ -139,7 +135,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
* @param ids /
|
||||
* @param targetClazz 目标类型
|
||||
*/
|
||||
public <G> List<G> quickListByIds(List<Serializable> ids, Class<G> targetClazz) {
|
||||
public <G> List<G> describeFeatureClazzListByIds(List<Serializable> ids, Class<G> targetClazz) {
|
||||
List<T> entitys = this.listByIds(ids);
|
||||
return entitys == null || entitys.isEmpty() ? CollUtil.newArrayList() : BeanUtil.copyToList(entitys, targetClazz);
|
||||
}
|
||||
@@ -149,7 +145,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
*
|
||||
* @param criteria 动态条件
|
||||
*/
|
||||
public <Q> List<T> quickList(Q criteria) {
|
||||
public <Q> List<T> describeClazzListByArgs(Q criteria) {
|
||||
QueryWrapper<T> predicate = MybatisHelper.build(criteria);
|
||||
return baseMapper.selectList(predicate);
|
||||
}
|
||||
@@ -159,7 +155,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
*
|
||||
* @param wrapper 制造条件
|
||||
*/
|
||||
public List<T> quickList(LambdaQueryWrapper<T> wrapper) {
|
||||
public List<T> describeClazzListByArgs(LambdaQueryWrapper<T> wrapper) {
|
||||
if (wrapper == null) {
|
||||
wrapper = new LambdaQueryWrapper<>();
|
||||
}
|
||||
@@ -172,7 +168,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
* @param criteria 动态条件
|
||||
* @param targetClazz 目标类型
|
||||
*/
|
||||
public <G, Q> List<G> quickList(Q criteria, Class<G> targetClazz) {
|
||||
public <G, Q> List<G> describeFeatureClazzListByArgs(Q criteria, Class<G> targetClazz) {
|
||||
QueryWrapper<T> predicate = MybatisHelper.build(criteria);
|
||||
List<T> data = baseMapper.selectList(predicate);
|
||||
return BeanUtil.copyToList(data, targetClazz);
|
||||
@@ -184,7 +180,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
* @param wrapper 制造条件
|
||||
* @param targetClazz 目标类型
|
||||
*/
|
||||
public <G> List<G> quickList(LambdaQueryWrapper<T> wrapper, Class<G> targetClazz) {
|
||||
public <G> List<G> describeFeatureClazzListByArgs(LambdaQueryWrapper<T> wrapper, Class<G> targetClazz) {
|
||||
if (wrapper == null) {
|
||||
wrapper = new LambdaQueryWrapper<>();
|
||||
}
|
||||
@@ -197,7 +193,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
* @param wrapper 制造条件
|
||||
* @param pageable 分页参数
|
||||
*/
|
||||
public PageResult<T> quickPage(LambdaQueryWrapper<T> wrapper, IPage<T> pageable) {
|
||||
public PageResult<T> describeClazzPageByArgs(LambdaQueryWrapper<T> wrapper, IPage<T> pageable) {
|
||||
if (wrapper == null) {
|
||||
wrapper = new LambdaQueryWrapper<>();
|
||||
}
|
||||
@@ -212,7 +208,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
* @param pageable 分页参数
|
||||
* @param targetClazz 目标类型
|
||||
*/
|
||||
public <G> PageResult<G> quickPage(LambdaQueryWrapper<T> wrapper, IPage<T> pageable, Class<G> targetClazz) {
|
||||
public <G> PageResult<G> describeFeatureClazzPageByArgs(LambdaQueryWrapper<T> wrapper, IPage<T> pageable, Class<G> targetClazz) {
|
||||
if (wrapper == null) {
|
||||
wrapper = new LambdaQueryWrapper<>();
|
||||
}
|
||||
@@ -220,13 +216,13 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
return new PageResult<>(BeanUtil.copyToList(originPageData.getRecords(), targetClazz), originPageData.getTotal());
|
||||
}
|
||||
|
||||
public <G, Q> PageResult<G> quickPage(Q criteria, IPage<T> pageable, Class<G> targetClazz) {
|
||||
public <G, Q> PageResult<G> describeFeatureClazzPageByArgs(Q criteria, IPage<T> pageable, Class<G> targetClazz) {
|
||||
QueryWrapper<T> wrapper = MybatisHelper.build(criteria);
|
||||
IPage<T> originPageData = baseMapper.selectPage(pageable, wrapper);
|
||||
return new PageResult<>(BeanUtil.copyToList(originPageData.getRecords(), targetClazz), originPageData.getTotal());
|
||||
}
|
||||
|
||||
public <Q> PageResult<T> quickPage(Q criteria, IPage<T> pageable) {
|
||||
public <Q> PageResult<T> describeClazzPageByArgs(Q criteria, IPage<T> pageable) {
|
||||
QueryWrapper<T> wrapper = MybatisHelper.build(criteria);
|
||||
IPage<T> originPageData = baseMapper.selectPage(pageable, wrapper);
|
||||
return new PageResult<>(originPageData.getRecords(), originPageData.getTotal());
|
||||
@@ -238,7 +234,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
* @param wrapper 制造条件
|
||||
* @param entity 更新内容
|
||||
*/
|
||||
public int quickUpdate(LambdaQueryWrapper<T> wrapper, T entity) {
|
||||
public int modifyClazzByArgs(LambdaQueryWrapper<T> wrapper, T entity) {
|
||||
if (wrapper == null) {
|
||||
throw new BadRequestException("参数wrapper必填");
|
||||
}
|
||||
@@ -250,7 +246,7 @@ public class EasyServiceImpl<M extends EasyMapper<T>, T> extends ServiceImpl<M,
|
||||
*
|
||||
* @param wrapper 制造条件
|
||||
*/
|
||||
public int quickDelete(LambdaQueryWrapper<T> wrapper) {
|
||||
public int removeClazzByArgs(LambdaQueryWrapper<T> wrapper) {
|
||||
if (wrapper == null) {
|
||||
throw new BadRequestException("参数wrapper必填");
|
||||
}
|
||||
|
||||
@@ -36,20 +36,17 @@ public class MybatisHelper {
|
||||
try {
|
||||
List<Field> fields = getAllFields(clazz, new ArrayList<>());
|
||||
for (Field field : fields) {
|
||||
if (!field.canAccess(clazz)) {
|
||||
if (!field.canAccess(query)) {
|
||||
field.setAccessible(true);
|
||||
MpQuery q = field.getAnnotation(MpQuery.class);
|
||||
if (q != null) {
|
||||
String propName = q.propName();
|
||||
String blurry = q.blurry();
|
||||
String attributeName = StrUtil.isBlank(propName) ? field.getName() : propName;
|
||||
attributeName = humpToUnderline(attributeName);
|
||||
String attributeName = getAttributeName(q, field);
|
||||
Object fieldVal = field.get(query);
|
||||
if (ObjectUtil.isNull(fieldVal) || "".equals(fieldVal)) {
|
||||
continue;
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(blurry)) {
|
||||
handleBlurryQuery(queryWrapper, blurry, fieldVal);
|
||||
if (StrUtil.isNotBlank(q.blurry())) {
|
||||
handleBlurryQuery(queryWrapper, q.blurry(), fieldVal);
|
||||
continue;
|
||||
}
|
||||
handleWrapper(q, queryWrapper, attributeName, fieldVal);
|
||||
@@ -58,11 +55,16 @@ public class MybatisHelper {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("组装SQL失败", e);
|
||||
log.error("Failed to build query wrapper for class: {}", clazz.getName(), e);
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
private static String getAttributeName(MpQuery q, Field field) {
|
||||
String attributeName = StrUtil.isBlank(q.propName()) ? field.getName() : q.propName();
|
||||
return StrUtil.toUnderlineCase(attributeName);
|
||||
}
|
||||
|
||||
private static <R> void handleWrapper(MpQuery q, QueryWrapper<R> queryWrapper, String attributeName, Object fieldVal) {
|
||||
switch (q.type()) {
|
||||
case EQUAL:
|
||||
@@ -87,10 +89,10 @@ public class MybatisHelper {
|
||||
queryWrapper.likeRight(attributeName, fieldVal);
|
||||
break;
|
||||
case IN:
|
||||
handleInQuery(queryWrapper, attributeName, fieldVal);
|
||||
handleInOrNotQuery(true, queryWrapper, attributeName, fieldVal);
|
||||
break;
|
||||
case NOT_IN:
|
||||
handleNotInQuery(queryWrapper, attributeName, fieldVal);
|
||||
handleInOrNotQuery(false, queryWrapper, attributeName, fieldVal);
|
||||
break;
|
||||
case NOT_EQUAL:
|
||||
queryWrapper.ne(attributeName, fieldVal);
|
||||
@@ -109,61 +111,42 @@ public class MybatisHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private static <R> void handleBetweenQuery(QueryWrapper<R> queryWrapper, Object fieldVal, String finalAttributeName) {
|
||||
if (fieldVal instanceof List) {
|
||||
List<Object> between = new ArrayList<>((List<?>) fieldVal);
|
||||
if (CollectionUtil.isNotEmpty(between)) {
|
||||
int minSize = 2;
|
||||
if (between.size() >= minSize) {
|
||||
queryWrapper.between(finalAttributeName, between.get(0), between.get(1));
|
||||
} else {
|
||||
throw new BadRequestException("BETWEEN类型的对象列表长度必须 >= " + minSize);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new BadRequestException("BETWEEN类型的对象必须是一个List子集合");
|
||||
}
|
||||
}
|
||||
|
||||
private static <R> void handleNotInQuery(QueryWrapper<R> queryWrapper, String finalAttributeName, Object fieldVal) {
|
||||
private static <R> void handleInOrNotQuery(boolean b, QueryWrapper<R> queryWrapper, String attributeName, Object fieldVal) {
|
||||
Collection<?> wrapNotInVal = (Collection<?>) fieldVal;
|
||||
if (CollectionUtil.isNotEmpty(wrapNotInVal)) {
|
||||
Optional<?> anyValOptional = wrapNotInVal.stream().findAny();
|
||||
if (anyValOptional.isPresent()) {
|
||||
Object o = anyValOptional.get();
|
||||
if (o instanceof Long) {
|
||||
queryWrapper.notIn(finalAttributeName, fieldVal);
|
||||
if (b) {
|
||||
queryWrapper.in(attributeName, fieldVal);
|
||||
} else {
|
||||
queryWrapper.notIn(attributeName, fieldVal);
|
||||
}
|
||||
} else if (o instanceof Integer) {
|
||||
queryWrapper.notIn(finalAttributeName, fieldVal);
|
||||
if (b) {
|
||||
queryWrapper.in(attributeName, fieldVal);
|
||||
} else {
|
||||
queryWrapper.notIn(attributeName, fieldVal);
|
||||
}
|
||||
} else {
|
||||
throw new BadRequestException("NOT_IN类型的对象属性值必须是Long/Integer类型集合");
|
||||
throw new BadRequestException("InOrNotIn查询参数类型的对象属性值必须是Long/Integer类型集合");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* IN查询
|
||||
*
|
||||
* @param queryWrapper /
|
||||
* @param fieldVal /
|
||||
* @param finalAttributeName /
|
||||
* @param <R> /
|
||||
*/
|
||||
private static <R> void handleInQuery(QueryWrapper<R> queryWrapper, String finalAttributeName, Object fieldVal) {
|
||||
Collection<?> wrapInVal = (Collection<?>) fieldVal;
|
||||
if (CollectionUtil.isNotEmpty(wrapInVal)) {
|
||||
Optional<?> anyValOptional = wrapInVal.stream().findAny();
|
||||
if (anyValOptional.isPresent()) {
|
||||
Object o = anyValOptional.get();
|
||||
if (o instanceof Long) {
|
||||
queryWrapper.in(finalAttributeName, fieldVal);
|
||||
} else if (o instanceof Integer) {
|
||||
queryWrapper.in(finalAttributeName, fieldVal);
|
||||
} else {
|
||||
throw new BadRequestException("IN类型的对象属性值必须是Long/Integer类型集合");
|
||||
}
|
||||
private static <R> void handleBetweenQuery(QueryWrapper<R> queryWrapper, Object fieldVal, String finalAttributeName) {
|
||||
if (fieldVal instanceof List) {
|
||||
List<Object> between = new ArrayList<>((List<?>) fieldVal);
|
||||
int minLength = 2;
|
||||
if (CollectionUtil.isNotEmpty(between) && between.size() >= minLength) {
|
||||
queryWrapper.between(finalAttributeName, between.get(0), between.get(1));
|
||||
} else {
|
||||
throw new BadRequestException("BETWEEN类型的对象列表长度必须 >= 2");
|
||||
}
|
||||
} else {
|
||||
throw new BadRequestException("BETWEEN类型的对象必须是一个List子集合");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +162,7 @@ public class MybatisHelper {
|
||||
List<String> blurryList = Arrays.stream(blurry.split(",")).filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList());
|
||||
queryWrapper.and(wrapper -> {
|
||||
for (String blurryItem : blurryList) {
|
||||
String column = humpToUnderline(blurryItem);
|
||||
String column = StrUtil.toUnderlineCase(blurryItem);
|
||||
wrapper.or();
|
||||
wrapper.like(column, fieldVal.toString());
|
||||
}
|
||||
@@ -194,16 +177,6 @@ public class MybatisHelper {
|
||||
return fields;
|
||||
}
|
||||
|
||||
/***
|
||||
* 驼峰命名转为下划线命名
|
||||
*
|
||||
* @param para
|
||||
* 驼峰命名的字符串
|
||||
*/
|
||||
private static String humpToUnderline(String para) {
|
||||
return StrUtil.toUnderlineCase(para);
|
||||
}
|
||||
|
||||
@TableName("test_domain")
|
||||
private static class TestDomain {
|
||||
@NotNull(groups = MyEntity.Update.class)
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package cn.odboy.properties;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
public class RsaProperties {
|
||||
|
||||
public static String privateKey;
|
||||
|
||||
@Value("${rsa.private_key}")
|
||||
public void setPrivateKey(String privateKey) {
|
||||
RsaProperties.privateKey = privateKey;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.odboy.server;
|
||||
|
||||
import cn.odboy.properties.FileProperties;
|
||||
import cn.odboy.config.AppProperties;
|
||||
import cn.odboy.config.model.FileUploadSettingModel;
|
||||
import com.alibaba.fastjson2.JSONWriter;
|
||||
import com.alibaba.fastjson2.support.config.FastJsonConfig;
|
||||
import com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter;
|
||||
@@ -26,9 +27,9 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
|
||||
/**
|
||||
* 文件配置
|
||||
*/
|
||||
private final FileProperties properties;
|
||||
private final AppProperties properties;
|
||||
|
||||
public ConfigurerAdapter(FileProperties properties) {
|
||||
public ConfigurerAdapter(AppProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@@ -46,7 +47,7 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
FileProperties.ElPath path = properties.getPath();
|
||||
FileUploadSettingModel.ElPath path = properties.getFile().getPath();
|
||||
String avatarUtl = "file:" + path.getAvatar().replace("\\", "/");
|
||||
String pathUtl = "file:" + path.getPath().replace("\\", "/");
|
||||
registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0);
|
||||
|
||||
@@ -42,7 +42,7 @@ public class SwaggerConfig {
|
||||
@Value("${server.servlet.context-path:}")
|
||||
private String apiPath;
|
||||
|
||||
@Value("${swagger.enabled}")
|
||||
@Value("${app.swagger.enabled}")
|
||||
private Boolean enabled;
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package cn.odboy.thread;
|
||||
|
||||
import cn.odboy.config.AppProperties;
|
||||
import cn.odboy.config.model.QuartzTaskThreadPoolSettingModel;
|
||||
import com.alibaba.ttl.TtlRunnable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -21,7 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@Configuration
|
||||
public class AsyncExecutor implements AsyncConfigurer {
|
||||
@Autowired
|
||||
private AsyncTaskProperties properties;
|
||||
private AppProperties properties;
|
||||
|
||||
/**
|
||||
* 自定义线程池,用法 @Async
|
||||
@@ -30,11 +32,12 @@ public class AsyncExecutor implements AsyncConfigurer {
|
||||
*/
|
||||
@Override
|
||||
public Executor getAsyncExecutor() {
|
||||
QuartzTaskThreadPoolSettingModel asyncTaskPool = properties.getAsyncTaskPool();
|
||||
// 自定义工厂
|
||||
ThreadFactory factory = r -> new Thread(r, "default-async-" + new AtomicInteger(1).getAndIncrement());
|
||||
// 自定义线程池
|
||||
return new ThreadPoolExecutor(properties.getCorePoolSize(), properties.getMaxPoolSize(), properties.getKeepAliveSeconds(),
|
||||
TimeUnit.SECONDS, new ArrayBlockingQueue<>(properties.getQueueCapacity()), factory,
|
||||
return new ThreadPoolExecutor(asyncTaskPool.getCorePoolSize(), asyncTaskPool.getMaxPoolSize(), asyncTaskPool.getKeepAliveSeconds(),
|
||||
TimeUnit.SECONDS, new ArrayBlockingQueue<>(asyncTaskPool.getQueueCapacity()), factory,
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
}
|
||||
|
||||
@@ -43,13 +46,14 @@ public class AsyncExecutor implements AsyncConfigurer {
|
||||
*/
|
||||
@Bean("taskAsync")
|
||||
public ThreadPoolTaskExecutor taskAsync() {
|
||||
QuartzTaskThreadPoolSettingModel asyncTaskPool = properties.getAsyncTaskPool();
|
||||
// 用法 private ThreadPoolTaskExecutor taskExecutor
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(properties.getCorePoolSize());
|
||||
executor.setMaxPoolSize(properties.getMaxPoolSize());
|
||||
executor.setQueueCapacity(properties.getQueueCapacity());
|
||||
executor.setCorePoolSize(asyncTaskPool.getCorePoolSize());
|
||||
executor.setMaxPoolSize(asyncTaskPool.getMaxPoolSize());
|
||||
executor.setQueueCapacity(asyncTaskPool.getQueueCapacity());
|
||||
executor.setThreadNamePrefix("task-async-");
|
||||
executor.setKeepAliveSeconds(properties.getKeepAliveSeconds());
|
||||
executor.setKeepAliveSeconds(asyncTaskPool.getKeepAliveSeconds());
|
||||
// DiscardOldestPolicy,抛弃最早的任务,将新任务加入队列。
|
||||
// AbortPolicy,拒绝执行新任务,并抛出异常。
|
||||
// CallerRunsPolicy,交由调用者线程执行新任务,如果调用者线程已关闭,则抛弃任务。
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package cn.odboy.thread;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "task.pool")
|
||||
public class AsyncTaskProperties {
|
||||
private int corePoolSize;
|
||||
private int maxPoolSize;
|
||||
private int keepAliveSeconds;
|
||||
private int queueCapacity;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.odboy.websocket.constant;
|
||||
|
||||
|
||||
public enum WebSocketMsgTypeEnum {
|
||||
public enum WebSocketMessageBizTypeEnum {
|
||||
/**
|
||||
* 连接
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.odboy.websocket.context;
|
||||
|
||||
import cn.odboy.websocket.dto.WebSocketMsgDto;
|
||||
import cn.odboy.websocket.dto.WebSocketMessageDto;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -88,8 +88,8 @@ public class WebSocketServer {
|
||||
/**
|
||||
* 群发自定义消息
|
||||
*/
|
||||
public static void sendMessage(WebSocketMsgDto webSocketMsgDto, @PathParam("sid") String sid) throws IOException {
|
||||
String message = JSON.toJSONString(webSocketMsgDto);
|
||||
public static void sendMessage(WebSocketMessageDto webSocketMessageDto, @PathParam("sid") String sid) throws IOException {
|
||||
String message = JSON.toJSONString(webSocketMessageDto);
|
||||
log.info("推送消息到{},推送内容:{}", sid, message);
|
||||
try {
|
||||
if (sid == null) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.odboy.websocket.dto;
|
||||
|
||||
import cn.odboy.websocket.constant.WebSocketMessageBizTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class WebSocketMessageDto {
|
||||
private String message;
|
||||
private WebSocketMessageBizTypeEnum bizType;
|
||||
|
||||
public WebSocketMessageDto(String message, WebSocketMessageBizTypeEnum bizType) {
|
||||
this.message = message;
|
||||
this.bizType = bizType;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package cn.odboy.websocket.dto;
|
||||
|
||||
import cn.odboy.websocket.constant.WebSocketMsgTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class WebSocketMsgDto {
|
||||
private String msg;
|
||||
private WebSocketMsgTypeEnum msgType;
|
||||
|
||||
public WebSocketMsgDto(String msg, WebSocketMsgTypeEnum msgType) {
|
||||
this.msg = msg;
|
||||
this.msgType = msgType;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.odboy;
|
||||
package cn.odboy.monitor;
|
||||
|
||||
import cn.odboy.application.system.service.DictService;
|
||||
import cn.odboy.monitor.service.HealthCheckPointService;
|
||||
@@ -7,7 +7,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class HealthCheckPointer implements HealthCheckPointService {
|
||||
public class HealthCheckPointerImpl implements HealthCheckPointService {
|
||||
@Autowired
|
||||
private DictService dictService;
|
||||
|
||||
@@ -157,59 +157,59 @@ mybatis-plus:
|
||||
# 是否控制台 print mybatis-plus 的 LOGO
|
||||
banner: true
|
||||
|
||||
# 登录
|
||||
login:
|
||||
# 是否限制单用户登录
|
||||
single-login: false
|
||||
# 验证码
|
||||
code:
|
||||
# 验证码类型配置 查看 LoginProperties 类
|
||||
code-type: arithmetic
|
||||
# 登录图形验证码有效时间/分钟
|
||||
expiration: 2
|
||||
# 验证码高度
|
||||
width: 111
|
||||
# 验证码宽度
|
||||
height: 36
|
||||
# 内容长度
|
||||
length: 2
|
||||
# 字体名称,为空则使用默认字体
|
||||
font-name:
|
||||
# 字体大小
|
||||
font-size: 25
|
||||
|
||||
# 鉴权
|
||||
jwt:
|
||||
# 必须使用最少88位的Base64对该令牌进行编码
|
||||
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
|
||||
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
||||
token-validity-in-seconds: 14400000
|
||||
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||
detect: 1800000
|
||||
# 续期时间范围,默认1小时,单位毫秒
|
||||
renew: 3600000
|
||||
|
||||
# 是否开启 swagger-ui
|
||||
swagger:
|
||||
enabled: true
|
||||
|
||||
# 文件存储路径
|
||||
file:
|
||||
mac:
|
||||
path: ~/file/
|
||||
avatar: ~/avatar/
|
||||
linux:
|
||||
path: /home/${spring.application.name}/file/
|
||||
avatar: /home/${spring.application.name}/avatar/
|
||||
windows:
|
||||
path: C:\${spring.application.name}\file\
|
||||
avatar: C:\${spring.application.name}\avatar\
|
||||
# 文件大小M
|
||||
maxSize: 100
|
||||
avatarMaxSize: 5
|
||||
|
||||
task:
|
||||
pool:
|
||||
app:
|
||||
# 文件存储路径
|
||||
file:
|
||||
mac:
|
||||
path: ~/file/
|
||||
avatar: ~/avatar/
|
||||
linux:
|
||||
path: /home/${spring.application.name}/file/
|
||||
avatar: /home/${spring.application.name}/avatar/
|
||||
windows:
|
||||
path: C:\${spring.application.name}\file\
|
||||
avatar: C:\${spring.application.name}\avatar\
|
||||
# 文件大小M
|
||||
fileMaxSize: 100
|
||||
avatarMaxSize: 5
|
||||
# 密码加密传输,前端公钥加密,后端私钥解密
|
||||
rsa:
|
||||
private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
|
||||
# 鉴权
|
||||
jwt:
|
||||
# 必须使用最少88位的Base64对该令牌进行编码
|
||||
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
|
||||
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
||||
token-validity-in-seconds: 14400000
|
||||
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||
detect: 1800000
|
||||
# 续期时间范围,默认1小时,单位毫秒
|
||||
renew: 3600000
|
||||
# 登录
|
||||
login:
|
||||
# 是否限制单用户登录
|
||||
single: false
|
||||
# 验证码
|
||||
captchaSetting:
|
||||
# 验证码类型配置 查看 LoginProperties 类
|
||||
code-type: arithmetic
|
||||
# 登录图形验证码有效时间/分钟
|
||||
expiration: 2
|
||||
# 验证码高度
|
||||
width: 111
|
||||
# 验证码宽度
|
||||
height: 36
|
||||
# 内容长度
|
||||
length: 2
|
||||
# 字体名称,为空则使用默认字体
|
||||
font-name:
|
||||
# 字体大小
|
||||
font-size: 25
|
||||
# 是否开启 swagger-ui
|
||||
swagger:
|
||||
enabled: true
|
||||
# 针对@Async
|
||||
async-task-pool:
|
||||
# 核心线程池大小
|
||||
core-pool-size: 10
|
||||
# 最大线程数
|
||||
@@ -218,16 +218,13 @@ task:
|
||||
keep-alive-seconds: 60
|
||||
# 队列容量
|
||||
queue-capacity: 50
|
||||
|
||||
# 七牛云
|
||||
qiniu:
|
||||
# 文件大小 /M
|
||||
max-size: 15
|
||||
|
||||
# 邮箱验证码有效时间/秒
|
||||
code:
|
||||
expiration: 300
|
||||
|
||||
# 密码加密传输,前端公钥加密,后端私钥解密
|
||||
rsa:
|
||||
private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
|
||||
# oss
|
||||
oss:
|
||||
# 七牛云
|
||||
qiniu:
|
||||
# 文件大小 /M
|
||||
max-size: 15
|
||||
email:
|
||||
captchaSetting:
|
||||
# 邮箱验证码有效时间/秒
|
||||
expiration: 300
|
||||
|
||||
@@ -3,6 +3,21 @@ server:
|
||||
http2:
|
||||
# 启用 HTTP/2 支持,提升传输效率
|
||||
enabled: true
|
||||
undertow:
|
||||
threads:
|
||||
# 工作线程数,默认设置为io-threads * 8。如果你的应用程序有很多同步阻塞操作,可以适当增加这个值
|
||||
worker: 4
|
||||
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
|
||||
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
|
||||
io: 2
|
||||
# 设置为true以使用直接内存(堆外内存)来存储缓冲区。这可以减少垃圾回收的开销。
|
||||
direct-buffers: true
|
||||
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
|
||||
# 每块buffer的空间大小,越小的空间被利用越充分
|
||||
buffer-size: 1024
|
||||
accesslog:
|
||||
# 关闭日志
|
||||
enabled: false
|
||||
compression:
|
||||
# 启用 GZIP 压缩,减少传输数据量
|
||||
enabled: true
|
||||
@@ -38,16 +53,16 @@ spring:
|
||||
datasource:
|
||||
druid:
|
||||
db-type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/cutejava20250321?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
|
||||
driverClassName: com.p6spy.engine.spy.P6SpyDriver
|
||||
url: jdbc:p6spy:mysql://127.0.0.1:3306/cutejava20250321?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
|
||||
username: root
|
||||
password: 123456
|
||||
# 初始连接数,建议设置为与最小空闲连接数相同
|
||||
initial-size: 20
|
||||
initial-size: 2
|
||||
# 最小空闲连接数,保持足够的空闲连接以应对请求
|
||||
min-idle: 20
|
||||
min-idle: 2
|
||||
# 最大连接数,根据并发需求适当增加
|
||||
max-active: 50
|
||||
max-active: 8
|
||||
# 获取连接超时时间(毫秒),调整以满足响应时间要求
|
||||
max-wait: 3000
|
||||
# 启用KeepAlive机制,保持长连接
|
||||
@@ -110,7 +125,6 @@ spring:
|
||||
max-idle: 20
|
||||
# 连接池中的最小空闲连接数
|
||||
min-idle: 1
|
||||
|
||||
# 持久层
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
@@ -143,59 +157,59 @@ mybatis-plus:
|
||||
# 是否控制台 print mybatis-plus 的 LOGO
|
||||
banner: true
|
||||
|
||||
# 登录
|
||||
login:
|
||||
# 是否限制单用户登录
|
||||
single-login: true
|
||||
# 验证码
|
||||
code:
|
||||
# 验证码类型配置 查看 LoginProperties 类
|
||||
code-type: arithmetic
|
||||
# 登录图形验证码有效时间/分钟
|
||||
expiration: 2
|
||||
# 验证码高度
|
||||
width: 111
|
||||
# 验证码宽度
|
||||
height: 36
|
||||
# 内容长度
|
||||
length: 2
|
||||
# 字体名称,为空则使用默认字体
|
||||
font-name:
|
||||
# 字体大小
|
||||
font-size: 25
|
||||
|
||||
# 鉴权
|
||||
jwt:
|
||||
# 必须使用最少88位的Base64对该令牌进行编码
|
||||
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
|
||||
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
||||
token-validity-in-seconds: 14400000
|
||||
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||
detect: 1800000
|
||||
# 续期时间范围,默认1小时,单位毫秒
|
||||
renew: 3600000
|
||||
|
||||
# 是否开启 swagger-ui
|
||||
swagger:
|
||||
enabled: true
|
||||
|
||||
# 文件存储路径
|
||||
file:
|
||||
mac:
|
||||
path: ~/file/
|
||||
avatar: ~/avatar/
|
||||
linux:
|
||||
path: /home/${spring.application.name}/file/
|
||||
avatar: /home/${spring.application.name}/avatar/
|
||||
windows:
|
||||
path: C:\${spring.application.name}\file\
|
||||
avatar: C:\${spring.application.name}\avatar\
|
||||
# 文件大小M
|
||||
maxSize: 100
|
||||
avatarMaxSize: 5
|
||||
|
||||
task:
|
||||
pool:
|
||||
app:
|
||||
# 文件存储路径
|
||||
file:
|
||||
mac:
|
||||
path: ~/file/
|
||||
avatar: ~/avatar/
|
||||
linux:
|
||||
path: /home/${spring.application.name}/file/
|
||||
avatar: /home/${spring.application.name}/avatar/
|
||||
windows:
|
||||
path: C:\${spring.application.name}\file\
|
||||
avatar: C:\${spring.application.name}\avatar\
|
||||
# 文件大小M
|
||||
fileMaxSize: 100
|
||||
avatarMaxSize: 5
|
||||
# 密码加密传输,前端公钥加密,后端私钥解密
|
||||
rsa:
|
||||
private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
|
||||
# 鉴权
|
||||
jwt:
|
||||
# 必须使用最少88位的Base64对该令牌进行编码
|
||||
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
|
||||
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
||||
token-validity-in-seconds: 14400000
|
||||
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||
detect: 1800000
|
||||
# 续期时间范围,默认1小时,单位毫秒
|
||||
renew: 3600000
|
||||
# 登录
|
||||
login:
|
||||
# 是否限制单用户登录
|
||||
single: true
|
||||
# 验证码
|
||||
captchaSetting:
|
||||
# 验证码类型配置 查看 LoginProperties 类
|
||||
code-type: arithmetic
|
||||
# 登录图形验证码有效时间/分钟
|
||||
expiration: 2
|
||||
# 验证码高度
|
||||
width: 111
|
||||
# 验证码宽度
|
||||
height: 36
|
||||
# 内容长度
|
||||
length: 2
|
||||
# 字体名称,为空则使用默认字体
|
||||
font-name:
|
||||
# 字体大小
|
||||
font-size: 25
|
||||
# 是否开启 swagger-ui
|
||||
swagger:
|
||||
enabled: false
|
||||
# 针对@Async
|
||||
async-task-pool:
|
||||
# 核心线程池大小
|
||||
core-pool-size: 10
|
||||
# 最大线程数
|
||||
@@ -204,16 +218,13 @@ task:
|
||||
keep-alive-seconds: 60
|
||||
# 队列容量
|
||||
queue-capacity: 50
|
||||
|
||||
# 七牛云
|
||||
qiniu:
|
||||
# 文件大小 /M
|
||||
max-size: 15
|
||||
|
||||
# 邮箱验证码有效时间/秒
|
||||
code:
|
||||
expiration: 300
|
||||
|
||||
# 密码加密传输,前端公钥加密,后端私钥解密
|
||||
rsa:
|
||||
private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
|
||||
# oss
|
||||
oss:
|
||||
# 七牛云
|
||||
qiniu:
|
||||
# 文件大小 /M
|
||||
max-size: 15
|
||||
email:
|
||||
captchaSetting:
|
||||
# 邮箱验证码有效时间/秒
|
||||
expiration: 300
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package cn.odboy.application.core.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 登录配置
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "login")
|
||||
public class LoginProperties {
|
||||
|
||||
/**
|
||||
* 账号单用户 登录
|
||||
*/
|
||||
private boolean singleLogin = false;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.odboy.application.core.context;
|
||||
|
||||
import cn.odboy.application.core.config.SecurityProperties;
|
||||
import cn.odboy.application.core.service.impl.UserOnlineServiceImpl;
|
||||
import cn.odboy.constant.RequestMethodEnum;
|
||||
import cn.odboy.util.AnonTagUtil;
|
||||
@@ -31,7 +30,6 @@ public class SpringSecurityConfig {
|
||||
private final JwtAuthenticationEntryPoint authenticationErrorHandler;
|
||||
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
|
||||
private final ApplicationContext applicationContext;
|
||||
private final SecurityProperties securityProperties;
|
||||
private final UserOnlineServiceImpl onlineUserService;
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -3,7 +3,7 @@ package cn.odboy.application.core.context;
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.odboy.application.core.config.SecurityProperties;
|
||||
import cn.odboy.config.AppProperties;
|
||||
import cn.odboy.constant.SystemConst;
|
||||
import cn.odboy.constant.SystemRedisKey;
|
||||
import cn.odboy.model.system.model.UserJwtModel;
|
||||
@@ -39,13 +39,13 @@ public class TokenProvider implements InitializingBean {
|
||||
private JwtParser jwtParser;
|
||||
private JwtBuilder jwtBuilder;
|
||||
private final RedisHelper redisHelper;
|
||||
private final SecurityProperties properties;
|
||||
private final AppProperties properties;
|
||||
public static final String AUTHORITIES_UUID_KEY = "uid";
|
||||
public static final String AUTHORITIES_UID_KEY = "userId";
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret());
|
||||
byte[] keyBytes = Decoders.BASE64.decode(properties.getJwt().getBase64Secret());
|
||||
Key key = Keys.hmacShaKeyFor(keyBytes);
|
||||
jwtParser = Jwts.parserBuilder()
|
||||
.setSigningKey(key)
|
||||
@@ -103,8 +103,8 @@ public class TokenProvider implements InitializingBean {
|
||||
// 判断当前时间与过期时间的时间差
|
||||
long differ = expireDate.getTime() - System.currentTimeMillis();
|
||||
// 如果在续期检查的范围内,则续期
|
||||
if (differ <= properties.getDetect()) {
|
||||
long renew = time + properties.getRenew();
|
||||
if (differ <= properties.getJwt().getDetect()) {
|
||||
long renew = time + properties.getJwt().getRenew();
|
||||
redisHelper.expire(loginKey, renew, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,23 +3,18 @@ package cn.odboy.application.core.rest;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.odboy.annotation.AnonymousPostMapping;
|
||||
import cn.odboy.application.core.config.CaptchaProperties;
|
||||
import cn.odboy.application.core.config.LoginProperties;
|
||||
import cn.odboy.application.core.constant.LoginCodeEnum;
|
||||
import cn.odboy.constant.LoginCodeEnum;
|
||||
import cn.odboy.application.core.context.TokenProvider;
|
||||
import cn.odboy.application.core.service.UserOnlineService;
|
||||
import cn.odboy.application.core.service.impl.UserDetailsServiceImpl;
|
||||
import cn.odboy.application.core.service.impl.UserOnlineServiceImpl;
|
||||
import cn.odboy.base.PageResult;
|
||||
import cn.odboy.constant.SystemConst;
|
||||
import cn.odboy.constant.SystemRedisKey;
|
||||
import cn.odboy.config.AppProperties;
|
||||
import cn.odboy.context.SecurityHelper;
|
||||
import cn.odboy.exception.BadRequestException;
|
||||
import cn.odboy.model.system.model.UserJwtModel;
|
||||
import cn.odboy.model.system.model.UserOnlineModel;
|
||||
import cn.odboy.model.system.request.UserLoginRequest;
|
||||
import cn.odboy.model.system.response.UserInfoResponse;
|
||||
import cn.odboy.properties.RsaProperties;
|
||||
import cn.odboy.redis.RedisHelper;
|
||||
import cn.odboy.util.RsaEncryptUtil;
|
||||
import cn.odboy.util.StringUtil;
|
||||
@@ -28,10 +23,8 @@ import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@@ -58,8 +51,7 @@ public class AuthController {
|
||||
private final RedisHelper redisHelper;
|
||||
private final UserOnlineServiceImpl onlineUserService;
|
||||
private final TokenProvider tokenProvider;
|
||||
private final CaptchaProperties captchaProperties;
|
||||
private final LoginProperties loginProperties;
|
||||
private final AppProperties properties;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final UserDetailsServiceImpl userDetailsService;
|
||||
|
||||
@@ -67,7 +59,7 @@ public class AuthController {
|
||||
@AnonymousPostMapping(value = "/login")
|
||||
public ResponseEntity<Object> login(@Validated @RequestBody UserLoginRequest loginRequest, HttpServletRequest request) throws Exception {
|
||||
// 密码解密
|
||||
String password = RsaEncryptUtil.decryptByPrivateKey(RsaProperties.privateKey, loginRequest.getPassword());
|
||||
String password = RsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), loginRequest.getPassword());
|
||||
// 查询验证码
|
||||
String code = redisHelper.get(loginRequest.getUuid(), String.class);
|
||||
// 清除验证码
|
||||
@@ -93,7 +85,7 @@ public class AuthController {
|
||||
put("token", String.format("%s %s", SystemConst.TOKEN_PREFIX, token));
|
||||
put("user", BeanUtil.copyProperties(jwtUser, UserInfoResponse.class));
|
||||
}};
|
||||
if (loginProperties.isSingleLogin()) {
|
||||
if (properties.getLogin().isSingle()) {
|
||||
// 踢掉之前已经登录的token
|
||||
onlineUserService.kickOutByUsername(loginRequest.getUsername());
|
||||
}
|
||||
@@ -115,7 +107,7 @@ public class AuthController {
|
||||
@AnonymousPostMapping(value = "/code")
|
||||
public ResponseEntity<Object> getCode() {
|
||||
// 获取运算的结果
|
||||
Captcha captcha = captchaProperties.getCaptcha();
|
||||
Captcha captcha = properties.getLogin().getCaptchaSetting().getCaptcha();
|
||||
String uuid = SystemRedisKey.CAPTCHA_LOGIN + IdUtil.simpleUUID();
|
||||
//当验证码类型为 arithmetic时且长度 >= 2 时,captcha.text()的结果有几率为浮点型
|
||||
String captchaValue = captcha.text();
|
||||
@@ -123,7 +115,7 @@ public class AuthController {
|
||||
captchaValue = captchaValue.split("\\.")[0];
|
||||
}
|
||||
// 保存
|
||||
redisHelper.set(uuid, captchaValue, captchaProperties.getExpiration(), TimeUnit.MINUTES);
|
||||
redisHelper.set(uuid, captchaValue, properties.getLogin().getCaptchaSetting().getExpiration(), TimeUnit.MINUTES);
|
||||
// 验证码信息
|
||||
Map<String, Object> imgResult = new HashMap<String, Object>(2) {{
|
||||
put("img", captcha.toBase64());
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package cn.odboy.application.core.service.impl;
|
||||
|
||||
import cn.odboy.application.core.config.SecurityProperties;
|
||||
import cn.odboy.application.core.context.TokenProvider;
|
||||
import cn.odboy.application.core.service.UserOnlineService;
|
||||
import cn.odboy.base.PageResult;
|
||||
import cn.odboy.config.AppProperties;
|
||||
import cn.odboy.constant.SystemRedisKey;
|
||||
import cn.odboy.model.system.model.UserJwtModel;
|
||||
import cn.odboy.model.system.model.UserOnlineModel;
|
||||
@@ -34,7 +34,7 @@ import java.util.concurrent.TimeUnit;
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class UserOnlineServiceImpl implements UserOnlineService {
|
||||
private final SecurityProperties properties;
|
||||
private final AppProperties properties;
|
||||
private final TokenProvider tokenProvider;
|
||||
private final RedisHelper redisHelper;
|
||||
|
||||
@@ -61,7 +61,7 @@ public class UserOnlineServiceImpl implements UserOnlineService {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
String loginKey = tokenProvider.loginKey(token);
|
||||
redisHelper.set(loginKey, userOnlineModel, properties.getTokenValidityInSeconds(), TimeUnit.MILLISECONDS);
|
||||
redisHelper.set(loginKey, userOnlineModel, properties.getJwt().getTokenValidityInSeconds(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,8 +2,7 @@ package cn.odboy.application.system.rest;
|
||||
|
||||
import cn.odboy.application.tools.service.CaptchaService;
|
||||
import cn.odboy.application.tools.service.EmailService;
|
||||
import cn.odboy.constant.CodeBiEnum;
|
||||
import cn.odboy.constant.CodeEnum;
|
||||
import cn.odboy.constant.CaptchaBizEnum;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -31,27 +30,27 @@ public class CaptchaController {
|
||||
@ApiOperation("重置邮箱,发送验证码")
|
||||
@PostMapping(value = "/sendResetEmailCaptcha")
|
||||
public ResponseEntity<Object> sendResetEmailCaptcha(@RequestParam String email) {
|
||||
emailService.sendEmail(captchaService.renderCodeTemplate(email, CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey()));
|
||||
emailService.sendEmail(captchaService.renderCodeTemplate(email, CaptchaBizEnum.EMAIL_RESET_EMAIL_CODE.getRedisKey()));
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ApiOperation("重置密码,发送验证码")
|
||||
@PostMapping(value = "/sendResetPasswordCaptcha")
|
||||
public ResponseEntity<Object> sendResetPasswordCaptcha(@RequestParam String email) {
|
||||
emailService.sendEmail(captchaService.renderCodeTemplate(email, CodeEnum.EMAIL_RESET_PWD_CODE.getKey()));
|
||||
emailService.sendEmail(captchaService.renderCodeTemplate(email, CaptchaBizEnum.EMAIL_RESET_PWD_CODE.getRedisKey()));
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ApiOperation("验证码验证")
|
||||
@PostMapping(value = "/checkCodeAvailable")
|
||||
public ResponseEntity<Object> checkCodeAvailable(@RequestParam String email, @RequestParam String code, @RequestParam Integer codeBi) {
|
||||
CodeBiEnum biEnum = CodeBiEnum.find(codeBi);
|
||||
public ResponseEntity<Object> checkCodeAvailable(@RequestParam String email, @RequestParam String code, @RequestParam String codeBi) {
|
||||
CaptchaBizEnum biEnum = CaptchaBizEnum.getByBizCode(codeBi);
|
||||
switch (Objects.requireNonNull(biEnum)) {
|
||||
case ONE:
|
||||
captchaService.checkCodeAvailable(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey(), email, code);
|
||||
case EMAIL_RESET_EMAIL_CODE:
|
||||
captchaService.checkCodeAvailable(CaptchaBizEnum.EMAIL_RESET_EMAIL_CODE.getBizCode(), email, code);
|
||||
break;
|
||||
case TWO:
|
||||
captchaService.checkCodeAvailable(CodeEnum.EMAIL_RESET_PWD_CODE.getKey(), email, code);
|
||||
case EMAIL_RESET_PWD_CODE:
|
||||
captchaService.checkCodeAvailable(CaptchaBizEnum.EMAIL_RESET_PWD_CODE.getBizCode(), email, code);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -8,7 +8,8 @@ import cn.odboy.application.system.service.UserService;
|
||||
import cn.odboy.application.tools.service.CaptchaService;
|
||||
import cn.odboy.base.MyMetaOption;
|
||||
import cn.odboy.base.PageResult;
|
||||
import cn.odboy.constant.CodeEnum;
|
||||
import cn.odboy.config.AppProperties;
|
||||
import cn.odboy.constant.CaptchaBizEnum;
|
||||
import cn.odboy.context.SecurityHelper;
|
||||
import cn.odboy.exception.BadRequestException;
|
||||
import cn.odboy.model.system.domain.Dept;
|
||||
@@ -16,7 +17,6 @@ import cn.odboy.model.system.domain.Role;
|
||||
import cn.odboy.model.system.domain.User;
|
||||
import cn.odboy.model.system.request.QueryUserRequest;
|
||||
import cn.odboy.model.system.response.UpdateUserPasswordResponse;
|
||||
import cn.odboy.properties.RsaProperties;
|
||||
import cn.odboy.util.PageUtil;
|
||||
import cn.odboy.util.RsaEncryptUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
@@ -59,6 +59,7 @@ public class UserController {
|
||||
private final DeptService deptService;
|
||||
private final RoleService roleService;
|
||||
private final CaptchaService verificationCodeService;
|
||||
private final AppProperties properties;
|
||||
|
||||
@ApiOperation("导出用户数据")
|
||||
@GetMapping(value = "/download")
|
||||
@@ -144,8 +145,8 @@ public class UserController {
|
||||
@ApiOperation("修改密码")
|
||||
@PostMapping(value = "/modifyUserPasswordByUsername")
|
||||
public ResponseEntity<Object> modifyUserPasswordByUsername(@RequestBody UpdateUserPasswordResponse passVo) throws Exception {
|
||||
String oldPass = RsaEncryptUtil.decryptByPrivateKey(RsaProperties.privateKey, passVo.getOldPass());
|
||||
String newPass = RsaEncryptUtil.decryptByPrivateKey(RsaProperties.privateKey, passVo.getNewPass());
|
||||
String oldPass = RsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), passVo.getOldPass());
|
||||
String newPass = RsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), passVo.getNewPass());
|
||||
User user = userService.describeUserByUsername(SecurityHelper.getCurrentUsername());
|
||||
if (!passwordEncoder.matches(oldPass, user.getPassword())) {
|
||||
throw new BadRequestException("修改失败,旧密码错误");
|
||||
@@ -174,12 +175,12 @@ public class UserController {
|
||||
@ApiOperation("修改邮箱")
|
||||
@PostMapping(value = "/modifyUserEmailByUsername/{code}")
|
||||
public ResponseEntity<Object> modifyUserEmailByUsername(@PathVariable String code, @RequestBody User resources) throws Exception {
|
||||
String password = RsaEncryptUtil.decryptByPrivateKey(RsaProperties.privateKey, resources.getPassword());
|
||||
String password = RsaEncryptUtil.decryptByPrivateKey(properties.getRsa().getPrivateKey(), resources.getPassword());
|
||||
User user = userService.describeUserByUsername(SecurityHelper.getCurrentUsername());
|
||||
if (!passwordEncoder.matches(password, user.getPassword())) {
|
||||
throw new BadRequestException("密码错误");
|
||||
}
|
||||
verificationCodeService.checkCodeAvailable(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey(), resources.getEmail(), code);
|
||||
verificationCodeService.checkCodeAvailable(CaptchaBizEnum.EMAIL_RESET_EMAIL_CODE.getBizCode(), resources.getEmail(), code);
|
||||
userService.modifyUserEmailByUsername(user.getUsername(), resources.getEmail());
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import cn.odboy.application.system.mapper.UserMapper;
|
||||
import cn.odboy.application.system.mapper.UserRoleMapper;
|
||||
import cn.odboy.application.system.service.UserService;
|
||||
import cn.odboy.base.PageResult;
|
||||
import cn.odboy.config.AppProperties;
|
||||
import cn.odboy.constant.SystemRedisKey;
|
||||
import cn.odboy.context.SecurityHelper;
|
||||
import cn.odboy.exception.BadRequestException;
|
||||
@@ -15,7 +16,6 @@ import cn.odboy.model.system.domain.Job;
|
||||
import cn.odboy.model.system.domain.Role;
|
||||
import cn.odboy.model.system.domain.User;
|
||||
import cn.odboy.model.system.request.QueryUserRequest;
|
||||
import cn.odboy.properties.FileProperties;
|
||||
import cn.odboy.redis.RedisHelper;
|
||||
import cn.odboy.util.FileUtil;
|
||||
import cn.odboy.util.PageUtil;
|
||||
@@ -47,7 +47,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
private final UserMapper userMapper;
|
||||
private final UserJobMapper userJobMapper;
|
||||
private final UserRoleMapper userRoleMapper;
|
||||
private final FileProperties fileProperties;
|
||||
private final AppProperties properties;
|
||||
private final RedisHelper redisHelper;
|
||||
private final UserCacheService userCacheService;
|
||||
private final UserOnlineService userOnlineService;
|
||||
@@ -211,7 +211,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, String> modifyUserAvatar(MultipartFile multipartFile) {
|
||||
// 文件大小验证
|
||||
FileUtil.checkSize(fileProperties.getAvatarMaxSize(), multipartFile.getSize());
|
||||
FileUtil.checkSize(properties.getFile().getAvatarMaxSize(), multipartFile.getSize());
|
||||
// 验证文件上传的格式
|
||||
String image = "gif jpg png jpeg";
|
||||
String fileType = FileUtil.getSuffix(multipartFile.getOriginalFilename());
|
||||
@@ -220,7 +220,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
}
|
||||
User user = userMapper.getUserByUsername(SecurityHelper.getCurrentUsername());
|
||||
String oldPath = user.getAvatarPath();
|
||||
File file = FileUtil.upload(multipartFile, fileProperties.getPath().getAvatar());
|
||||
File file = FileUtil.upload(multipartFile, properties.getFile().getPath().getAvatar());
|
||||
user.setAvatarPath(Objects.requireNonNull(file).getPath());
|
||||
user.setAvatarName(file.getName());
|
||||
saveOrUpdate(user);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.odboy.application.tools.rest;
|
||||
|
||||
import cn.odboy.application.tools.service.QiNiuConfigService;
|
||||
import cn.odboy.application.tools.service.QiniuConfigService;
|
||||
import cn.odboy.application.tools.service.QiniuContentService;
|
||||
import cn.odboy.base.PageResult;
|
||||
import cn.odboy.model.tools.domain.QiniuConfig;
|
||||
@@ -38,7 +38,7 @@ import java.util.Map;
|
||||
@Api(tags = "工具:七牛云存储管理")
|
||||
public class QiniuController {
|
||||
private final QiniuContentService qiniuContentService;
|
||||
private final QiNiuConfigService qiNiuConfigService;
|
||||
private final QiniuConfigService qiNiuConfigService;
|
||||
|
||||
@ApiOperation("查询七牛云存储配置")
|
||||
@PostMapping(value = "/describeQiniuConfig")
|
||||
|
||||
@@ -4,7 +4,7 @@ import cn.odboy.model.tools.domain.QiniuConfig;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
|
||||
public interface QiNiuConfigService extends IService<QiniuConfig> {
|
||||
public interface QiniuConfigService extends IService<QiniuConfig> {
|
||||
|
||||
/**
|
||||
* 查询配置
|
||||
@@ -20,7 +20,7 @@ import java.util.Collections;
|
||||
@RequiredArgsConstructor
|
||||
public class CaptchaServiceImpl implements CaptchaService {
|
||||
private final RedisHelper redisHelper;
|
||||
@Value("${code.expiration}")
|
||||
@Value("${app.email.captchaSetting.expiration}")
|
||||
private Long expiration;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,10 +4,10 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.odboy.application.tools.mapper.LocalStorageMapper;
|
||||
import cn.odboy.application.tools.service.LocalStorageService;
|
||||
import cn.odboy.base.PageResult;
|
||||
import cn.odboy.config.AppProperties;
|
||||
import cn.odboy.exception.BadRequestException;
|
||||
import cn.odboy.model.tools.domain.LocalStorage;
|
||||
import cn.odboy.model.tools.request.QueryLocalStorageRequest;
|
||||
import cn.odboy.properties.FileProperties;
|
||||
import cn.odboy.util.FileUtil;
|
||||
import cn.odboy.util.PageUtil;
|
||||
import cn.odboy.util.StringUtil;
|
||||
@@ -29,9 +29,8 @@ import java.util.Map;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LocalStorageServiceImpl extends ServiceImpl<LocalStorageMapper, LocalStorage> implements LocalStorageService {
|
||||
|
||||
private final LocalStorageMapper localStorageMapper;
|
||||
private final FileProperties properties;
|
||||
private final AppProperties properties;
|
||||
|
||||
@Override
|
||||
public PageResult<LocalStorage> describeLocalStoragePage(QueryLocalStorageRequest criteria, Page<Object> page) {
|
||||
@@ -47,10 +46,10 @@ public class LocalStorageServiceImpl extends ServiceImpl<LocalStorageMapper, Loc
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public LocalStorage uploadFile(String name, MultipartFile multipartFile) {
|
||||
long size = multipartFile.getSize();
|
||||
FileUtil.checkSize(properties.getMaxSize(), size);
|
||||
FileUtil.checkSize(properties.getFile().getFileMaxSize(), size);
|
||||
String suffix = FileUtil.getSuffix(multipartFile.getOriginalFilename());
|
||||
String type = FileUtil.getFileType(suffix);
|
||||
File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + type + File.separator);
|
||||
File file = FileUtil.upload(multipartFile, properties.getFile().getPath() + type + File.separator);
|
||||
if (ObjectUtil.isNull(file)) {
|
||||
throw new BadRequestException("上传失败");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.odboy.application.tools.service.impl;
|
||||
|
||||
import cn.odboy.application.tools.mapper.QiniuConfigMapper;
|
||||
import cn.odboy.application.tools.service.QiNiuConfigService;
|
||||
import cn.odboy.application.tools.service.QiniuConfigService;
|
||||
import cn.odboy.constant.TransferProtocolConst;
|
||||
import cn.odboy.exception.BadRequestException;
|
||||
import cn.odboy.model.tools.domain.QiniuConfig;
|
||||
@@ -17,7 +17,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CacheConfig(cacheNames = "qiNiu")
|
||||
public class QiNiuConfigServiceImpl extends ServiceImpl<QiniuConfigMapper, QiniuConfig> implements QiNiuConfigService {
|
||||
public class QiniuConfigServiceImpl extends ServiceImpl<QiniuConfigMapper, QiniuConfig> implements QiniuConfigService {
|
||||
@Override
|
||||
@Cacheable(key = "'config'")
|
||||
public QiniuConfig describeQiniuConfig() {
|
||||
@@ -1,9 +1,9 @@
|
||||
package cn.odboy.application.tools.service.impl;
|
||||
|
||||
import cn.odboy.application.tools.mapper.QiniuContentMapper;
|
||||
import cn.odboy.application.tools.service.QiNiuConfigService;
|
||||
import cn.odboy.application.tools.service.QiniuConfigService;
|
||||
import cn.odboy.application.tools.service.QiniuContentService;
|
||||
import cn.odboy.application.tools.util.QiNiuUtil;
|
||||
import cn.odboy.application.tools.util.QiniuUtil;
|
||||
import cn.odboy.base.PageResult;
|
||||
import cn.odboy.exception.BadRequestException;
|
||||
import cn.odboy.model.tools.domain.QiniuConfig;
|
||||
@@ -40,9 +40,9 @@ import java.util.Map;
|
||||
@CacheConfig(cacheNames = "qiNiu")
|
||||
public class QiniuContentServiceImpl extends ServiceImpl<QiniuContentMapper, QiniuContent> implements QiniuContentService {
|
||||
private final QiniuContentMapper qiniuContentMapper;
|
||||
private final QiNiuConfigService qiNiuConfigService;
|
||||
private final QiniuConfigService qiNiuConfigService;
|
||||
|
||||
@Value("${qiniu.max-size}")
|
||||
@Value("${app.oss.qiniu.max-size}")
|
||||
private Long maxSize;
|
||||
|
||||
@Override
|
||||
@@ -64,14 +64,14 @@ public class QiniuContentServiceImpl extends ServiceImpl<QiniuContentMapper, Qin
|
||||
throw new BadRequestException("请先添加相应配置,再操作");
|
||||
}
|
||||
// 构造一个带指定Zone对象的配置类
|
||||
Configuration cfg = new Configuration(QiNiuUtil.getRegion(qiniuConfig.getZone()));
|
||||
Configuration cfg = new Configuration(QiniuUtil.getRegion(qiniuConfig.getZone()));
|
||||
UploadManager uploadManager = new UploadManager(cfg);
|
||||
Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
|
||||
String upToken = auth.uploadToken(qiniuConfig.getBucket());
|
||||
try {
|
||||
String key = file.getOriginalFilename();
|
||||
if (qiniuContentMapper.getQiniuContentByName(key) != null) {
|
||||
key = QiNiuUtil.getKey(key);
|
||||
key = QiniuUtil.getKey(key);
|
||||
}
|
||||
Response response = uploadManager.put(file.getBytes(), key, upToken);
|
||||
// 解析上传成功的结果
|
||||
@@ -120,7 +120,7 @@ public class QiniuContentServiceImpl extends ServiceImpl<QiniuContentMapper, Qin
|
||||
throw new BadRequestException("文件不存在");
|
||||
}
|
||||
// 构造一个带指定Zone对象的配置类
|
||||
Configuration cfg = new Configuration(QiNiuUtil.getRegion(qiniuConfig.getZone()));
|
||||
Configuration cfg = new Configuration(QiniuUtil.getRegion(qiniuConfig.getZone()));
|
||||
Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
|
||||
BucketManager bucketManager = new BucketManager(auth, cfg);
|
||||
try {
|
||||
@@ -140,7 +140,7 @@ public class QiniuContentServiceImpl extends ServiceImpl<QiniuContentMapper, Qin
|
||||
throw new BadRequestException("请先添加相应配置,再操作");
|
||||
}
|
||||
//构造一个带指定Zone对象的配置类
|
||||
Configuration cfg = new Configuration(QiNiuUtil.getRegion(qiniuConfig.getZone()));
|
||||
Configuration cfg = new Configuration(QiniuUtil.getRegion(qiniuConfig.getZone()));
|
||||
Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
|
||||
BucketManager bucketManager = new BucketManager(auth, cfg);
|
||||
//文件名前缀
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.Date;
|
||||
/**
|
||||
* 七牛云存储工具类
|
||||
*/
|
||||
public final class QiNiuUtil {
|
||||
public final class QiniuUtil {
|
||||
|
||||
private static final String HUAD = "华东";
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# 可参考: https://hub.docker.com/_/mysql
|
||||
version: '3'
|
||||
services:
|
||||
mysql:
|
||||
image: registry.cn-shanghai.aliyuncs.com/odboy/ops:mysql-8.0 # 原镜像`mysql:8.0`
|
||||
container_name: mysql8 # 容器名为'mysql8'
|
||||
restart: unless-stopped # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
|
||||
volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
|
||||
- "./mysql/my.cnf:/etc/mysql/my.cnf"
|
||||
- "./mysql/data:/var/lib/mysql"
|
||||
- "./mysql/mysql-files:/var/lib/mysql-files"
|
||||
environment: # 设置环境变量,相当于docker run命令中的-e
|
||||
TZ: Asia/Shanghai
|
||||
LANG: en_US.UTF-8
|
||||
MYSQL_ROOT_PASSWORD: root # 设置root用户密码
|
||||
MYSQL_DATABASE: demo # 初始化的数据库名称
|
||||
privileged: true
|
||||
user: root
|
||||
ports: # 映射端口
|
||||
- "3306:3306"
|
||||
@@ -0,0 +1,3 @@
|
||||
port: 13306
|
||||
username: root
|
||||
password: root
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
docker-compose -f docker-compose-mysql.yml -p mysql8 up -d
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
docker-compose -p mysql8 down
|
||||
@@ -0,0 +1,16 @@
|
||||
version: '3'
|
||||
services:
|
||||
redis:
|
||||
image: registry.cn-shanghai.aliyuncs.com/odboy/ops:redis-7.0.5 # 镜像'redis:7.0.5'
|
||||
container_name: redis7 # 容器名为'redis'
|
||||
restart: unless-stopped # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
|
||||
command: redis-server /etc/redis/redis.conf --requirepass 123456 --appendonly no # 启动redis服务并添加密码为:123456,默认不开启redis-aof方式持久化配置
|
||||
# command: redis-server --requirepass 123456 --appendonly yes # 启动redis服务并添加密码为:123456,并开启redis持久化配置
|
||||
environment: # 设置环境变量,相当于docker run命令中的-e
|
||||
TZ: Asia/Shanghai
|
||||
LANG: en_US.UTF-8
|
||||
volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
|
||||
- "./redis/data:/data"
|
||||
- "./redis/config/redis.conf:/etc/redis/redis.conf" # `redis.conf`文件内容`http://download.redis.io/redis-stable/redis.conf`
|
||||
ports: # 映射端口
|
||||
- "6379:6379"
|
||||
@@ -0,0 +1,2 @@
|
||||
port: 16379
|
||||
password: 123456
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
# 当前目录下所有文件赋予权限(读、写、执行)
|
||||
chmod -R 777 ./redis
|
||||
# 运行 -- 单机模式
|
||||
docker-compose -f docker-compose-redis.yml -p redis7 up -d
|
||||
@@ -0,0 +1 @@
|
||||
docker-compose -p redis7 down
|
||||
@@ -11,7 +11,7 @@
|
||||
Target Server Version : 80025
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 28/03/2025 19:11:17
|
||||
Date: 11/04/2025 14:45:16
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@@ -281,14 +281,13 @@ CREATE TABLE `sys_dept` (
|
||||
-- ----------------------------
|
||||
-- Records of sys_dept
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_dept` VALUES (2, 7, 2, '研发部', 3, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_dept` VALUES (2, 7, 1, '研发部', 3, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_dept` VALUES (5, 7, 0, '运维部', 4, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_dept` VALUES (6, 8, 0, '测试部', 6, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_dept` VALUES (7, NULL, 2, '华南分部', 0, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_dept` VALUES (8, NULL, 2, '华北分部', 1, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_dept` VALUES (15, 8, 0, 'UI部门', 7, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_dept` VALUES (17, 2, 0, '研发一组', 999, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_dept` VALUES (18, 2, 0, 'asdasdasd', 999, b'1', 'admin', 'admin', '2025-03-28 14:56:05', '2025-03-28 14:56:05');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_dict
|
||||
@@ -303,7 +302,7 @@ CREATE TABLE `sys_dict` (
|
||||
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建日期',
|
||||
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '数据字典' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '数据字典' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_dict
|
||||
@@ -455,7 +454,7 @@ INSERT INTO `sys_menu` VALUES (119, 10, 0, 1, '数字滚动', 'countToDemo', 'co
|
||||
INSERT INTO `sys_menu` VALUES (120, 10, 0, 1, '拖拽表格', 'dragTableDemo', 'components/base/DragTableDemo', 999, 'menu', 'dragTableDemo', b'0', b'0', b'0', NULL, 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_menu` VALUES (121, 10, 0, 1, '分割面板', 'splitPaneDemo', 'components/base/SplitPaneDemo', 999, 'menu', 'splitPaneDemo', b'0', b'0', b'0', NULL, 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_menu` VALUES (122, 10, 0, 1, 'WebSocket', 'webSocketDemo', 'components/base/WebSocketDemo', 999, 'menu', 'webSocketDemo', b'0', b'0', b'0', NULL, 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_menu` VALUES (125, 10, 0, 1, '业务组件Demo', 'DemoShow', 'components/business/DemoShow', 999, 'menu', 'bussinessDemo', b'0', b'0', b'0', NULL, 'admin', 'admin', '2025-03-28 11:28:35', '2025-03-28 11:28:35');
|
||||
INSERT INTO `sys_menu` VALUES (125, 10, 0, 1, '业务组件Demo', 'DemoShow', 'components/business/DemoShow', 999, 'menu', 'bussinessDemo', b'0', b'0', b'0', NULL, 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_quartz_job
|
||||
@@ -487,8 +486,6 @@ CREATE TABLE `sys_quartz_job` (
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_quartz_job` VALUES (2, 'testTask', '0/5 * * * * ?', b'1', '测试1', 'run1', 'test', '带参测试,多参使用json', '测试', NULL, NULL, NULL, 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_quartz_job` VALUES (3, 'testTask', '0/5 * * * * ?', b'1', '测试', 'run', '', '不带参测试', 'Zheng Jie', '', '6', b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_quartz_job` VALUES (5, 'Test', '0/5 * * * * ?', b'1', '任务告警测试', 'run', NULL, '测试', 'test', '', NULL, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_quartz_job` VALUES (6, 'testTask', '0/5 * * * * ?', b'1', '测试3', 'run2', NULL, '测试3', 'Zheng Jie', '', NULL, b'1', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_quartz_log
|
||||
@@ -506,7 +503,7 @@ CREATE TABLE `sys_quartz_log` (
|
||||
`exception_detail` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '异常详情',
|
||||
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '定时任务日志' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '定时任务日志' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_quartz_log
|
||||
@@ -537,7 +534,7 @@ CREATE TABLE `sys_role` (
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_role` VALUES (1, '超级管理员', 1, '666', '全部', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_role` VALUES (2, '普通用户', 2, '-', '本级', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_role` VALUES (7, 'test', 3, 'testtesttesttesttesttesttesttesttest', '全部', 'admin', 'admin', '2025-03-28 16:09:42', '2025-03-28 16:09:42');
|
||||
INSERT INTO `sys_role` VALUES (7, 'test', 3, 'testtesttesttesttesttesttesttesttest', '全部', 'admin', 'admin', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_roles_depts
|
||||
@@ -583,10 +580,12 @@ INSERT INTO `sys_roles_menus` VALUES (10, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (11, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (11, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (14, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (14, 7);
|
||||
INSERT INTO `sys_roles_menus` VALUES (15, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (15, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (18, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (18, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (18, 7);
|
||||
INSERT INTO `sys_roles_menus` VALUES (21, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (21, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (22, 1);
|
||||
@@ -605,6 +604,7 @@ INSERT INTO `sys_roles_menus` VALUES (34, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (35, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (36, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (36, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (36, 7);
|
||||
INSERT INTO `sys_roles_menus` VALUES (37, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (39, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (41, 1);
|
||||
@@ -631,10 +631,13 @@ INSERT INTO `sys_roles_menus` VALUES (74, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (75, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (77, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (77, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (77, 7);
|
||||
INSERT INTO `sys_roles_menus` VALUES (78, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (78, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (78, 7);
|
||||
INSERT INTO `sys_roles_menus` VALUES (79, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (79, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (79, 7);
|
||||
INSERT INTO `sys_roles_menus` VALUES (80, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (80, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (83, 1);
|
||||
@@ -681,12 +684,13 @@ CREATE TABLE `sys_user` (
|
||||
INDEX `idx_dept_id`(`dept_id`) USING BTREE,
|
||||
INDEX `idx_enabled`(`enabled`) USING BTREE,
|
||||
INDEX `uniq_phone`(`phone`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统用户' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统用户' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of sys_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_user` VALUES (1, 2, 'admin', '管理员', '男', '18888888888', '1943815081@qq.com', '', '', '$2a$10$Egp1/gvFlt7zhlXVfEFw4OfWQCGPw0ClmMcc6FjTnvXNRVf9zdMRa', b'1', b'1', 'admin', 'admin', '2020-05-03 16:38:31', '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
INSERT INTO `sys_user` VALUES (3, 2, '测试', '测试', '男', '18888888881', '188888@qq.com', NULL, NULL, '$2a$10$DpAGWp3CYtYySPqJe.CnL.c/OCR0kkPLLAwAyID0yFHLamtYdYsvy', b'0', b'1', 'admin', 'admin', NULL, '2025-01-05 00:00:00', '2025-01-05 00:00:00');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_users_jobs
|
||||
@@ -704,6 +708,7 @@ CREATE TABLE `sys_users_jobs` (
|
||||
-- Records of sys_users_jobs
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_users_jobs` VALUES (1, 11);
|
||||
INSERT INTO `sys_users_jobs` VALUES (3, 11);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_users_roles
|
||||
@@ -721,6 +726,7 @@ CREATE TABLE `sys_users_roles` (
|
||||
-- Records of sys_users_roles
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_users_roles` VALUES (1, 1);
|
||||
INSERT INTO `sys_users_roles` VALUES (3, 2);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tool_email_config
|
||||
@@ -757,11 +763,12 @@ CREATE TABLE `tool_local_storage` (
|
||||
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建日期',
|
||||
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '本地存储' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '本地存储' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tool_local_storage
|
||||
-- ----------------------------
|
||||
INSERT INTO `tool_local_storage` VALUES (11, 'bg-202504100131576.jpg', 'bg', 'jpg', 'C:\\cutejava\\file\\image\\bg-202504100131576.jpg', 'image', '20.20MB ', 'admin', 'admin', '2025-04-10 13:32:00', '2025-04-10 13:32:00');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tool_qiniu_config
|
||||
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 29 KiB |