diff --git a/README.md b/README.md index 20cec8d8011818c814758560d220fedee77d96a2..cbc439febce9cb4b7b3b2fce777dbc216f5ef95e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Bootx-Platform (v1.1.0-beta-1) +# Bootx-Platform (v1.1.0-beta-2)

star - Build Status + Build Status Build Status - Downloads + Downloads

@@ -82,6 +82,8 @@ bootx-platform ├── common-websocket -- websocket ├── common-xxl-job -- XXL-JOB定时任务 ├── bootx-demo -- demo示例模块 + ├── bootx-modules -- 业务系统 + ├── eshop -- 网上商城 ├── bootx-services -- 业务服务模块 ├── service-baseapi -- 基础api功能服务 ├── service-goods -- 商品中心服务(未完成) diff --git a/_config/elk/filebeat/Dockerfile b/_config/elk/filebeat/Dockerfile index d7e70646825f718861c707c613613cf82cd991d4..6279ddcabb4cbcd82bcc9d348da9d149d99bf435 100644 --- a/_config/elk/filebeat/Dockerfile +++ b/_config/elk/filebeat/Dockerfile @@ -1,8 +1,8 @@ FROM docker.elastic.co/beats/filebeat:7.13.2 -MAINTAINER xxm1995@outlook.com +MAINTAINER xxm COPY filebeat.yml /usr/share/filebeat/filebeat.yml USER root -RUN chown root:filebeat /usr/share/filebeat/filebeat.yml +RUN chown filebeat /usr/share/filebeat/filebeat.yml USER filebeat \ No newline at end of file diff --git a/_doc/ChangeLog.md b/_doc/ChangeLog.md index 324d6ed490835e070702bee42bccf13a48357623..c0bd3023305693914f9679afb9fe8de2a9e96a6a 100644 --- a/_doc/ChangeLog.md +++ b/_doc/ChangeLog.md @@ -1,12 +1,28 @@ # CHANGELOG ## [v1.1.0-bate-2] 一号线-工研院.测试版2 - 增加ELK相关配置,优化日志输出格式 +- 增加不同的终端可以有不同的菜单权限列表 - 增加RabbitMQ消息队列模块 +- 增加Redis简单消息队列方式,实现简单消息队列功能 +- 增加Redis过期事件封装,实现定时消息通知功能 +- 增加Redis简单消息队列和过期事件封装演示 +- 增加Websocket模块及演示DEMO - 增加分布式锁组件 +- 增加分布式锁演示模块 +- 网上商城配套开发 + - 类目管理及相关规格、品牌、参数管理 +- 优化Redis支持集群配置 +- 优化定时任务增加状态同步按钮,处理定时任务job运行状态不一致情况 - 优化数据权限异常类型 - 优化一些抛出异常的处理 - 优化项目pom结构 +- 优化前端路由跳过登录鉴权配置 +- 优化请求权限校验流程 +- 优化MQTT .lock文件夹问题 +- 优化前端支持内部打开外部页面 - fix: 权限不拦截问题 +- fix: 开启验证码后, 在登录页面提示请求报错 +- fix: 在MacOS环境下运行日志存储报错问题 - fix: mqtt ClientId配置问题导致启动时连接失败的问题 ## [v1.1.0-bate-1] 一号线-工研院.测试版1 - 增加kay/value存储类 diff --git a/bootx-common-core/pom.xml b/bootx-common-core/pom.xml index 894d52cea3d149f21a5f8be8d0ea2fa6bc9e92ee..77d22882bc7cca62076e67b0669c7031ad360067 100644 --- a/bootx-common-core/pom.xml +++ b/bootx-common-core/pom.xml @@ -14,14 +14,14 @@ UTF-8 - 5.7.22 + 5.8.0 2.12.3 3.11 4.4 1.9 2.11.0 31.1-jre - 7.0.1.Final + 7.0.4.Final 4.0.1 1.7.30 diff --git a/bootx-common-core/src/main/java/cn/bootx/common/core/annotation/OperateLog.java b/bootx-common-core/src/main/java/cn/bootx/common/core/annotation/OperateLog.java index 0bd2dd982f1a236b748eca05adf8c855ca9c3b7d..7d3660fd73a9f818d6c16655bd964ddb27a5fd6a 100644 --- a/bootx-common-core/src/main/java/cn/bootx/common/core/annotation/OperateLog.java +++ b/bootx-common-core/src/main/java/cn/bootx/common/core/annotation/OperateLog.java @@ -5,7 +5,7 @@ import cn.bootx.common.core.enums.BusinessType; import java.lang.annotation.*; /** -* 操作日志注解 +* 操作日志注解(支持重复注解) * @author xxm * @date 2021/8/13 */ diff --git a/bootx-common-core/src/main/java/cn/bootx/common/core/code/WebHeaderCode.java b/bootx-common-core/src/main/java/cn/bootx/common/core/code/WebHeaderCode.java index ef96ed84067d287faee6afd0d67fc51f477519cd..545d74cb2c4a988b8b35b30bccd23ba4cbfb19ca 100644 --- a/bootx-common-core/src/main/java/cn/bootx/common/core/code/WebHeaderCode.java +++ b/bootx-common-core/src/main/java/cn/bootx/common/core/code/WebHeaderCode.java @@ -1,7 +1,7 @@ package cn.bootx.common.core.code; /** - * web常量 + * web请求头常量 * @author network */ public interface WebHeaderCode { diff --git a/bootx-common-core/src/main/java/cn/bootx/common/core/entity/UserDetail.java b/bootx-common-core/src/main/java/cn/bootx/common/core/entity/UserDetail.java index 767d1479d6251d86aa60992d9c8c32475001a4f1..7e8b98df6ed659771116c62b7ac47f52b70b38d6 100644 --- a/bootx-common-core/src/main/java/cn/bootx/common/core/entity/UserDetail.java +++ b/bootx-common-core/src/main/java/cn/bootx/common/core/entity/UserDetail.java @@ -7,6 +7,8 @@ import lombok.Setter; import lombok.ToString; import lombok.experimental.Accessors; +import java.util.List; + /** * 用户类 * @author xxm @@ -27,6 +29,9 @@ public class UserDetail{ @JsonIgnore private transient String password; + /** 拥有终端列表 */ + private List clientIds; + /** 是否管理员 */ private boolean admin; diff --git a/bootx-common-core/src/main/java/cn/bootx/common/core/extra/ParamService.java b/bootx-common-core/src/main/java/cn/bootx/common/core/function/ParamService.java similarity index 64% rename from bootx-common-core/src/main/java/cn/bootx/common/core/extra/ParamService.java rename to bootx-common-core/src/main/java/cn/bootx/common/core/function/ParamService.java index b193fae8f8af1fa5d4f7457bc63984056016ab9a..c91dff6db1fc459ab794276c9e401d97c7f11061 100644 --- a/bootx-common-core/src/main/java/cn/bootx/common/core/extra/ParamService.java +++ b/bootx-common-core/src/main/java/cn/bootx/common/core/function/ParamService.java @@ -1,7 +1,7 @@ -package cn.bootx.common.core.extra; +package cn.bootx.common.core.function; /** -* 参数获取服务 +* 参数获取服务(必须有实现类) * @author xxm * @date 2022/5/1 */ diff --git a/bootx-common-core/src/main/java/cn/bootx/common/core/rest/ResResult.java b/bootx-common-core/src/main/java/cn/bootx/common/core/rest/ResResult.java index f2948bf615ee5a9bcc964b6a1b541bf882e57999..14dc2c749f392f7b5193036053ff45fe2b1464b1 100644 --- a/bootx-common-core/src/main/java/cn/bootx/common/core/rest/ResResult.java +++ b/bootx-common-core/src/main/java/cn/bootx/common/core/rest/ResResult.java @@ -3,6 +3,7 @@ package cn.bootx.common.core.rest; import cn.bootx.common.core.code.CommonCode; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import java.io.Serializable; @@ -13,6 +14,7 @@ import java.io.Serializable; */ @Getter @Setter +@ToString public class ResResult implements Serializable { private static final long serialVersionUID = -3041700282408360384L; private String msg = "success"; diff --git a/bootx-common-core/src/main/java/cn/bootx/common/core/util/CollUtil.java b/bootx-common-core/src/main/java/cn/bootx/common/core/util/CollUtil.java index bd2a80faa9acaa4a6955f0b23dcf8de887cc4024..c3b89abf509e972df3801e52de835e0924142a9c 100644 --- a/bootx-common-core/src/main/java/cn/bootx/common/core/util/CollUtil.java +++ b/bootx-common-core/src/main/java/cn/bootx/common/core/util/CollUtil.java @@ -10,7 +10,7 @@ import java.util.Collection; * @date 2020/11/28 */ @UtilityClass -public class CollUtil { +public class CollUtil extends cn.hutool.core.collection.CollUtil { /** * 判断两个集合是否有交集 diff --git a/bootx-common-core/src/main/java/cn/bootx/common/core/util/ValidationUtil.java b/bootx-common-core/src/main/java/cn/bootx/common/core/util/ValidationUtil.java index a89829eb637c7c0dd21e23c8bba694ad11264d1d..036217847d9c28465308ebb34c94a610496e8b02 100644 --- a/bootx-common-core/src/main/java/cn/bootx/common/core/util/ValidationUtil.java +++ b/bootx-common-core/src/main/java/cn/bootx/common/core/util/ValidationUtil.java @@ -23,9 +23,9 @@ public class ValidationUtil { /** * 验证参数对象,如果验证失败则抛出异常 */ - public void validateParam(Object paramObject) { + public void validateParam(Object paramObject, Class... groups) { Validator validator = validatorFactory.getValidator(); - Set> violations = validator.validate(paramObject); + Set> violations = validator.validate(paramObject,groups); if (!violations.isEmpty()) { throw new ValidationFailedException(extractMessages(violations)); } @@ -42,9 +42,9 @@ public class ValidationUtil { /** * 验证参数对象,如果验证失败则返回所有失败信息 */ - public String validate(Object paramObject){ + public String validate(Object paramObject, Class... groups){ Validator validator = validatorFactory.getValidator(); - Set> violations = validator.validate(paramObject); + Set> violations = validator.validate(paramObject,groups); StringBuilder message = new StringBuilder(); for (ConstraintViolation violation : violations) { diff --git a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/authentication/AbstractAuthentication.java b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/authentication/AbstractAuthentication.java index 39244945cf89b5f0f0bbdec2df95ee3650214d07..8a36c0471cc950a0e3b65616a1e6a1f1897789dc 100644 --- a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/authentication/AbstractAuthentication.java +++ b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/authentication/AbstractAuthentication.java @@ -2,8 +2,9 @@ package cn.bootx.starter.auth.authentication; import cn.bootx.common.core.entity.UserDetail; import cn.bootx.starter.auth.config.AuthProperties; -import cn.bootx.starter.auth.entity.LoginAuthContext; +import cn.bootx.starter.auth.entity.AuthClient; import cn.bootx.starter.auth.entity.AuthInfoResult; +import cn.bootx.starter.auth.entity.LoginAuthContext; import cn.bootx.starter.auth.exception.LoginFailureException; import javax.validation.constraints.NotNull; @@ -39,8 +40,9 @@ public interface AbstractAuthentication { */ default AuthInfoResult authentication(LoginAuthContext context){ this.authenticationBefore(context); + // 认证逻辑 AuthInfoResult authInfoResult = this.attemptAuthentication(context); - + AuthClient authClient = context.getAuthClient(); // 添加用户信息到上下文中 UserDetail userDetail = authInfoResult.getUserDetail(); context.setUserDetail(userDetail); @@ -50,7 +52,13 @@ public interface AbstractAuthentication { if (!authProperties.isEnableAdmin()&&userDetail.isAdmin()){ throw new LoginFailureException("未开启超级管理员权限"); } - + // 管理员跳过各种限制 + if (!userDetail.isAdmin()){ + // 在终端有独立权限控制的情况下, 判断用户是否拥有终端的权限 + if (authClient.isAlonePrem() && !userDetail.getClientIds().contains(authClient.getId())){ + throw new LoginFailureException("该用户不拥有该终端的权限"); + } + } authenticationAfter(authInfoResult,context); return authInfoResult; } diff --git a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/cache/SessionCacheLocal.java b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/cache/SessionCacheLocal.java index 472100666f529148fb082cce2792cb4c469ff9d5..95fcc967926a3b46f228331cfea6a9d50be80b8d 100644 --- a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/cache/SessionCacheLocal.java +++ b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/cache/SessionCacheLocal.java @@ -3,28 +3,25 @@ package cn.bootx.starter.auth.cache; import cn.bootx.common.core.entity.UserDetail; import com.alibaba.ttl.TransmittableThreadLocal; -import java.util.Optional; - /** * 会话缓存线程存储 * @author xxm * @date 2022/1/8 */ public final class SessionCacheLocal { - private static final ThreadLocal> THREAD_LOCAL_TENANT = new TransmittableThreadLocal<>(); + private static final ThreadLocal THREAD_LOCAL_TENANT = new TransmittableThreadLocal<>(); /** * TTL 设置数据 */ - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - public static void put(Optional userDetail) { + public static void put(UserDetail userDetail) { THREAD_LOCAL_TENANT.set(userDetail); } /** * 获取TTL中的数据 */ - public static Optional get() { + public static UserDetail get() { return THREAD_LOCAL_TENANT.get(); } diff --git a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/config/AuthConfigure.java b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/config/AuthConfigure.java deleted file mode 100644 index 0a5ceade8e3212b927b9cdc7057989f64969bc9e..0000000000000000000000000000000000000000 --- a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/config/AuthConfigure.java +++ /dev/null @@ -1,12 +0,0 @@ -package cn.bootx.starter.auth.config; - -import org.springframework.context.annotation.Configuration; - -/** -* 认证相关配置 -* @author xxm -* @date 2021/7/30 -*/ -@Configuration -public class AuthConfigure { -} diff --git a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/entity/AuthClient.java b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/entity/AuthClient.java index 016421f6e3d495dfcfc697413efbf04b3da70b09..89c7fac1499226427055c142090d09ad487b7043 100644 --- a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/entity/AuthClient.java +++ b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/entity/AuthClient.java @@ -12,6 +12,10 @@ import lombok.experimental.Accessors; @Accessors(chain = true) @Schema(title = "认证终端") public class AuthClient { + + /** 终端id */ + private Long id; + /** 编码 */ private String code; @@ -21,6 +25,9 @@ public class AuthClient { /** 在线时长 分钟 */ private long timeout; + /** 是否有独立菜单和权限 */ + private boolean alonePrem; + /** 是否可用 */ private boolean enable; diff --git a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/handler/BootxSaTokenListener.java b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/handler/BootxSaTokenListener.java deleted file mode 100644 index 908ded4e7b9854c229045178f43c712946363a30..0000000000000000000000000000000000000000 --- a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/handler/BootxSaTokenListener.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.bootx.starter.auth.handler; - -import cn.dev33.satoken.listener.SaTokenListenerDefaultImpl; -import cn.dev33.satoken.stp.SaLoginModel; -import org.springframework.stereotype.Component; - -/** -* 自定义侦听器实现 -* @author xxm -* @date 2021/7/30 -*/ -@Component -public class BootxSaTokenListener extends SaTokenListenerDefaultImpl { - - /** 每次登录时触发 */ - @Override - public void doLogin(String loginType, Object loginId, SaLoginModel loginModel) { - // ... - - } - - /** 每次注销时触发 */ - @Override - public void doLogout(String loginType, Object loginId, String tokenValue) { - // ... - } - - - - /** 每次被封禁时触发 */ - @Override - public void doDisable(String loginType, Object loginId, long disableTime) { - // ... - } - - /** 每次被解封时触发 */ - @Override - public void doUntieDisable(String loginType, Object loginId) { - // ... - } - - /** 每次创建Session时触发 */ - @Override - public void doCreateSession(String id) { - // ... - } - - /** 每次注销Session时触发 */ - @Override - public void doLogoutSession(String id) { - // ... - } -} diff --git a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/impl/IgnoreAdminUserRouterCheck.java b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/impl/IgnoreAdminUserRouterCheck.java new file mode 100644 index 0000000000000000000000000000000000000000..00f29a8613026d7acbdd96fbf44ca0135438da39 --- /dev/null +++ b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/impl/IgnoreAdminUserRouterCheck.java @@ -0,0 +1,33 @@ +package cn.bootx.starter.auth.impl; + + +import cn.bootx.common.core.entity.UserDetail; +import cn.bootx.starter.auth.authentication.RouterCheck; +import cn.bootx.starter.auth.config.AuthProperties; +import cn.bootx.starter.auth.util.SecurityUtil; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +/** +* 超级管理员跳过各种限制 +* @author xxm +* @date 2022/5/27 +*/ +@Component +@RequiredArgsConstructor +public class IgnoreAdminUserRouterCheck implements RouterCheck { + private final AuthProperties authProperties; + @Override + public int sortNo() { + return 0; + } + + @Override + public boolean check(Object handler) { + if (authProperties.isEnableAdmin()){ + UserDetail userDetail = SecurityUtil.getCurrentUser().orElse(new UserDetail()); + return userDetail.isAdmin(); + } + return false; + } +} diff --git a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/impl/IgnoreAuthRouterCheck.java b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/impl/IgnoreAnnotationRouterCheck.java similarity index 90% rename from bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/impl/IgnoreAuthRouterCheck.java rename to bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/impl/IgnoreAnnotationRouterCheck.java index c2515cb0c5bed224756d588ce57e3e34bf4ca8ad..6d9c1e5164796da73efe7d0c15cd663f04c8ceb2 100644 --- a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/impl/IgnoreAuthRouterCheck.java +++ b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/impl/IgnoreAnnotationRouterCheck.java @@ -13,7 +13,12 @@ import java.util.Objects; * @date 2021/12/21 */ @Component -public class IgnoreAuthRouterCheck implements RouterCheck { +public class IgnoreAnnotationRouterCheck implements RouterCheck { + + @Override + public int sortNo() { + return -99; + } @Override public boolean check(Object handler) { diff --git a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/util/SecurityUtil.java b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/util/SecurityUtil.java index 1278272dc9f1320e0556a1fc12a1afec26672ab8..015b224f1e98af3acf6ecae36963b9ff0775e943 100644 --- a/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/util/SecurityUtil.java +++ b/bootx-common-starters/common-starter-auth/src/main/java/cn/bootx/starter/auth/util/SecurityUtil.java @@ -2,15 +2,14 @@ package cn.bootx.starter.auth.util; import cn.bootx.common.core.code.CommonCode; import cn.bootx.common.core.entity.UserDetail; -import cn.bootx.starter.auth.exception.NotLoginException; import cn.bootx.starter.auth.cache.SessionCacheLocal; +import cn.bootx.starter.auth.exception.NotLoginException; import cn.dev33.satoken.exception.SaTokenException; import cn.dev33.satoken.stp.StpUtil; import lombok.experimental.UtilityClass; import org.springframework.lang.Nullable; import javax.servlet.http.HttpServletRequest; -import java.util.Objects; import java.util.Optional; /** @@ -56,15 +55,15 @@ public class SecurityUtil { * 获取当前用户,无异常, 使用线程缓存来减少redis的访问频率 */ private Optional getCurrentUser0(){ - Optional userDetail = SessionCacheLocal.get(); - if (Objects.isNull(userDetail)){ + Optional userDetail = Optional.ofNullable(SessionCacheLocal.get()); + if (!userDetail.isPresent()){ try { userDetail = Optional.ofNullable(StpUtil.getSession()) .map(saSession -> saSession.getModel(CommonCode.USER,UserDetail.class)); + SessionCacheLocal.put(userDetail.orElse(null)); } catch (SaTokenException e) { userDetail = Optional.empty(); } - SessionCacheLocal.put(userDetail); } return userDetail; } diff --git a/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/controller.java.vm b/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/controller.java.vm index d03994cd388c7ce5bce4a3f2c1547c72123bc0c9..d842769a432984290509e43201b0495a3538a537 100644 --- a/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/controller.java.vm +++ b/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/controller.java.vm @@ -7,7 +7,6 @@ import cn.bootx.common.core.rest.param.PageParam; import cn.bootx.${module}.core.${method}.service.${className}Service; import cn.bootx.${module}.dto.${method}.${className}Dto; import cn.bootx.${module}.param.${method}.${className}Param; -import QueryParams; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -29,14 +28,16 @@ public class ${className}Controller { @Operation( summary = "添加") @PostMapping(value = "/add") - public ResResult<${className}Dto> add(@RequestBody ${className}Param param){ - return Res.ok(${classname}Service.add(param)); + public ResResult add(@RequestBody ${className}Param param){ + ${classname}Service.add(param); + return Res.ok(); } @Operation( summary = "修改") @PostMapping(value = "/update") - public ResResult<${className}Dto> update(@RequestBody ${className}Param param){ - return Res.ok(${classname}Service.update(param)); + public ResResult update(@RequestBody ${className}Param param){ + ${classname}Service.update(param); + return Res.ok(); } @Operation( summary = "删除") diff --git a/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/manager.java.vm b/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/manager.java.vm index d27b122232477fd9049d38913a34b8195b71ce20..6a914206c6f135393c6c6b720705b5084c453066 100644 --- a/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/manager.java.vm +++ b/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/manager.java.vm @@ -1,6 +1,7 @@ package cn.bootx.${module}.core.${method}.dao; import cn.bootx.common.mybatisplus.impl.BaseManager; +import cn.bootx.${module}.param.${method}.${className}Param; import cn.bootx.${module}.core.${method}.entity.${className}; import cn.bootx.common.core.rest.param.PageParam; import cn.bootx.common.mybatisplus.base.MpBaseEntity; @@ -28,6 +29,6 @@ public class ${className}Manager extends BaseManager<${className}Mapper, ${class */ public Page<${className}> page(PageParam pageParam, ${className}Param param) { Page<${className}> mpPage = MpUtil.getMpPage(pageParam, ${className}.class); - return lambdaQuery().orderByDesc(MpBaseEntity::getCreateTime).page(mpPage); + return lambdaQuery().orderByDesc(MpBaseEntity::getId).page(mpPage); } } \ No newline at end of file diff --git a/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/service.java.vm b/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/service.java.vm index efb6854f3eb382e475662067e2464909fc66a021..ab59434403ea4157a8e8db07de6f441bfb9beba1 100644 --- a/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/service.java.vm +++ b/bootx-common-starters/common-starter-code-gen/src/main/resources/codegen/template/java/service.java.vm @@ -5,11 +5,12 @@ import cn.bootx.common.core.rest.PageResult; import cn.bootx.common.core.rest.param.PageParam; import cn.bootx.common.core.util.ResultConvertUtil; import cn.bootx.common.mybatisplus.util.MpUtil; - ${module}.dto.${method}.${className}Dto; - ${module}.param.${method}.${className}Param; - ${module}.core.${method}.convert.${className}Convert; - ${module}.core.${method}.entity.${className}; - ${module}.core.${method}.dao.${className}Manager; +import cn.bootx.${module}.dto.${method}.${className}Dto; +import cn.bootx.${module}.param.${method}.${className}Param; +import cn.bootx.${module}.core.${method}.convert.${className}Convert; +import cn.bootx.${module}.core.${method}.entity.${className}; +import cn.bootx.${module}.core.${method}.dao.${className}Manager; +import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -29,19 +30,19 @@ public class ${className}Service { /** * 添加 */ - public ${className}Dto add(${className}Param param){ + public void add(${className}Param param){ ${className} ${classname} = ${className}.init(param); - return ${classname}Manager.save(${classname}).toDto(); + ${classname}Manager.save(${classname}); } /** * 修改 */ - public ${className}Dto update(${className}Param param){ + public void update(${className}Param param){ ${className} ${classname} = ${classname}Manager.findById(param.getId()).orElseThrow(DataNotExistException::new); BeanUtil.copyProperties(param,${classname}, CopyOptions.create().ignoreNullValue()); - return ${classname}Manager.updateById(${classname}).toDto(); + ${classname}Manager.updateById(${classname}); } /** @@ -65,5 +66,10 @@ public class ${className}Service { return ResultConvertUtil.dtoListConvert(${classname}Manager.findAll()); } - + /** + * 删除 + */ + public void delete(Long id){ + ${classname}Manager.deleteById(id); + } } \ No newline at end of file diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/starter/file/service/FileUploadService.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/starter/file/service/FileUploadService.java index 7d458e3f6a36a6e86d5b3b691eee443b106197e7..667012075745fa1e8bd53ae558747064c100855c 100644 --- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/starter/file/service/FileUploadService.java +++ b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/starter/file/service/FileUploadService.java @@ -1,7 +1,7 @@ package cn.bootx.starter.file.service; import cn.bootx.common.core.exception.BizException; -import cn.bootx.common.core.extra.ParamService; +import cn.bootx.common.core.function.ParamService; import cn.bootx.common.core.rest.PageResult; import cn.bootx.common.core.rest.param.PageParam; import cn.bootx.common.mybatisplus.util.MpUtil; diff --git a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/controller/QuartzJobController.java b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/controller/QuartzJobController.java index 30c4a50c4a522965d136cab4b47cb61f1f2add2d..9cae63f4982983603e97b149b66c478eec425b0d 100644 --- a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/controller/QuartzJobController.java +++ b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/controller/QuartzJobController.java @@ -83,4 +83,11 @@ public class QuartzJobController { public ResResult judgeJobClass(String jobClassName){ return Res.ok(quartzJobService.judgeJobClass(jobClassName)); } + + @Operation(summary = "同步定时任务状态") + @PostMapping("/syncJobStatus") + public ResResult syncJobStatus(){ + quartzJobService.syncJobStatus(); + return Res.ok(); + } } diff --git a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/core/dao/QuartzJobManager.java b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/core/dao/QuartzJobManager.java index 3d9f1ea830ef7b921edcc542006b09ce4329f21f..e4fcd76b3367d1acea9229849c42da85f880ba01 100644 --- a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/core/dao/QuartzJobManager.java +++ b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/core/dao/QuartzJobManager.java @@ -3,6 +3,7 @@ package cn.bootx.starter.quartz.core.dao; import cn.bootx.common.core.rest.param.PageParam; import cn.bootx.common.mybatisplus.impl.BaseManager; import cn.bootx.common.mybatisplus.util.MpUtil; +import cn.bootx.starter.quartz.code.QuartzJobCode; import cn.bootx.starter.quartz.core.entity.QuartzJob; import cn.bootx.starter.quartz.param.QuartzJobParam; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -10,6 +11,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; +import java.util.List; + /** * 定时任务 * @author xxm @@ -29,4 +32,11 @@ public class QuartzJobManager extends BaseManager { .orderByDesc(QuartzJob::getId) .page(mpPage); } + + /** + * 查询在执行中的定时任务配置 + */ + public List findRunning(){ + return findAllByField(QuartzJob::getState, QuartzJobCode.RUNNING); + } } diff --git a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/core/service/QuartzJobService.java b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/core/service/QuartzJobService.java index 611075f1c57c9f9d7066b4bdc5d462d5f92ef969..42d48362ba36d4c4fb339a658b26bed65bb26efa 100644 --- a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/core/service/QuartzJobService.java +++ b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/core/service/QuartzJobService.java @@ -4,6 +4,7 @@ import cn.bootx.common.core.exception.BizException; import cn.bootx.common.core.exception.DataNotExistException; import cn.bootx.common.core.rest.PageResult; import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.core.util.CollUtil; import cn.bootx.common.mybatisplus.util.MpUtil; import cn.bootx.starter.quartz.code.QuartzJobCode; import cn.bootx.starter.quartz.core.dao.QuartzJobManager; @@ -15,16 +16,21 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.quartz.Trigger; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Collection; +import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; /** -* 定时任务 -* @author xxm -* @date 2021/11/2 -*/ + * 定时任务 + * @author xxm + * @date 2021/11/2 + */ @Slf4j @Service @RequiredArgsConstructor @@ -136,4 +142,32 @@ public class QuartzJobService { return null; } + /** + * 同步状态 + */ + public void syncJobStatus(){ + Map quartzJobMap = quartzJobManager.findRunning().stream() + .collect(Collectors.toMap(o->o.getId().toString(), o -> o)); + + List triggers = jobScheduler.findTriggers(); + + // 将开始任务列表里没有的Trigger给删除. 将未启动的任务状态更新成停止 + for (Trigger trigger : triggers) { + String triggerName = trigger.getKey().getName(); + if (!quartzJobMap.containsKey(triggerName)) { + jobScheduler.delete(Long.valueOf(triggerName)); + } else { + quartzJobMap.remove(triggerName); + } + } + // 更新任务列表状态 + Collection quartzJobs = quartzJobMap.values(); + for (QuartzJob quartzJob : quartzJobs) { + quartzJob.setState(QuartzJobCode.STOP); + } + if (CollUtil.isNotEmpty(quartzJobs)) { + quartzJobManager.updateAllById(quartzJobs); + } + } + } diff --git a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/handler/QuartzJobScheduler.java b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/handler/QuartzJobScheduler.java index a870e9fd251ac5593965d60138b6d4906c599b41..6c9b7128eec544d95a08bf7675adf65c99ce5327 100644 --- a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/handler/QuartzJobScheduler.java +++ b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/starter/quartz/handler/QuartzJobScheduler.java @@ -4,10 +4,17 @@ package cn.bootx.starter.quartz.handler; import cn.bootx.common.core.exception.BizException; import cn.hutool.core.util.RandomUtil; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.quartz.*; +import org.quartz.impl.matchers.GroupMatcher; import org.springframework.stereotype.Service; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + /** * 定时任务调度器 * @author xxm @@ -99,7 +106,27 @@ public class QuartzJobScheduler { log.error(e.getMessage(),e); throw new BizException("定时任务启动失败"); } + } + + /** + * 获取定时任务列表 + */ + public List findTriggers() { + try { + GroupMatcher matcher = GroupMatcher.anyJobGroup(); + Set jobKeys = scheduler.getJobKeys(matcher); + return jobKeys.stream().map(this::getTriggersOfJob) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + + } catch (SchedulerException e) { + throw new BizException(e.getMessage()); + } + } + @SneakyThrows + private List getTriggersOfJob(JobKey jobKey){ + return scheduler.getTriggersOfJob(jobKey); } /** diff --git a/bootx-commons/common-cache/src/main/java/cn/bootx/common/cache/CachingConfiguration.java b/bootx-commons/common-cache/src/main/java/cn/bootx/common/cache/CachingConfiguration.java index e4b0cfb7192aad0267fb45a26c880b0f6584f57b..896741e190556d73f7c266cbdc13204419d68ab9 100644 --- a/bootx-commons/common-cache/src/main/java/cn/bootx/common/cache/CachingConfiguration.java +++ b/bootx-commons/common-cache/src/main/java/cn/bootx/common/cache/CachingConfiguration.java @@ -1,10 +1,7 @@ package cn.bootx.common.cache; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; -import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -33,11 +30,15 @@ import java.time.Duration; @EnableConfigurationProperties(CachingProperties.class) @ConditionalOnClass(CacheManager.class) @ConditionalOnProperty(prefix = "bootx.common.cache", value = "enabled", havingValue = "true",matchIfMissing = true) -@RequiredArgsConstructor public class CachingConfiguration extends CachingConfigurerSupport { private final CachingProperties cachingProperties; - private final ObjectMapper objectMapper; + private final ObjectMapper redisObjectMapper; + + public CachingConfiguration(CachingProperties cachingProperties, @Qualifier("redisObjectMapper") ObjectMapper redisObjectMapper) { + this.cachingProperties = cachingProperties; + this.redisObjectMapper = redisObjectMapper; + } /** * 不配置key的情况,将方法名作为缓存key名称 @@ -69,15 +70,7 @@ public class CachingConfiguration extends CachingConfigurerSupport { private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Duration duration) { // 序列化方式 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); - - // 复制出一份 - ObjectMapper objectMapperCopy = objectMapper.copy(); - //指定序列化输入的类型为非最终类型,除了少数“自然”类型(字符串、布尔值、整数、双精度),它们可以从 JSON 正确推断; 以及所有非最终类型的数组 - objectMapperCopy.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY) - // null 值不序列化 - .setSerializationInclusion(JsonInclude.Include.NON_NULL); - - jackson2JsonRedisSerializer.setObjectMapper(objectMapperCopy); + jackson2JsonRedisSerializer.setObjectMapper(redisObjectMapper); // redis缓存配置 return RedisCacheConfiguration diff --git a/bootx-commons/common-jackson/src/main/java/cn/bootx/common/jackson/util/JacksonUtilsConfiguration.java b/bootx-commons/common-jackson/src/main/java/cn/bootx/common/jackson/util/JacksonUtilsConfiguration.java index 5ea5679b4edd9f2e55a0d340e71cdcfa3f1607f4..debaa26e44d729d35b151743dd2de7b6aad4e044 100644 --- a/bootx-commons/common-jackson/src/main/java/cn/bootx/common/jackson/util/JacksonUtilsConfiguration.java +++ b/bootx-commons/common-jackson/src/main/java/cn/bootx/common/jackson/util/JacksonUtilsConfiguration.java @@ -9,7 +9,7 @@ import org.springframework.context.annotation.Configuration; import javax.validation.constraints.NotNull; /** -* +* 设置JacksonUtil 的 om对象 * @author xxm * @date 2021/7/6 */ diff --git a/bootx-commons/common-lock/src/main/java/cn/bootx/common/lock/annotation/Lock.java b/bootx-commons/common-lock/src/main/java/cn/bootx/common/lock/annotation/Lock.java index ac42c82f53f6d4d3d80d2ab78f5db96a7028df9d..a129712cf16c6cb1d0bfe79db34fb04af1a330c5 100644 --- a/bootx-commons/common-lock/src/main/java/cn/bootx/common/lock/annotation/Lock.java +++ b/bootx-commons/common-lock/src/main/java/cn/bootx/common/lock/annotation/Lock.java @@ -49,7 +49,7 @@ public @interface Lock { TimeUnit timeUnit() default TimeUnit.SECONDS; /** - * 自定义业务key + * 自定义业务key 支持SpEl表达式 */ String[] keys() default {}; } diff --git a/bootx-commons/common-lock/src/main/java/cn/bootx/common/lock/service/impl/FairLockServiceImpl.java b/bootx-commons/common-lock/src/main/java/cn/bootx/common/lock/service/impl/FairLockServiceImpl.java index 79352d11aa9f5b917cc04fb0775caeefb7d078a8..514c9730c5f96c7a898b356d8cafba1a5caf9ba7 100644 --- a/bootx-commons/common-lock/src/main/java/cn/bootx/common/lock/service/impl/FairLockServiceImpl.java +++ b/bootx-commons/common-lock/src/main/java/cn/bootx/common/lock/service/impl/FairLockServiceImpl.java @@ -21,7 +21,6 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT public class FairLockServiceImpl implements LockService { private final RedissonClient redissonClient; - private final ThreadLocal lockInfoThreadLocal = new ThreadLocal<>(); @Override diff --git a/bootx-commons/common-log/src/main/resources/cn/bootx/common/log/logback-bootx-common.xml b/bootx-commons/common-log/src/main/resources/cn/bootx/common/log/logback-bootx-common.xml index a0dff063c1d71101e53907e46f293c8a23745888..4e0e589471aa911904d1501b1a20942427525d09 100644 --- a/bootx-commons/common-log/src/main/resources/cn/bootx/common/log/logback-bootx-common.xml +++ b/bootx-commons/common-log/src/main/resources/cn/bootx/common/log/logback-bootx-common.xml @@ -18,6 +18,7 @@ ${logdir}/${appname}.log ${logdir}/${appname}.log.%d{yyyy-MM-dd}.gz + 30 @@ -31,6 +32,7 @@ ${logdir}/${appname}.link.json ${logdir}/${appname}.link.%d{yyyy-MM-dd}.gz + 30 diff --git a/bootx-commons/common-rabbitmq/src/main/java/cn/bootx/common/rabbit/configuration/BootxRabbitListenerConfigurer.java b/bootx-commons/common-rabbitmq/src/main/java/cn/bootx/common/rabbit/configuration/BootxRabbitListenerConfigurer.java index 4cbf239ee16ecca0778c88b6655cdefb25302cd8..96bab3e132c98ab9e63f66d75fb46e953dd9d2b9 100644 --- a/bootx-commons/common-rabbitmq/src/main/java/cn/bootx/common/rabbit/configuration/BootxRabbitListenerConfigurer.java +++ b/bootx-commons/common-rabbitmq/src/main/java/cn/bootx/common/rabbit/configuration/BootxRabbitListenerConfigurer.java @@ -14,7 +14,6 @@ import org.springframework.messaging.handler.annotation.support.DefaultMessageHa @Configuration @RequiredArgsConstructor public class BootxRabbitListenerConfigurer implements RabbitListenerConfigurer { - private final DefaultMessageHandlerMethodFactory jsonHandlerMethodFactory; @Override diff --git a/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/RedisClient.java b/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/RedisClient.java index 1e02a74513b14276ce06e62ab7b0834c864f406a..f28141231feac8f0e3a3882d1f1bf02db7003f01 100644 --- a/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/RedisClient.java +++ b/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/RedisClient.java @@ -42,6 +42,11 @@ public class RedisClient { stringRedisTemplate.opsForValue().set(key, value, timeoutMs, TimeUnit.MILLISECONDS); } + /** 设置超时通知的事件 */ + public void setKeyExpired(String keyPrefix, String key, long timeoutMs) { + stringRedisTemplate.opsForValue().set(keyPrefix+key, "", timeoutMs, TimeUnit.MILLISECONDS); + } + /** 是否过期 */ @SuppressWarnings("all") public boolean exists(String key) { diff --git a/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/configuration/RedisAutoConfiguration.java b/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/configuration/RedisAutoConfiguration.java index f6c371afc444c87adabaa44ab4f5b1cc11ea9faa..3e6c598edf08d1316478b1ec56112dd58b4132aa 100644 --- a/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/configuration/RedisAutoConfiguration.java +++ b/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/configuration/RedisAutoConfiguration.java @@ -6,6 +6,7 @@ import cn.bootx.common.redis.code.RedisCode; import cn.bootx.common.redis.listener.RedisTopicReceiver; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; @@ -156,14 +157,18 @@ public class RedisAutoConfiguration { } /** - * redis序列化配置 + * redis序列化配置 ObjectMapper 对象 + * 会记录被序列化的类型信息, 反序列化时直接能反序列化回原始的对象类型 */ @Bean public ObjectMapper redisObjectMapper() { // 对象映射器 ObjectMapper copy = objectMapper.copy(); // 序列化是记录被序列化的类型信息 - copy.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY); + //指定序列化输入的类型为非最终类型,除了少数“自然”类型(字符串、布尔值、整数、双精度),它们可以从 JSON 正确推断; 以及所有非最终类型的数组 + copy.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY) + // null 值不序列化 + .setSerializationInclusion(JsonInclude.Include.NON_NULL); return copy; } } diff --git a/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/KeyExpiredListener.java b/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/RedisKeyExpiredListener.java similarity index 87% rename from bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/KeyExpiredListener.java rename to bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/RedisKeyExpiredListener.java index f743387f6b33fc95cea19426735bdaa90f5a0486..7c490b78fe8cf127ed6a0f7c6920364b62077b8c 100644 --- a/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/KeyExpiredListener.java +++ b/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/RedisKeyExpiredListener.java @@ -5,7 +5,7 @@ package cn.bootx.common.redis.listener; * @author xxm * @date 2022/5/7 */ -public interface KeyExpiredListener { +public interface RedisKeyExpiredListener { /** * 要监听的key diff --git a/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/KeyExpiredReceiver.java b/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/RedisKeyExpiredReceiver.java similarity index 56% rename from bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/KeyExpiredReceiver.java rename to bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/RedisKeyExpiredReceiver.java index 4e266b8e7420e475898c4f9c6f08219723660746..1e7d9f8fce331ee311a19caa0662ddd66c298e07 100644 --- a/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/KeyExpiredReceiver.java +++ b/bootx-commons/common-redis-client/src/main/java/cn/bootx/common/redis/listener/RedisKeyExpiredReceiver.java @@ -16,22 +16,22 @@ import java.util.List; */ @Slf4j @Component -public class KeyExpiredReceiver extends KeyExpirationEventMessageListener { - private final List keyExpiredListeners; +public class RedisKeyExpiredReceiver extends KeyExpirationEventMessageListener { + private final List redisKeyExpiredListeners; - public KeyExpiredReceiver(RedisMessageListenerContainer listenerContainer, List keyExpiredListeners) { + public RedisKeyExpiredReceiver(RedisMessageListenerContainer listenerContainer, List redisKeyExpiredListeners) { super(listenerContainer); - this.keyExpiredListeners = keyExpiredListeners; + this.redisKeyExpiredListeners = redisKeyExpiredListeners; } @Override public void onMessage(Message message, byte[] pattern) { String expiredKey = new String(message.getBody()); - for (KeyExpiredListener keyExpiredListener : keyExpiredListeners) { - String prefixKey = keyExpiredListener.getPrefixKey(); + for (RedisKeyExpiredListener redisKeyExpiredListener : redisKeyExpiredListeners) { + String prefixKey = redisKeyExpiredListener.getPrefixKey(); if (StrUtil.startWith(expiredKey,prefixKey)){ // 去除key前缀 - keyExpiredListener.onMessage(StrUtil.removePrefix(expiredKey,prefixKey)); + redisKeyExpiredListener.onMessage(StrUtil.removePrefix(expiredKey,prefixKey)); } } } diff --git a/bootx-commons/common-websocket/src/main/java/cn/bootx/common/websocket/entity/WsResult.java b/bootx-commons/common-websocket/src/main/java/cn/bootx/common/websocket/entity/WsResult.java new file mode 100644 index 0000000000000000000000000000000000000000..b75f8add7722d75c593d873d037ddd1ec681775a --- /dev/null +++ b/bootx-commons/common-websocket/src/main/java/cn/bootx/common/websocket/entity/WsResult.java @@ -0,0 +1,21 @@ +package cn.bootx.common.websocket.entity; + +import cn.bootx.common.core.code.CommonCode; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** +* +* @author xxm +* @date 2022/5/25 +*/ +@Data +@Accessors(chain = true) +public class WsResult implements Serializable { + private static final long serialVersionUID = 2643141359685957800L; + + private int code = CommonCode.SUCCESS_CODE; + private String data; +} diff --git a/bootx-commons/common-websocket/src/main/java/cn/bootx/common/websocket/handler/WebSocketInterceptor.java b/bootx-commons/common-websocket/src/main/java/cn/bootx/common/websocket/handler/WebSocketInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..686fecb36933e32a0f03e443496a93c2bdc138a4 --- /dev/null +++ b/bootx-commons/common-websocket/src/main/java/cn/bootx/common/websocket/handler/WebSocketInterceptor.java @@ -0,0 +1,23 @@ +package cn.bootx.common.websocket.handler; + +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.server.HandshakeInterceptor; + +import java.util.Map; + +@Component +public class WebSocketInterceptor implements HandshakeInterceptor { + @Override + public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception { + + return true; + } + + @Override + public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { + + } +} diff --git a/bootx-commons/common-websocket/src/main/java/cn/bootx/common/websocket/service/WebSocketSessionManager.java b/bootx-commons/common-websocket/src/main/java/cn/bootx/common/websocket/service/WebSocketSessionManager.java new file mode 100644 index 0000000000000000000000000000000000000000..55d62e4102f21a33d795a8bff1ec6e4365f0777e --- /dev/null +++ b/bootx-commons/common-websocket/src/main/java/cn/bootx/common/websocket/service/WebSocketSessionManager.java @@ -0,0 +1,88 @@ +package cn.bootx.common.websocket.service; + +import cn.hutool.core.collection.ListUtil; + +import javax.websocket.Session; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; + +/** +* websocket抽象类 +* @author xxm +* @date 2022/5/27 +*/ +public class WebSocketSessionManager { + // session缓存 + protected static final Map sessionPool = new ConcurrentHashMap<>(); + // sessionId 与 连接id 的映射关系 n:1 + protected static final Map sid2id = new ConcurrentHashMap<>(); + // 连接id 与 sessionId 的映射关系 1:n + protected static final Map> id2sid = new ConcurrentHashMap<>(); + + /** + * 添加会话session关联 + */ + public void addSession(String id, Session session) { + try { + sid2id.put(session.getId(),id); + sessionPool.put(session.getId(),session); + List list = Optional.ofNullable(id2sid.get(id)) + .orElse(new CopyOnWriteArrayList<>()); + list.add(session.getId()); + id2sid.put(id,list); + } catch (Exception ignored) { + } + } + + /** + * 删掉 连接Session + */ + public void removeSession(Session session) { + sessionPool.remove(session.getId()); + String id = sid2id.remove(session.getId()); + Optional.ofNullable(id2sid.get(id)) + .ifPresent(list->list.removeIf(s-> Objects.equals(s,session.getId()))); + } + /** + * 删除 + */ + public void removeSessionById(String id){ + List sessionIds = id2sid.get(id); + sessionIds.forEach(sessionPool::remove); + sessionIds.forEach(sid2id::remove); + id2sid.remove(id); + + } + /** + * 根据id获取关联的session列表 + */ + public List getSessionsById(String id){ + List sessionIds = id2sid.get(id); + return sessionIds.stream().map(sessionPool::get) + .collect(Collectors.toList()); + } + + /** + * 获取所有连接session + */ + public ArrayList getSessions(){ + return ListUtil.toList(sessionPool.values()); + } + + + /** + * 根据session获取连接id + */ + public String getIdBySession(Session session){ + return sid2id.get(session.getId()); + } + + /** + * 根据session获取连接id + */ + public String getIdBySessionId(String sessionId){ + return sid2id.get(sessionId); + } +} diff --git a/bootx-demo/pom.xml b/bootx-demo/pom.xml index c0401cad4b7d13f21f9d6f72f32658c1d3c78039..48166c1e3b6bad110809ef08cdef43d592cd6372 100644 --- a/bootx-demo/pom.xml +++ b/bootx-demo/pom.xml @@ -39,6 +39,10 @@ cn.bootx.platform common-lock + + cn.bootx.platform + common-mqtt + cn.bootx.platform common-starter-dingtalk diff --git a/bootx-demo/src/main/java/cn/bootx/demo/controller/TestController.java b/bootx-demo/src/main/java/cn/bootx/demo/controller/TestController.java index 1a8d0bfbc644952afcaead88e0d0191eef7ef41e..8eea9f475d10d48106b3b40360245bd39e92e525 100644 --- a/bootx-demo/src/main/java/cn/bootx/demo/controller/TestController.java +++ b/bootx-demo/src/main/java/cn/bootx/demo/controller/TestController.java @@ -5,26 +5,22 @@ import cn.bootx.common.core.annotation.OperateLog; import cn.bootx.common.core.rest.Res; import cn.bootx.common.core.rest.ResResult; import cn.bootx.common.core.rest.dto.KeyValue; -import cn.bootx.common.lock.annotation.Lock; -import cn.bootx.common.redis.RedisClient; import cn.bootx.common.redis.code.RedisCode; import cn.bootx.common.sequence.func.Sequence; import cn.bootx.common.sequence.impl.DefaultRangeSequence; import cn.bootx.common.sequence.range.SeqRangeConfig; import cn.bootx.common.sequence.range.SeqRangeManager; -import cn.hutool.core.thread.ThreadUtil; +import cn.bootx.demo.ws.WebSocketDemo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.concurrent.TimeUnit; - @Slf4j @Tag(name ="测试控制器") @RestController @@ -32,10 +28,8 @@ import java.util.concurrent.TimeUnit; @RequiredArgsConstructor public class TestController { private final Sequence sequence; - private final TestService testService; + private final WebSocketDemo webSocketDemo; private final SeqRangeManager seqRangeManager; - private final RedisClient redisClient; - private final StringRedisTemplate stringRedisTemplate; private final RedisTemplate redisTemplate; @OperateLog(title = "测试日志") @@ -73,23 +67,6 @@ public class TestController { return Res.ok(defaultRangeSequence.next("aa")); } - @Operation(summary = "lock1") - @GetMapping("/lock1") - @Lock(keys = "#x",name="lock",waitTime = Long.MAX_VALUE) - public ResResult lock1(Integer x){ - log.info("start"); - ThreadUtil.sleep(15, TimeUnit.SECONDS); - log.info("end"); - return Res.ok(); - } - @Operation(summary="lock2") - @GetMapping("/lock2") - @Lock(keys = "#x",name="lock",waitTime = Long.MAX_VALUE) - public ResResult lock2(Integer x){ - log.info("345"); - return Res.ok(); - } - @Operation(summary = "redis消息队列发布") @GetMapping("/redisPub") public ResResult redisPub(){ @@ -101,4 +78,18 @@ public class TestController { // stringRedisTemplate.convertAndSend(RedisCode.TOPIC_PREFIX+"t2",new KeyValue("aa","bbb")); return Res.ok(); } + + @Operation(summary = "发送ws消息") + @PostMapping("/sendWsByUserId") + public ResResult sendWsByUserId(Long userId,String msg){ + webSocketDemo.sendMessage(msg,userId); + return Res.ok(); + } + + @Operation(summary = "发送ws消息(全部用户)") + @PostMapping("/sendWsByAll") + public ResResult sendWsByUserId(String msg){ + webSocketDemo.sendMessage(msg); + return Res.ok(); + } } diff --git a/bootx-demo/src/main/java/cn/bootx/demo/controller/TestLogController.java b/bootx-demo/src/main/java/cn/bootx/demo/controller/TestLogController.java deleted file mode 100644 index b6a96ec9ad96bef74421746c913c1381e689d7a0..0000000000000000000000000000000000000000 --- a/bootx-demo/src/main/java/cn/bootx/demo/controller/TestLogController.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.bootx.demo.controller; - -import cn.bootx.common.core.rest.Res; -import cn.bootx.common.core.rest.ResResult; -import cn.bootx.iam.core.client.entity.Client; -import cn.bootx.starter.audit.log.param.DataVersionLogParam; -import cn.bootx.starter.audit.log.service.DataVersionLogService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.time.LocalDateTime; - -/** -* 测试日志 -* @author xxm -* @date 2022/1/10 -*/ -@Tag(name = "测试日志") -@RestController -@RequestMapping("/") -@RequiredArgsConstructor -public class TestLogController { - private final DataVersionLogService dataVersionLogService; - - - @Operation(summary = "测试数据版本日志") - @PostMapping("/testDataVersion") - public ResResult testDataVersion(String msg){ - Client client = new Client(); - client.setName(msg); - client.setId(1L); - client.setCreateTime(LocalDateTime.now()); - dataVersionLogService.add(new DataVersionLogParam().setDataId(String.valueOf(client.getId())).setDataName("client").setDataContent(client)); - return Res.ok(); - } -} diff --git a/bootx-demo/src/main/java/cn/bootx/demo/controller/lock/IdempotencyDemoController.java b/bootx-demo/src/main/java/cn/bootx/demo/controller/lock/IdempotencyDemoController.java index 077ef5b81779b19eaa25244567ef5544fa44265c..b2c3b68a2036e41fdad0053ddc63b7f8e3438dbe 100644 --- a/bootx-demo/src/main/java/cn/bootx/demo/controller/lock/IdempotencyDemoController.java +++ b/bootx-demo/src/main/java/cn/bootx/demo/controller/lock/IdempotencyDemoController.java @@ -4,11 +4,14 @@ import cn.bootx.common.core.annotation.Idempotent; import cn.bootx.common.core.rest.Res; import cn.bootx.common.core.rest.ResResult; import cn.bootx.common.lock.annotation.Lock; +import cn.bootx.common.lock.annotation.LockKey; +import cn.bootx.common.lock.constant.LockType; import cn.hutool.core.thread.ThreadUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -35,17 +38,19 @@ public class IdempotencyDemoController { } @Operation(summary = "分布式锁(暂停5秒)") - @PostMapping("/lock5") - @Lock(name = "test:lock") - public ResResult lock5(){ + @GetMapping("/lock5") + @Lock(name = "test:lock",lockType = LockType.REENTRANT) + public ResResult lock5(@LockKey Integer a){ + log.info("开始"); ThreadUtil.sleep(5, TimeUnit.SECONDS); + log.info("结束"); return Res.ok(); } @Operation(summary = "分布式锁(暂停20秒)") - @PostMapping("/lock20") + @GetMapping("/lock20") @Lock(name = "test:lock") - public ResResult lock20(){ + public ResResult lock20(@LockKey Integer a){ ThreadUtil.sleep(20, TimeUnit.SECONDS); return Res.ok(); } diff --git a/bootx-demo/src/main/java/cn/bootx/demo/controller/mq/MessageQueueDemoController.java b/bootx-demo/src/main/java/cn/bootx/demo/controller/mq/MessageQueueDemoController.java new file mode 100644 index 0000000000000000000000000000000000000000..cb7932f78387ccc36ef8767ce009f3856e883376 --- /dev/null +++ b/bootx-demo/src/main/java/cn/bootx/demo/controller/mq/MessageQueueDemoController.java @@ -0,0 +1,67 @@ +package cn.bootx.demo.controller.mq; + +import cn.bootx.common.core.rest.Res; +import cn.bootx.common.core.rest.ResResult; +import cn.bootx.common.jackson.util.JacksonUtil; +import cn.bootx.common.redis.RedisClient; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.nio.charset.StandardCharsets; + +/** +* @author xxm +* @date 2022/5/27 +*/ +@Tag(name = "测试消息队列") +@RestController +@RequestMapping("/demo/mq") +@RequiredArgsConstructor +public class MessageQueueDemoController { + private final RabbitTemplate rabbitTemplate; + private final MqttClient mqttClient; + private final RedisClient redisClient; + + @SneakyThrows + @Operation(summary = "发送MQTT消息") + @PostMapping("/sendMqttMsg") + public ResResult sendMqttMsg(String msg){ + String json = JacksonUtil.toJson(Res.ok(msg)); + MqttMessage mqttMessage = new MqttMessage(json.getBytes(StandardCharsets.UTF_8)); + mqttClient.publish("demo",mqttMessage); + return Res.ok(); + } + + @Operation(summary = "发送RabbitMQ消息") + @PostMapping("/sendRabbitMsg") + public ResResult sendRabbitMsg(String msg){ + rabbitTemplate.convertAndSend( + "service.demo", + "demo.testMq", + Res.ok(msg) + ); + return Res.ok(); + } + + @Operation(summary = "发送RedisMq消息") + @PostMapping("/sendRedisMsg") + public ResResult sendRedisMsg(String msg){ + redisClient.convertAndSend("demo:redis", Res.ok(msg)); + return Res.ok(); + } + + @Operation(summary = "创建15秒后过期的事件") + @PostMapping("/sendKeyExpired") + public ResResult sendKeyExpired(String key){ + redisClient.setKeyExpired("demo:redis:expired:",key,15*1000); + return Res.ok(); + } +} diff --git a/bootx-demo/src/main/java/cn/bootx/demo/core/mq/mqtt/DemoMqttConfiguration.java b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/mqtt/DemoMqttConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..cf5615a16e90616869373aaa0e47062a5a3b9892 --- /dev/null +++ b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/mqtt/DemoMqttConfiguration.java @@ -0,0 +1,34 @@ +package cn.bootx.demo.core.mq.mqtt; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.PostConstruct; + +/** +* +* @author xxm +* @date 2022/5/30 +*/ +@Slf4j +@Configuration +@RequiredArgsConstructor +public class DemoMqttConfiguration { + private final MqttClient mqttClient; + private final DemoMqttMessageListener iotMessageListener; + + /** + * 添加监听器 + */ + @PostConstruct + public void listener(){ + try { + mqttClient.subscribe("demo", iotMessageListener); + } catch (MqttException e) { + log.error("MQTT添加监听器失败",e); + } + } +} diff --git a/bootx-demo/src/main/java/cn/bootx/demo/core/mq/mqtt/DemoMqttMessageListener.java b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/mqtt/DemoMqttMessageListener.java new file mode 100644 index 0000000000000000000000000000000000000000..2a240e2d5f55f9e7d302522d00edc34febc0c515 --- /dev/null +++ b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/mqtt/DemoMqttMessageListener.java @@ -0,0 +1,22 @@ +package cn.bootx.demo.core.mq.mqtt; + +import lombok.RequiredArgsConstructor; +import org.eclipse.paho.client.mqttv3.IMqttMessageListener; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.stereotype.Component; + +/** +* mqtt消息接收器 +* @author xxm +* @date 2022/5/30 +*/ +@Component +@RequiredArgsConstructor +public class DemoMqttMessageListener implements IMqttMessageListener { + + + @Override + public void messageArrived(String topic, MqttMessage message) throws Exception { + + } +} diff --git a/bootx-demo/src/main/java/cn/bootx/demo/core/mq/rabbit/DemoRabbitMqConfiguration.java b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/rabbit/DemoRabbitMqConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..1a5f805725c0e597fd6ee461c762dbbcf39d336e --- /dev/null +++ b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/rabbit/DemoRabbitMqConfiguration.java @@ -0,0 +1,35 @@ +package cn.bootx.demo.core.mq.rabbit; + +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.DirectExchange; +import org.springframework.amqp.core.Queue; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** +* 演示RabbitMQ消息队列配置 +* @author xxm +* @date 2022/5/30 +*/ +@Configuration +public class DemoRabbitMqConfiguration { + + /** 测试demo消息队列 */ + @Bean + public Queue demoTestQueue() { + return new Queue("demo.testMq"); + } + /** 交换机 */ + @Bean + public DirectExchange demoExchange() { + return new DirectExchange("service.demo"); + } + /** 绑定测试队列和交换机 */ + @Bean + public Binding bindDemoMq() { + return BindingBuilder.bind(demoTestQueue()) + .to(demoExchange()) + .with("demo.testMq"); + } +} diff --git a/bootx-demo/src/main/java/cn/bootx/demo/core/mq/rabbit/DemoRabbitMqMessageListener.java b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/rabbit/DemoRabbitMqMessageListener.java new file mode 100644 index 0000000000000000000000000000000000000000..bf2bcd3133b42ffd5895167bb0c4898ded188bb8 --- /dev/null +++ b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/rabbit/DemoRabbitMqMessageListener.java @@ -0,0 +1,26 @@ +package cn.bootx.demo.core.mq.rabbit; + +import cn.bootx.common.core.rest.ResResult; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Component; + +/** +* +* @author xxm +* @date 2022/5/30 +*/ +@Slf4j +@Component +@RequiredArgsConstructor +public class DemoRabbitMqMessageListener { + + /** + * 测试MQ消息 + */ + @RabbitListener(queues = "demo.testMq") + public void payCancel(ResResult hello) { + log.info("测试MQ消息 :{}",hello); + } +} diff --git a/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/DemoRedisExpiredListener.java b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/DemoRedisExpiredListener.java new file mode 100644 index 0000000000000000000000000000000000000000..ec364a39b42ac2518734b8b612beddf4c073f7be --- /dev/null +++ b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/DemoRedisExpiredListener.java @@ -0,0 +1,27 @@ +package cn.bootx.demo.core.mq.redis; + +import cn.bootx.common.redis.listener.RedisKeyExpiredListener; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** +* redis过期事件监听 +* @author xxm +* @date 2022/5/30 +*/ +@Slf4j +@Component +@RequiredArgsConstructor +public class DemoRedisExpiredListener implements RedisKeyExpiredListener { + + @Override + public String getPrefixKey() { + return "demo:redis:expired:"; + } + + @Override + public void onMessage(String key) { + log.info("redis过期事件监听演示, key : {}",key); + } +} diff --git a/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/T2TopicListener.java b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/DemoRedisTopicListener.java similarity index 47% rename from bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/T2TopicListener.java rename to bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/DemoRedisTopicListener.java index fda6e354d6243a46aac6eff444aac500b958876a..0c28220530e563dffdff208747f4db1b173665bd 100644 --- a/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/T2TopicListener.java +++ b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/DemoRedisTopicListener.java @@ -1,23 +1,26 @@ package cn.bootx.demo.core.mq.redis; -import cn.bootx.common.core.rest.dto.KeyValue; +import cn.bootx.common.core.rest.ResResult; import cn.bootx.common.redis.listener.RedisTopicListener; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; /** -* 测试消息队列 +* 测试Redis消息队列 * @author xxm * @date 2022/5/7 */ +@Slf4j @Component -public class T2TopicListener implements RedisTopicListener { +public class DemoRedisTopicListener implements RedisTopicListener> { + @Override public String getTopic() { - return "test2"; + return "demo:redis"; } @Override - public void onMessage(KeyValue obj) { - System.out.println(obj); + public void onMessage(ResResult obj) { + log.info("{}",obj); } } diff --git a/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/T1TopicListener.java b/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/T1TopicListener.java deleted file mode 100644 index 320031390beb29fe09039cfded2c785ae10f6fb6..0000000000000000000000000000000000000000 --- a/bootx-demo/src/main/java/cn/bootx/demo/core/mq/redis/T1TopicListener.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.bootx.demo.core.mq.redis; - -import cn.bootx.common.redis.listener.RedisTopicListener; -import org.springframework.stereotype.Component; - -/** -* 测试消息队列 -* @author xxm -* @date 2022/5/7 -*/ -@Component -public class T1TopicListener implements RedisTopicListener { - @Override - public String getTopic() { - return "testt1"; - } - - @Override - public void onMessage(String obj) { - System.out.println(obj); - } -} diff --git a/bootx-demo/src/main/java/cn/bootx/demo/ws/WebSocketDemo.java b/bootx-demo/src/main/java/cn/bootx/demo/ws/WebSocketDemo.java index 00734dd35b1b47a7ec51120090c4b0fa2c53d994..dcac7e6188db11b15a0f72b0a1080f3d3ccc217f 100644 --- a/bootx-demo/src/main/java/cn/bootx/demo/ws/WebSocketDemo.java +++ b/bootx-demo/src/main/java/cn/bootx/demo/ws/WebSocketDemo.java @@ -1,22 +1,26 @@ package cn.bootx.demo.ws; +import cn.bootx.common.websocket.service.WebSocketSessionManager; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.websocket.*; +import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** -* websocket demo -* @author xxm -* @date 2022/3/27 -*/ + * websocket demo + * @author xxm + * @date 2022/3/27 + */ @Slf4j @Component -@ServerEndpoint("/test/ws") +@ServerEndpoint("/test/ws/{userId}") public class WebSocketDemo { - + private final WebSocketSessionManager wsManager = new WebSocketSessionManager(); /** 记录当前在线连接数 */ private static final AtomicInteger onlineCount = new AtomicInteger(0); @@ -24,9 +28,10 @@ public class WebSocketDemo { * 连接建立成功调用的方法 */ @OnOpen - public void onOpen(Session session) { + public void onOpen(@PathParam("userId") Long userId,Session session) { + wsManager.addSession(String.valueOf(userId),session); onlineCount.incrementAndGet(); // 在线数加1 - log.info("有新连接加入:{},当前在线人数为:{}", session.getId(), onlineCount.get()); + log.info("有新连接加入:{},当前在线人数为:{}", userId, onlineCount.get()); } /** @@ -35,34 +40,53 @@ public class WebSocketDemo { @OnClose public void onClose(Session session) { onlineCount.decrementAndGet(); // 在线数减1 - log.info("有一连接关闭:{},当前在线人数为:{}", session.getId(), onlineCount.get()); + String userId = wsManager.getIdBySession(session); + wsManager.removeSession(session); + log.info("有一连接关闭:{},当前在线人数为:{}", userId, onlineCount.get()); } /** * 收到客户端消息后调用的方法 * - * @param message - * 客户端发送过来的消息 + * @param message 客户端发送过来的消息 */ @OnMessage public void onMessage(String message, Session session) { - log.info("服务端收到客户端[{}]的消息:{}", session.getId(), message); - this.sendMessage("Hello, " + message, session); + Long userId = Long.valueOf(wsManager.getIdBySession(session)); + log.info("服务端收到客户端[{}]的消息:{}", userId, message); + this.sendMessage("响应: "+message,userId); } @OnError public void onError(Session session, Throwable error) { - log.error("发生错误"); + log.error("{} 发生错误",session.getId()); error.printStackTrace(); } /** - * 服务端发送消息给客户端 + * 服务端发送消息给客户端(单发) + */ + public void sendMessage(String message, Long userId) { + try { + List sessions = wsManager.getSessionsById(String.valueOf(userId)); + + for (Session session : sessions) { + session.getBasicRemote().sendText(message); + } + } catch (Exception e) { + log.error("服务端发送消息给客户端失败:", e); + } + } + + /** + * 服务端发送消息给客户端(全发) */ - private void sendMessage(String message, Session toSession) { + public void sendMessage(String message) { try { - log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message); - toSession.getBasicRemote().sendText(message); + ArrayList sessions = wsManager.getSessions(); + for (Session session : sessions) { + session.getBasicRemote().sendText(message); + } } catch (Exception e) { log.error("服务端发送消息给客户端失败:", e); } diff --git a/bootx-modules/module-eshop/pom.xml b/bootx-modules/module-eshop/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..2ae9c2d0b0f7c03ee4f8806cda768a3c9efbb461 --- /dev/null +++ b/bootx-modules/module-eshop/pom.xml @@ -0,0 +1,44 @@ + + + + bootx-modules + cn.bootx.platform + 1.1.0-beta-1-SNAPSHOT + + 4.0.0 + + module-eshop + jar + 网上商城 + + + + cn.bootx.platform + service-iam + ${bootx-platform.version} + + + cn.bootx.platform + service-payment + ${bootx-platform.version} + + + cn.bootx.platform + service-goods + ${bootx-platform.version} + + + cn.bootx.platform + service-sales + ${bootx-platform.version} + + + cn.bootx.platform + service-order + ${bootx-platform.version} + + + + \ No newline at end of file diff --git a/bootx-modules/module-eshop/src/main/java/cn/bootx/models/eshop/EshopApplication.java b/bootx-modules/module-eshop/src/main/java/cn/bootx/models/eshop/EshopApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..f33bff7c890c9eab1b293920f921dad916a8d4f4 --- /dev/null +++ b/bootx-modules/module-eshop/src/main/java/cn/bootx/models/eshop/EshopApplication.java @@ -0,0 +1,17 @@ +package cn.bootx.models.eshop; + +import org.apache.ibatis.annotations.Mapper; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.ComponentScan; + +/** +* 网上商城 +* @author xxm +* @date 2022/5/9 +*/ +@ComponentScan +@ConfigurationPropertiesScan +@MapperScan(annotationClass = Mapper.class) +public class EshopApplication { +} diff --git a/bootx-modules/module-eshop/src/main/resources/META-INF/spring.factories b/bootx-modules/module-eshop/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000000000000000000000000000000000..8ca5a5a0cbdbb25cf91d95ba93fc36078a7c3854 --- /dev/null +++ b/bootx-modules/module-eshop/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +## 配置自动化配置 +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + cn.bootx.models.eshop.EshopApplication diff --git a/bootx-modules/pom.xml b/bootx-modules/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..9a16d620ae28647bf4b269fdfc42c80552c1fa3f --- /dev/null +++ b/bootx-modules/pom.xml @@ -0,0 +1,27 @@ + + + + bootx-platform + cn.bootx.platform + 1.1.0-beta-1-SNAPSHOT + + 4.0.0 + + bootx-modules + pom + 解决方案实现 + + module-eshop + + + + + cn.bootx.platform + service-baseapi + ${bootx-platform.version} + + + + \ No newline at end of file diff --git a/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/controller/DictionaryItemController.java b/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/controller/DictionaryItemController.java index 5a0a8c4c736a31e23c88892e29b923f82b1d0bf0..50207ecd3f25a0537807bc44077709136a85db48 100644 --- a/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/controller/DictionaryItemController.java +++ b/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/controller/DictionaryItemController.java @@ -37,13 +37,6 @@ public class DictionaryItemController { return Res.ok(dictionaryItemService.add(param)); } - @Operation( summary = "删除字典项") - @DeleteMapping(value = "/delete") - public ResResult delete(Long id) { - dictionaryItemService.delete(id); - return Res.ok(); - } - @Operation( summary = "修改字典项(返回字典项对象)") @PostMapping(value = "/update") public ResResult update(@RequestBody DictionaryItemParam param) { @@ -51,6 +44,13 @@ public class DictionaryItemController { return Res.ok( dictionaryItemService.update(param)); } + @Operation( summary = "删除字典项") + @DeleteMapping(value = "/delete") + public ResResult delete(Long id) { + dictionaryItemService.delete(id); + return Res.ok(); + } + @Operation( summary = "根据字典项ID查询") @GetMapping("/findById") public ResResult findById(@Parameter(description = "字典项ID")Long id) { diff --git a/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/convert/DictionaryConvert.java b/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/convert/DictionaryConvert.java index b0c46cf6ca79011c174edf69ac6ce9d115c2158c..fbc20c700898e0723fa4ed6bfad88a30e2fc4c49 100644 --- a/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/convert/DictionaryConvert.java +++ b/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/convert/DictionaryConvert.java @@ -19,13 +19,11 @@ import org.mapstruct.factory.Mappers; public interface DictionaryConvert { DictionaryConvert CONVERT = Mappers.getMapper(DictionaryConvert.class); - Dictionary convert(DictionaryDto in); Dictionary convert(DictionaryParam in); DictionaryDto convert(Dictionary in); - DictionaryItem convert(DictionaryItemDto in); DictionaryItem convert(DictionaryItemParam in); diff --git a/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/dao/DictionaryManager.java b/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/dao/DictionaryManager.java index 24a626d4c2daa5522e8e44159966c05c70ab4046..2b91d884f397ea75f293d39e27b38a55c50e4d9f 100644 --- a/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/dao/DictionaryManager.java +++ b/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/dao/DictionaryManager.java @@ -43,7 +43,8 @@ public class DictionaryManager extends BaseManager return lambdaQuery() .orderByDesc(MpBaseEntity::getId) .like(StrUtil.isNotBlank(param.getName()),Dictionary::getName,param.getName()) - .like(StrUtil.isNotBlank(param.getCode()),Dictionary::getCode,param.getCode()) + .like(StrUtil.isNotBlank(param.getName()),Dictionary::getName,param.getName()) + .like(StrUtil.isNotBlank(param.getGroupTag()),Dictionary::getGroupTag,param.getGroupTag()) .page(mpPage); } } diff --git a/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/entity/Dictionary.java b/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/entity/Dictionary.java index fc1d56312f97b7bf3db669c34bd41005b0102936..2a7b2f6b8407f9c74878376c45705af99f9b20ba 100644 --- a/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/entity/Dictionary.java +++ b/bootx-services/service-baseapi/src/main/java/cn/bootx/baseapi/core/dict/entity/Dictionary.java @@ -22,16 +22,15 @@ public class Dictionary extends MpBaseEntity implements EntityBaseFunctionmysql-connector-java runtime - - + - com.baomidou - mybatis-plus-boot-starter + cn.bootx.platform + common-starter-quartz - \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/code/CategoryCode.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/code/CategoryCode.java new file mode 100644 index 0000000000000000000000000000000000000000..f85bbb5b44c74d51a5650fa0b340c0a555f31799 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/code/CategoryCode.java @@ -0,0 +1,21 @@ +package cn.bootx.goods.code; + +/** +* 类目相关常量 +* @author xxm +* @date 2022/5/9 +*/ +public interface CategoryCode { + + /** 根类目 id */ + long ID_ROOT = 0L; + + // 类目层级 + /** 一级类目 */ + int LEVEL_TOP = 1; + /** 中间类目 */ + int LEVEL_MIDDLE = 2; + /** 子孙类目 */ + int LEVEL_CHILD = 3; + +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/BrandController.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/BrandController.java new file mode 100644 index 0000000000000000000000000000000000000000..088fe9eeef7de6aec1db81073ee6bbab79ee28cd --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/BrandController.java @@ -0,0 +1,66 @@ + +package cn.bootx.goods.controller; + +import cn.bootx.common.core.rest.PageResult; +import cn.bootx.common.core.rest.Res; +import cn.bootx.common.core.rest.ResResult; +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.goods.core.category.service.BrandService; +import cn.bootx.goods.dto.category.BrandDto; +import cn.bootx.goods.param.category.BrandParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 品牌 + * @author xxm + * @date 2022-05-09 + */ +@Tag(name ="品牌") +@RestController +@RequestMapping("/brand") +@RequiredArgsConstructor +public class BrandController { + private final BrandService brandService; + + @Operation( summary = "添加") + @PostMapping(value = "/add") + public ResResult add(@RequestBody BrandParam param){ + return Res.ok(brandService.add(param)); + } + + @Operation( summary = "修改") + @PostMapping(value = "/update") + public ResResult update(@RequestBody BrandParam param){ + return Res.ok(brandService.update(param)); + } + + @Operation( summary = "删除") + @DeleteMapping(value = "/delete") + public ResResult delete(Long id){ + brandService.delete(id); + return Res.ok(); + } + + @Operation( summary = "通过ID查询") + @GetMapping(value = "/findById") + public ResResult findById(Long id){ + return Res.ok(brandService.findById(id)); + } + + @Operation( summary = "查询所有") + @GetMapping(value = "/findAll") + public ResResult> findAll(){ + return Res.ok(brandService.findAll()); + } + + @Operation( summary = "分页查询") + @GetMapping(value = "/page") + public ResResult> page(PageParam pageParam, BrandParam brandParam){ + return Res.ok(brandService.page(pageParam,brandParam)); + } +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryController.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryController.java index 9eac8037706b1e1f1153a782d8e05a66f2578e67..ddf687babbba914935b192f209a9e40a31d96397 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryController.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryController.java @@ -2,10 +2,13 @@ package cn.bootx.goods.controller; import cn.bootx.common.core.rest.Res; import cn.bootx.common.core.rest.ResResult; -import cn.bootx.common.core.rest.param.SingleIdParam; +import cn.bootx.common.core.util.ValidationUtil; import cn.bootx.goods.core.category.service.CategoryService; import cn.bootx.goods.dto.category.CategoryDto; import cn.bootx.goods.dto.category.CategoryTreeNode; +import cn.bootx.goods.param.category.CategoryBrandParam; +import cn.bootx.goods.param.category.CategoryParam; +import cn.bootx.goods.param.category.CategorySpecParam; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -27,8 +30,10 @@ public class CategoryController { @Operation(summary = "增加新类目") @PostMapping("/add") - public ResResult addCategory(@RequestBody CategoryDto categoryDto) { - return Res.ok(categoryService.addCategory(categoryDto)); + public ResResult add(@RequestBody CategoryParam categoryParam) { + ValidationUtil.validateParam(categoryParam); + categoryService.add(categoryParam); + return Res.ok(); } @Operation(summary = "更新类目") @@ -38,28 +43,68 @@ public class CategoryController { } @Operation( summary = "获取所有类目") - @GetMapping("/all") + @GetMapping("/findAll") public ResResult> findAll() { return Res.ok(categoryService.findAll()); } + @Operation(summary = "判断类目是否已经存在") + @GetMapping("/existsByName") + public ResResult existsByName(String name){ + return Res.ok(categoryService.existsByName(name)); + } + + @Operation(summary = "判断类目是否已经存在(不包含自身)") + @GetMapping("/existsByNameNotId") + public ResResult existsByName(String name,Long id){ + return Res.ok(categoryService.existsByName(name,id)); + } + @Operation( summary = "获取类目树") - @GetMapping("/tree") + @GetMapping("/findTree") public ResResult> findTree() { return Res.ok(categoryService.findTree()); } @Operation( summary = "通过 id 获取指定类目") - @GetMapping("/id") - public ResResult getCategory(@Parameter(description = "类目 id", required = true) + @GetMapping("/findById") + public ResResult findById(@Parameter(description = "类目 id", required = true) @RequestParam(value = "id") Long id) { - return Res.ok(categoryService.getById(id)); + return Res.ok(categoryService.findById(id)); } @Operation( summary = "通过 id 删除类目") @DeleteMapping("/delete") - public ResResult deleteCategoryById(@RequestBody SingleIdParam param) { - categoryService.deleteById(param.getId()); + public ResResult delete(Long id) { + categoryService.delete(id); + return Res.ok(); + } + + @Operation(summary = "根据类目id查询关联的绑定品牌id集合") + @GetMapping("/findBindBrandIds") + public ResResult> findBindBrandIds(Long categoryId){ + return Res.ok(categoryService.findBindBrandIds(categoryId)); + } + + @Operation(summary = "绑定品牌") + @PostMapping("/bindBrand") + public ResResult bindBrand(@RequestBody CategoryBrandParam param){ + ValidationUtil.validateParam(param); + categoryService.bindBrand(param); + return Res.ok(); + } + + @Operation(summary = "根据类目id查询关联的绑定规格id集合") + @GetMapping("/findBindSpecIds") + public ResResult> findBindSpecIds(Long categoryId){ + return Res.ok(categoryService.findBindSpecIds(categoryId)); + } + + @Operation(summary = "绑定规格") + @PostMapping("/bindSpec") + public ResResult bindSpec(@RequestBody CategorySpecParam param){ + ValidationUtil.validateParam(param); + categoryService.bindSpec(param); return Res.ok(); } } diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryParameterController.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryParameterController.java new file mode 100644 index 0000000000000000000000000000000000000000..1d99d4e9034a76fc51ed537e881ff77ef8aced94 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryParameterController.java @@ -0,0 +1,83 @@ +package cn.bootx.goods.controller; + +import cn.bootx.common.core.rest.PageResult; +import cn.bootx.common.core.rest.Res; +import cn.bootx.common.core.rest.ResResult; +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.core.util.ValidationUtil; +import cn.bootx.common.core.validation.ValidationGroup; +import cn.bootx.goods.core.category.service.CategoryParameterService; +import cn.bootx.goods.dto.category.CategoryParameterDto; +import cn.bootx.goods.param.category.CategoryParameterParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 类目参数 + * @author xxm + * @date 2022-05-09 + */ +@Tag(name ="类目参数") +@RestController +@RequestMapping("/categoryParameter") +@RequiredArgsConstructor +public class CategoryParameterController { + private final CategoryParameterService categoryParameterService; + + @Operation( summary = "添加") + @PostMapping(value = "/add") + public ResResult add(@RequestBody CategoryParameterParam param){ + ValidationUtil.validateParam(param, ValidationGroup.add.class); + return Res.ok(categoryParameterService.add(param)); + } + + @Operation( summary = "修改") + @PostMapping(value = "/update") + public ResResult update(@RequestBody CategoryParameterParam param){ + ValidationUtil.validateParam(param,ValidationGroup.edit.class); + return Res.ok(categoryParameterService.update(param)); + } + + @Operation( summary = "删除") + @DeleteMapping(value = "/delete") + public ResResult delete(Long id){ + categoryParameterService.delete(id); + return Res.ok(); + } + + @Operation( summary = "通过ID查询") + @GetMapping(value = "/findById") + public ResResult findById(Long id){ + return Res.ok(categoryParameterService.findById(id)); + } + + @Operation( summary = "查询所有") + @GetMapping(value = "/findAll") + public ResResult> findAll(){ + return Res.ok(categoryParameterService.findAll()); + } + + @Operation( summary = "分页查询(限定类目和分组id)") + @GetMapping(value = "/page") + public ResResult> page(PageParam pageParam, CategoryParameterParam categoryParameterParam){ + ValidationUtil.validateParam(categoryParameterParam,ValidationGroup.query.class); + return Res.ok(categoryParameterService.page(pageParam,categoryParameterParam)); + } + + @Operation(summary = "判断类目参数是否已经存在") + @GetMapping("/existsByName") + public ResResult existsByName(String name,Long groupId){ + return Res.ok(categoryParameterService.existsByName(name,groupId)); + } + + @Operation(summary = "判断类目参数是否已经存在(不包含自身)") + @GetMapping("/existsByNameNotId") + public ResResult existsByName(String name,Long groupId,Long id){ + return Res.ok(categoryParameterService.existsByName(name,groupId,id)); + } + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryParameterGroupController.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryParameterGroupController.java new file mode 100644 index 0000000000000000000000000000000000000000..c81f9f737e9ae97d71dc636db4fc38ee3cb3d269 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/CategoryParameterGroupController.java @@ -0,0 +1,78 @@ +package cn.bootx.goods.controller; + +import cn.bootx.common.core.rest.PageResult; +import cn.bootx.common.core.rest.Res; +import cn.bootx.common.core.rest.ResResult; +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.goods.core.category.service.CategoryParameterGroupService; +import cn.bootx.goods.dto.category.CategoryParameterGroupDto; +import cn.bootx.goods.param.category.CategoryParameterGroupParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 类目参数组 + * @author xxm + * @date 2022-05-09 + */ +@Tag(name ="类目参数组") +@RestController +@RequestMapping("/categoryParameterGroup") +@RequiredArgsConstructor +public class CategoryParameterGroupController { + private final CategoryParameterGroupService categoryParameterGroupService; + + @Operation( summary = "添加") + @PostMapping(value = "/add") + public ResResult add(@RequestBody CategoryParameterGroupParam param){ + return Res.ok(categoryParameterGroupService.add(param)); + } + + @Operation( summary = "修改") + @PostMapping(value = "/update") + public ResResult update(@RequestBody CategoryParameterGroupParam param){ + return Res.ok(categoryParameterGroupService.update(param)); + } + + @Operation( summary = "删除") + @DeleteMapping(value = "/delete") + public ResResult delete(Long id){ + categoryParameterGroupService.delete(id); + return Res.ok(); + } + + @Operation( summary = "通过ID查询") + @GetMapping(value = "/findById") + public ResResult findById(Long id){ + return Res.ok(categoryParameterGroupService.findById(id)); + } + + @Operation( summary = "查询所有") + @GetMapping(value = "/findAll") + public ResResult> findAll(){ + return Res.ok(categoryParameterGroupService.findAll()); + } + + @Operation( summary = "分页查询") + @GetMapping(value = "/page") + public ResResult> page(PageParam pageParam, CategoryParameterGroupParam categoryParameterGroupParam){ + return Res.ok(categoryParameterGroupService.page(pageParam,categoryParameterGroupParam)); + } + + @Operation(summary = "判断类目参数组是否已经存在") + @GetMapping("/existsByName") + public ResResult existsByName(String name,Long categoryId){ + return Res.ok(categoryParameterGroupService.existsByName(name,categoryId)); + } + + @Operation(summary = "判断类目参数组是否已经存在(不包含自身)") + @GetMapping("/existsByNameNotId") + public ResResult existsByName(String name,Long categoryId,Long id){ + return Res.ok(categoryParameterGroupService.existsByName(name,categoryId,id)); + } + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/GoodsController.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/GoodsController.java index 9af783b1e5847e96fe7c2166af1b7404291f9d78..f6f6eee3f4f2552f69435e2b036ef382b8ef563f 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/GoodsController.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/GoodsController.java @@ -1,12 +1,14 @@ package cn.bootx.goods.controller; +import cn.bootx.common.core.rest.PageResult; import cn.bootx.common.core.rest.Res; import cn.bootx.common.core.rest.ResResult; +import cn.bootx.common.core.rest.param.PageParam; import cn.bootx.goods.core.goods.service.GoodsService; import cn.bootx.goods.dto.goods.GoodsDto; import cn.bootx.goods.param.goods.GoodsParam; -import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -21,8 +23,9 @@ public class GoodsController{ @Operation(summary = "添加商品") @PostMapping("/add") - public ResResult add(@RequestBody GoodsParam param){ - return Res.ok(goodsService.add(param)); + public ResResult add(@RequestBody GoodsParam param){ + goodsService.add(param); + return Res.ok(); } @Operation(summary = "查询全部") @@ -31,6 +34,12 @@ public class GoodsController{ return Res.ok(goodsService.findAll()); } + @Operation(summary = "分页") + @GetMapping("/page") + public ResResult> page(PageParam param, GoodsParam query){ + return Res.ok(goodsService.page(param,query)); + } + @Operation(summary = "查询包含sku的详情") @GetMapping("/getDetails") public ResResult getDetails(Long id){ diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/SpecificationController.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/SpecificationController.java new file mode 100644 index 0000000000000000000000000000000000000000..a8f45b5fae65578e1fe13bfe4440b0bebd08175c --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/controller/SpecificationController.java @@ -0,0 +1,66 @@ +package cn.bootx.goods.controller; + +import cn.bootx.common.core.rest.PageResult; +import cn.bootx.common.core.rest.Res; +import cn.bootx.common.core.rest.ResResult; +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.goods.core.category.service.SpecificationService; +import cn.bootx.goods.dto.category.SpecificationDto; +import cn.bootx.goods.param.category.SpecificationParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 规格 + * @author xxm + * @date 2022-05-09 + */ +@Tag(name ="规格") +@RestController +@RequestMapping("/specification") +@RequiredArgsConstructor +public class SpecificationController { + private final SpecificationService specificationService; + + @Operation( summary = "添加") + @PostMapping(value = "/add") + public ResResult add(@RequestBody SpecificationParam param){ + specificationService.add(param); + return Res.ok(); + } + + @Operation( summary = "修改") + @PostMapping(value = "/update") + public ResResult update(@RequestBody SpecificationParam param){ + return Res.ok(specificationService.update(param)); + } + + @Operation( summary = "删除") + @DeleteMapping(value = "/delete") + public ResResult delete(Long id){ + specificationService.delete(id); + return Res.ok(); + } + + @Operation( summary = "通过ID查询") + @GetMapping(value = "/findById") + public ResResult findById(Long id){ + return Res.ok(specificationService.findById(id)); + } + + @Operation( summary = "查询所有") + @GetMapping(value = "/findAll") + public ResResult> findAll(){ + return Res.ok(specificationService.findAll()); + } + + @Operation( summary = "分页查询") + @GetMapping(value = "/page") + public ResResult> page(PageParam pageParam, SpecificationParam specificationParam){ + return Res.ok(specificationService.page(pageParam,specificationParam)); + } +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/BrandConvert.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/BrandConvert.java new file mode 100644 index 0000000000000000000000000000000000000000..aa7604963893792b5eee29cc2b549acbfd54665e --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/BrandConvert.java @@ -0,0 +1,22 @@ +package cn.bootx.goods.core.category.convert; + +import cn.bootx.goods.core.category.entity.Brand; +import cn.bootx.goods.dto.category.BrandDto; +import cn.bootx.goods.param.category.BrandParam; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 品牌 + * @author xxm + * @date 2022-05-09 + */ +@Mapper +public interface BrandConvert { + BrandConvert CONVERT = Mappers.getMapper(BrandConvert.class); + + Brand convert(BrandParam in); + + BrandDto convert(Brand in); + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryConvert.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryConvert.java index 259a2a6bca34881ba8aa7afff1a3558812672605..b6351621806c117acf741ca9fbe287be00414335 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryConvert.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryConvert.java @@ -12,6 +12,4 @@ public interface CategoryConvert { CategoryDto convert(Category in); Category convert(CategoryParam in); - - Category convert(CategoryDto in); } diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryParameterConvert.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryParameterConvert.java new file mode 100644 index 0000000000000000000000000000000000000000..b71219821b43d011f16b4d2d831d71a0ccd0c85b --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryParameterConvert.java @@ -0,0 +1,22 @@ +package cn.bootx.goods.core.category.convert; + +import cn.bootx.goods.core.category.entity.CategoryParameter; +import cn.bootx.goods.dto.category.CategoryParameterDto; +import cn.bootx.goods.param.category.CategoryParameterParam; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 类目参数 + * @author xxm + * @date 2022-05-09 + */ +@Mapper +public interface CategoryParameterConvert { + CategoryParameterConvert CONVERT = Mappers.getMapper(CategoryParameterConvert.class); + + CategoryParameter convert(CategoryParameterParam in); + + CategoryParameterDto convert(CategoryParameter in); + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryParameterGroupConvert.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryParameterGroupConvert.java new file mode 100644 index 0000000000000000000000000000000000000000..ba35f682173c0e0b7d434994406c91b1ec2081d7 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/CategoryParameterGroupConvert.java @@ -0,0 +1,22 @@ +package cn.bootx.goods.core.category.convert; + +import cn.bootx.goods.core.category.entity.CategoryParameterGroup; +import cn.bootx.goods.dto.category.CategoryParameterGroupDto; +import cn.bootx.goods.param.category.CategoryParameterGroupParam; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 类目参数组 + * @author xxm + * @date 2022-05-09 + */ +@Mapper +public interface CategoryParameterGroupConvert { + CategoryParameterGroupConvert CONVERT = Mappers.getMapper(CategoryParameterGroupConvert.class); + + CategoryParameterGroup convert(CategoryParameterGroupParam in); + + CategoryParameterGroupDto convert(CategoryParameterGroup in); + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/SpecificationConvert.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/SpecificationConvert.java new file mode 100644 index 0000000000000000000000000000000000000000..493e0deb87d995e76e961ce131abd975578621bf --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/convert/SpecificationConvert.java @@ -0,0 +1,22 @@ +package cn.bootx.goods.core.category.convert; + +import cn.bootx.goods.core.category.entity.Specification; +import cn.bootx.goods.dto.category.SpecificationDto; +import cn.bootx.goods.param.category.SpecificationParam; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 规格 + * @author xxm + * @date 2022-05-09 + */ +@Mapper +public interface SpecificationConvert { + SpecificationConvert CONVERT = Mappers.getMapper(SpecificationConvert.class); + + Specification convert(SpecificationParam in); + + SpecificationDto convert(Specification in); + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/BrandManager.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/BrandManager.java new file mode 100644 index 0000000000000000000000000000000000000000..8dcb39add1c3a8ef9cee79ddbb05d38e8c055709 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/BrandManager.java @@ -0,0 +1,30 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.common.mybatisplus.impl.BaseManager; +import cn.bootx.common.mybatisplus.util.MpUtil; +import cn.bootx.goods.core.category.entity.Brand; +import cn.bootx.goods.param.category.BrandParam; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +/** + * 品牌 + * @author xxm + * @date 2022-05-09 + */ +@Repository +@RequiredArgsConstructor +public class BrandManager extends BaseManager { + private final BrandMapper mapper; + + /** + * 分页 + */ + public Page page(PageParam pageParam, BrandParam param) { + Page mpPage = MpUtil.getMpPage(pageParam, Brand.class); + return lambdaQuery().orderByDesc(MpBaseEntity::getId).page(mpPage); + } +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/BrandMapper.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/BrandMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..b28500c7bde713eda0c0c35c0baf926504c1e70e --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/BrandMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.goods.core.category.entity.Brand; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 品牌 + * @author xxm + * @date 2022-05-09 + */ +@Mapper +public interface BrandMapper extends BaseMapper { +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryBrandManager.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryBrandManager.java new file mode 100644 index 0000000000000000000000000000000000000000..78ac2a6868178206e38793d813e1e9e47358c227 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryBrandManager.java @@ -0,0 +1,28 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.common.mybatisplus.impl.BaseManager; +import cn.bootx.goods.core.category.entity.CategoryBrand; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** +* +* @author xxm +* @date 2022/5/9 +*/ +@Slf4j +@Repository +@RequiredArgsConstructor +public class CategoryBrandManager extends BaseManager { + + public List findAllByCategoryId(Long categoryId) { + return findAllByField(CategoryBrand::getCategoryId,categoryId); + } + + public void deleteByCategoryId(Long categoryId){ + deleteByField(CategoryBrand::getCategoryId,categoryId); + } +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryBrandMapper.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryBrandMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..c1f252c117dc9b991dee4cd751fad300120849aa --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryBrandMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.goods.core.category.entity.CategoryBrand; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* +* @author xxm +* @date 2022/5/9 +*/ +@Mapper +public interface CategoryBrandMapper extends BaseMapper { +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryManager.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryManager.java index 073f6387c3e601c83a705169c9d002f8cb4b1da6..182320bf5878297a8d619d5b8bd5896413ca872b 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryManager.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryManager.java @@ -16,6 +16,10 @@ import org.springframework.stereotype.Repository; @RequiredArgsConstructor public class CategoryManager extends BaseManager { + public boolean existedByChildren(Long id) { + return existedByField(Category::getPid,id); + } + public boolean existsName(String name) { return existedByField(Category::getName,name); } diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterGroupManager.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterGroupManager.java new file mode 100644 index 0000000000000000000000000000000000000000..216c0ce5ffb8152c5a58ef687d07afd00ddbf9c1 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterGroupManager.java @@ -0,0 +1,53 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.common.mybatisplus.impl.BaseManager; +import cn.bootx.common.mybatisplus.util.MpUtil; +import cn.bootx.goods.core.category.entity.CategoryParameterGroup; +import cn.bootx.goods.param.category.CategoryParameterGroupParam; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +/** + * 类目参数组 + * @author xxm + * @date 2022-05-09 + */ +@Repository +@RequiredArgsConstructor +public class CategoryParameterGroupManager extends BaseManager { + private final CategoryParameterGroupMapper mapper; + + /** + * 分页 + */ + public Page page(PageParam pageParam, CategoryParameterGroupParam param) { + Page mpPage = MpUtil.getMpPage(pageParam, CategoryParameterGroup.class); + return lambdaQuery() + .eq(CategoryParameterGroup::getCategoryId,param.getCategoryId()) + .orderByDesc(MpBaseEntity::getId) + .page(mpPage); + } + + /** + * 名称是否存在 + */ + public boolean existedByName(String name,Long categoryId){ + return this.lambdaQuery() + .eq(CategoryParameterGroup::getName,name) + .eq(CategoryParameterGroup::getCategoryId,categoryId) + .exists(); + } + /** + * 名称是否存在 + */ + public boolean existedByName(String name,Long categoryId,Long id){ + return this.lambdaQuery() + .eq(CategoryParameterGroup::getName,name) + .eq(CategoryParameterGroup::getCategoryId,categoryId) + .ne(CategoryParameterGroup::getId,id) + .exists(); + } +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterGroupMapper.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterGroupMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..440f10d7feea33d162eb6be8590acc4eec6155e5 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterGroupMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.goods.core.category.entity.CategoryParameterGroup; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 类目参数组 + * @author xxm + * @date 2022-05-09 + */ +@Mapper +public interface CategoryParameterGroupMapper extends BaseMapper { +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterManager.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterManager.java new file mode 100644 index 0000000000000000000000000000000000000000..ba1600c6b0ae0c693b36f6494c0e33254b522a09 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterManager.java @@ -0,0 +1,54 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.common.mybatisplus.impl.BaseManager; +import cn.bootx.common.mybatisplus.util.MpUtil; +import cn.bootx.goods.core.category.entity.CategoryParameter; +import cn.bootx.goods.param.category.CategoryParameterParam; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +/** + * 类目参数 + * @author xxm + * @date 2022-05-09 + */ +@Repository +@RequiredArgsConstructor +public class CategoryParameterManager extends BaseManager { + private final CategoryParameterMapper mapper; + + /** + * 分页 + */ + public Page page(PageParam pageParam, CategoryParameterParam param) { + Page mpPage = MpUtil.getMpPage(pageParam, CategoryParameter.class); + return lambdaQuery() + .eq(CategoryParameter::getCategoryId,param.getCategoryId()) + .eq(CategoryParameter::getGroupId,param.getGroupId()) + .orderByDesc(MpBaseEntity::getId) + .page(mpPage); + } + + /** + * 名称是否存在 + */ + public boolean existedByName(String name,Long groupId){ + return this.lambdaQuery() + .eq(CategoryParameter::getName,name) + .eq(CategoryParameter::getGroupId,groupId) + .exists(); + } + /** + * 名称是否存在 + */ + public boolean existedByName(String name,Long groupId,Long id){ + return this.lambdaQuery() + .eq(CategoryParameter::getName,name) + .eq(CategoryParameter::getGroupId,groupId) + .ne(CategoryParameter::getId,id) + .exists(); + } +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterMapper.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..808327b81456cc6ebe733941cb32f2b3c8dadb18 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategoryParameterMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.goods.core.category.entity.CategoryParameter; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 类目参数 + * @author xxm + * @date 2022-05-09 + */ +@Mapper +public interface CategoryParameterMapper extends BaseMapper { +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategorySpecificationManager.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategorySpecificationManager.java new file mode 100644 index 0000000000000000000000000000000000000000..ea9a34516d16cb301a15cdd5241ba8531d8a92f5 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategorySpecificationManager.java @@ -0,0 +1,28 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.common.mybatisplus.impl.BaseManager; +import cn.bootx.goods.core.category.entity.CategorySpecification; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** +* +* @author xxm +* @date 2022/5/13 +*/ +@Slf4j +@Repository +@RequiredArgsConstructor +public class CategorySpecificationManager extends BaseManager { + + public List findAllByCategoryId(Long categoryId) { + return findAllByField(CategorySpecification::getCategoryId,categoryId); + } + + public void deleteByCategoryId(Long categoryId){ + deleteByField(CategorySpecification::getCategoryId,categoryId); + } +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategorySpecificationMapper.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategorySpecificationMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..2bab2c82b2463020e14ea49d15c1d8eb13a996be --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/CategorySpecificationMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.goods.core.category.entity.CategorySpecification; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* +* @author xxm +* @date 2022/5/13 +*/ +@Mapper +public interface CategorySpecificationMapper extends BaseMapper { +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/SpecificationManager.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/SpecificationManager.java new file mode 100644 index 0000000000000000000000000000000000000000..1e5c90418883bac9ae6ed58d34cbcae10bccfc64 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/SpecificationManager.java @@ -0,0 +1,30 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.common.mybatisplus.impl.BaseManager; +import cn.bootx.common.mybatisplus.util.MpUtil; +import cn.bootx.goods.core.category.entity.Specification; +import cn.bootx.goods.param.category.SpecificationParam; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +/** + * 规格 + * @author xxm + * @date 2022-05-09 + */ +@Repository +@RequiredArgsConstructor +public class SpecificationManager extends BaseManager { + private final SpecificationMapper mapper; + + /** + * 分页 + */ + public Page page(PageParam pageParam, SpecificationParam param) { + Page mpPage = MpUtil.getMpPage(pageParam, Specification.class); + return lambdaQuery().orderByDesc(MpBaseEntity::getId).page(mpPage); + } +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/SpecificationMapper.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/SpecificationMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..16f2f68e7b723dccd6195c8fabfae8773e1e967a --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/dao/SpecificationMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.goods.core.category.dao; + +import cn.bootx.goods.core.category.entity.Specification; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 规格 + * @author xxm + * @date 2022-05-09 + */ +@Mapper +public interface SpecificationMapper extends BaseMapper { +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Brand.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Brand.java new file mode 100644 index 0000000000000000000000000000000000000000..14b8cc546cfcecf17ca88ac432bcc1ffa33b2e1f --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Brand.java @@ -0,0 +1,43 @@ +package cn.bootx.goods.core.category.entity; + +import cn.bootx.common.core.function.EntityBaseFunction; +import cn.bootx.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.goods.core.category.convert.BrandConvert; +import cn.bootx.goods.dto.category.BrandDto; +import cn.bootx.goods.param.category.BrandParam; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** +* 品牌 +* @author xxm +* @date 2022-05-09 +*/ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("gc_brand") +@Accessors(chain = true) +public class Brand extends MpBaseEntity implements EntityBaseFunction{ + + /** 品牌名称 */ + private String name; + /** 品牌图标 */ + private String logo; + /** 状态 */ + private Boolean enable; + /** 描述 */ + private String remark; + + /** 创建对象 */ + public static Brand init(BrandParam in) { + return BrandConvert.CONVERT.convert(in); + } + + /** 转换成dto */ + @Override + public BrandDto toDto() { + return BrandConvert.CONVERT.convert(this); + } +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Category.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Category.java index eba2163d5f6d2fdbeacccbe1bfc14f6d62bfa584..ff82a51b7107906447f42cb035cb3373fbe0ba03 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Category.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Category.java @@ -21,7 +21,6 @@ import lombok.experimental.Accessors; @TableName("gc_category") @Accessors(chain = true) public class Category extends MpBaseEntity implements EntityBaseFunction { - private static final long serialVersionUID = -3604408346443111551L; /** 上级类目id */ @@ -29,16 +28,15 @@ public class Category extends MpBaseEntity implements EntityBaseFunction{ + + /** 参数名称 */ + private String name; + /** 类型 */ + private String type; + /** 选择值(列表) */ + @TableField(typeHandler= JacksonTypeHandler.class) + private List options; + /** 是否必填 */ + private Boolean required; + /** 排序 */ + private Double sortNo; + /** 参数组id */ + private Long groupId; + /** 类目id */ + private Long categoryId; + /** 描述 */ + private String remark; + + /** 创建对象 */ + public static CategoryParameter init(CategoryParameterParam in) { + return CategoryParameterConvert.CONVERT.convert(in); + } + + /** 转换成dto */ + @Override + public CategoryParameterDto toDto() { + return CategoryParameterConvert.CONVERT.convert(this); + } +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/CategoryParameterGroup.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/CategoryParameterGroup.java new file mode 100644 index 0000000000000000000000000000000000000000..dbb0474f6242202455d3724cd3e373d7b582e6d3 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/CategoryParameterGroup.java @@ -0,0 +1,43 @@ +package cn.bootx.goods.core.category.entity; + +import cn.bootx.common.core.function.EntityBaseFunction; +import cn.bootx.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.goods.core.category.convert.CategoryParameterGroupConvert; +import cn.bootx.goods.dto.category.CategoryParameterGroupDto; +import cn.bootx.goods.param.category.CategoryParameterGroupParam; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** +* 类目参数组 +* @author xxm +* @date 2022-05-09 +*/ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("gc_category_parameter_group") +@Accessors(chain = true) +public class CategoryParameterGroup extends MpBaseEntity implements EntityBaseFunction{ + + /** 参数组名称 */ + private String name; + /** 排序 */ + private Double sortNo; + /** 类目id */ + private Long categoryId; + /** 描述 */ + private String remark; + + /** 创建对象 */ + public static CategoryParameterGroup init(CategoryParameterGroupParam in) { + return CategoryParameterGroupConvert.CONVERT.convert(in); + } + + /** 转换成dto */ + @Override + public CategoryParameterGroupDto toDto() { + return CategoryParameterGroupConvert.CONVERT.convert(this); + } +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/CategorySpecification.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/CategorySpecification.java new file mode 100644 index 0000000000000000000000000000000000000000..d273d19fbc123b1d078b669ee1f37443956e7381 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/CategorySpecification.java @@ -0,0 +1,25 @@ +package cn.bootx.goods.core.category.entity; + +import cn.bootx.common.mybatisplus.base.MpIdEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 商品分类规格 + * @author xxm + * @date 2022/5/9 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@TableName("gc_category_specification") +public class CategorySpecification extends MpIdEntity { + + /** 类目id */ + private Long categoryId; + + /** 规格id */ + private Long specificationId; +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Specification.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Specification.java new file mode 100644 index 0000000000000000000000000000000000000000..31b8df36728aa800c104060eba476dea2620a3c3 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/entity/Specification.java @@ -0,0 +1,57 @@ +package cn.bootx.goods.core.category.entity; + +import cn.bootx.common.core.function.EntityBaseFunction; +import cn.bootx.common.mybatisplus.base.MpBaseEntity; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import cn.bootx.goods.dto.category.SpecificationDto; +import cn.bootx.goods.param.category.SpecificationParam; +import cn.bootx.goods.core.category.convert.SpecificationConvert; + + +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.util.List; + + +/** + * 规格 + * @author xxm + * @date 2022-05-09 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@TableName(value = "gc_specification",autoResultMap = true) +public class Specification extends MpBaseEntity implements EntityBaseFunction{ + + /** 规格名称 */ + private String name; + + /** 规格类型(文本/列表选择) */ + private String type; + + /** 规格值(列表) */ + @TableField(typeHandler= JacksonTypeHandler.class) + private List options; + + /** 状态 */ + private String state; + + /** 描述 */ + private String remark; + + /** 创建对象 */ + public static Specification init(SpecificationParam in) { + return SpecificationConvert.CONVERT.convert(in); + } + + /** 转换成dto */ + @Override + public SpecificationDto toDto() { + return SpecificationConvert.CONVERT.convert(this); + } +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/handler/ValueDisplayPair.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/handler/ValueDisplayPair.java deleted file mode 100644 index cce0c80562e28aac3dca03457446605dd57e7502..0000000000000000000000000000000000000000 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/handler/ValueDisplayPair.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.bootx.goods.core.category.handler; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -/** -* 值显示对 -* @author xxm -* @date 2020/11/21 -*/ -@Data -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -public class ValueDisplayPair { - private String value; - private String display; - -} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/BrandService.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/BrandService.java new file mode 100644 index 0000000000000000000000000000000000000000..93b5deaf00ec2e413ba5d842810c80d738e82fa7 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/BrandService.java @@ -0,0 +1,77 @@ +package cn.bootx.goods.core.category.service; + +import cn.bootx.common.core.exception.DataNotExistException; +import cn.bootx.common.core.rest.PageResult; +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.core.util.ResultConvertUtil; +import cn.bootx.common.mybatisplus.util.MpUtil; +import cn.bootx.goods.core.category.dao.BrandManager; +import cn.bootx.goods.core.category.entity.Brand; +import cn.bootx.goods.dto.category.BrandDto; +import cn.bootx.goods.param.category.BrandParam; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 品牌 + * @author xxm + * @date 2022-05-09 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class BrandService { + private final BrandManager brandManager; + + /** + * 添加 + */ + public BrandDto add(BrandParam param){ + Brand brand = Brand.init(param); + return brandManager.save(brand).toDto(); + } + + /** + * 修改 + */ + public BrandDto update(BrandParam param){ + Brand brand = brandManager.findById(param.getId()).orElseThrow(DataNotExistException::new); + + BeanUtil.copyProperties(param,brand, CopyOptions.create().ignoreNullValue()); + return brandManager.updateById(brand).toDto(); + } + + /** + * 分页 + */ + public PageResult page(PageParam pageParam,BrandParam brandParam){ + return MpUtil.convert2DtoPageResult(brandManager.page(pageParam,brandParam)); + } + + /** + * 获取单条 + */ + public BrandDto findById(Long id){ + return brandManager.findById(id).map(Brand::toDto).orElseThrow(DataNotExistException::new); + } + + /** + * 获取全部 + */ + public List findAll(){ + return ResultConvertUtil.dtoListConvert(brandManager.findAll()); + } + + /** + * 删除 + */ + public void delete(Long id){ + brandManager.deleteById(id); + } + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryParameterGroupService.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryParameterGroupService.java new file mode 100644 index 0000000000000000000000000000000000000000..54d67588ed99d535688ed203bbdc76bd837eddde --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryParameterGroupService.java @@ -0,0 +1,90 @@ +package cn.bootx.goods.core.category.service; + +import cn.bootx.common.core.exception.DataNotExistException; +import cn.bootx.common.core.rest.PageResult; +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.core.util.ResultConvertUtil; +import cn.bootx.common.mybatisplus.util.MpUtil; +import cn.bootx.goods.core.category.dao.CategoryParameterGroupManager; +import cn.bootx.goods.core.category.entity.CategoryParameterGroup; +import cn.bootx.goods.dto.category.CategoryParameterGroupDto; +import cn.bootx.goods.param.category.CategoryParameterGroupParam; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 类目参数组 + * @author xxm + * @date 2022-05-09 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class CategoryParameterGroupService { + private final CategoryParameterGroupManager categoryParameterGroupManager; + + /** + * 添加 + */ + public CategoryParameterGroupDto add(CategoryParameterGroupParam param) { + CategoryParameterGroup categoryParameterGroup = CategoryParameterGroup.init(param); + return categoryParameterGroupManager.save(categoryParameterGroup).toDto(); + } + + /** + * 修改 + */ + public CategoryParameterGroupDto update(CategoryParameterGroupParam param) { + CategoryParameterGroup categoryParameterGroup = categoryParameterGroupManager.findById(param.getId()).orElseThrow(DataNotExistException::new); + param.setId(null); + BeanUtil.copyProperties(param, categoryParameterGroup, CopyOptions.create().ignoreNullValue()); + return categoryParameterGroupManager.updateById(categoryParameterGroup).toDto(); + } + + /** + * 分页 + */ + public PageResult page(PageParam pageParam, CategoryParameterGroupParam categoryParameterGroupParam) { + return MpUtil.convert2DtoPageResult(categoryParameterGroupManager.page(pageParam, categoryParameterGroupParam)); + } + + /** + * 获取单条 + */ + public CategoryParameterGroupDto findById(Long id) { + return categoryParameterGroupManager.findById(id).map(CategoryParameterGroup::toDto).orElseThrow(DataNotExistException::new); + } + + /** + * 获取全部 + */ + public List findAll() { + return ResultConvertUtil.dtoListConvert(categoryParameterGroupManager.findAll()); + } + + /** + * 删除 + */ + public void delete(Long id) { + categoryParameterGroupManager.deleteById(id); + } + + /** + * 名称是否存在 + */ + public boolean existsByName(String name, Long categoryId) { + return categoryParameterGroupManager.existedByName(name,categoryId); + } + + /** + * 名称是否存在 + */ + public boolean existsByName(String name, Long categoryId, Long id) { + return categoryParameterGroupManager.existedByName(name,categoryId,id); + } +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryParameterService.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryParameterService.java new file mode 100644 index 0000000000000000000000000000000000000000..5091771a7285eb90ccc88d67899f01bacf214e55 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryParameterService.java @@ -0,0 +1,90 @@ +package cn.bootx.goods.core.category.service; + +import cn.bootx.common.core.exception.DataNotExistException; +import cn.bootx.common.core.rest.PageResult; +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.core.util.ResultConvertUtil; +import cn.bootx.common.mybatisplus.util.MpUtil; +import cn.bootx.goods.core.category.dao.CategoryParameterManager; +import cn.bootx.goods.core.category.entity.CategoryParameter; +import cn.bootx.goods.dto.category.CategoryParameterDto; +import cn.bootx.goods.param.category.CategoryParameterParam; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 类目参数 + * @author xxm + * @date 2022-05-09 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class CategoryParameterService { + private final CategoryParameterManager categoryParameterManager; + + /** + * 添加 + */ + public CategoryParameterDto add(CategoryParameterParam param){ + CategoryParameter categoryParameter = CategoryParameter.init(param); + return categoryParameterManager.save(categoryParameter).toDto(); + } + + /** + * 修改 + */ + public CategoryParameterDto update(CategoryParameterParam param){ + CategoryParameter categoryParameter = categoryParameterManager.findById(param.getId()).orElseThrow(DataNotExistException::new); + + BeanUtil.copyProperties(param,categoryParameter, CopyOptions.create().ignoreNullValue()); + return categoryParameterManager.updateById(categoryParameter).toDto(); + } + + /** + * 分页 + */ + public PageResult page(PageParam pageParam,CategoryParameterParam categoryParameterParam){ + return MpUtil.convert2DtoPageResult(categoryParameterManager.page(pageParam,categoryParameterParam)); + } + + /** + * 获取单条 + */ + public CategoryParameterDto findById(Long id){ + return categoryParameterManager.findById(id).map(CategoryParameter::toDto).orElseThrow(DataNotExistException::new); + } + + /** + * 获取全部 + */ + public List findAll(){ + return ResultConvertUtil.dtoListConvert(categoryParameterManager.findAll()); + } + + /** + * 删除 + */ + public void delete(Long id){ + categoryParameterManager.deleteById(id); + } + + /** + * 名称是否存在 + */ + public boolean existsByName(String name, Long groupId) { + return categoryParameterManager.existedByName(name,groupId); + } + + /** + * 名称是否存在 + */ + public boolean existsByName(String name, Long groupId, Long id) { + return categoryParameterManager.existedByName(name,groupId,id); + } +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryService.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryService.java index c8226b6f3b7aa0a34f61b41df3f64c1e64b52282..db23e21a6ea46f98c3e3704ca80963794ada256b 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryService.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/CategoryService.java @@ -1,46 +1,70 @@ package cn.bootx.goods.core.category.service; +import cn.bootx.common.core.exception.BizException; import cn.bootx.common.core.exception.DataNotExistException; +import cn.bootx.goods.code.CategoryCode; import cn.bootx.goods.core.category.convert.CategoryConvert; +import cn.bootx.goods.core.category.dao.CategoryBrandManager; import cn.bootx.goods.core.category.dao.CategoryManager; +import cn.bootx.goods.core.category.dao.CategorySpecificationManager; import cn.bootx.goods.core.category.entity.Category; -import cn.bootx.goods.core.category.handler.CategoryTreeHandler; +import cn.bootx.goods.core.category.entity.CategoryBrand; +import cn.bootx.goods.core.category.entity.CategorySpecification; +import cn.bootx.goods.core.category.util.CategoryTreeUtil; import cn.bootx.goods.dto.category.CategoryDto; import cn.bootx.goods.dto.category.CategoryTreeNode; import cn.bootx.goods.exception.category.CategoryAlreadyExistedException; import cn.bootx.goods.exception.category.CategoryNotExistedException; +import cn.bootx.goods.param.category.CategoryBrandParam; +import cn.bootx.goods.param.category.CategoryParam; +import cn.bootx.goods.param.category.CategorySpecParam; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.core.collection.CollUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Comparator; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; /** -* 类目 -* @author xxm -* @date 2020/11/19 -*/ + * 类目 + * @author xxm + * @date 2020/11/19 + */ @Slf4j @Service @RequiredArgsConstructor public class CategoryService { private final CategoryManager categoryManager; + private final CategoryBrandManager categoryBrandManager; + private final CategorySpecificationManager categorySpecificationManager; /** * 添加新类目 */ @Transactional(rollbackFor = Exception.class) - public CategoryDto addCategory(CategoryDto categoryDto) { - if (categoryManager.existsName(categoryDto.getName())) { + public void add(CategoryParam param) { + int level = 1; + // 不传pid为根类目 + if (Objects.nonNull(param.getPid())){ + Category category = categoryManager.findById(param.getPid()).orElseThrow(() -> new BizException("父类不存在")); + level = category.getLevel() + 1; + if (level > CategoryCode.LEVEL_CHILD){ + throw new BizException("类目层级最高为三层"); + } + + } + if (categoryManager.existsName(param.getName())) { throw new CategoryAlreadyExistedException(); } - Category convert = CategoryConvert.CONVERT.convert(categoryDto); - Category category = categoryManager.save(convert); - return category.toDto(); + Category category = CategoryConvert.CONVERT.convert(param); + category.setLevel(level); + categoryManager.save(category); } /** @@ -49,6 +73,8 @@ public class CategoryService { @Transactional(rollbackFor = Exception.class) public CategoryDto update(CategoryDto param) { Category category = categoryManager.findById(param.getId()).orElseThrow(CategoryNotExistedException::new); + // pid不可以更新 + param.setPid(null); BeanUtil.copyProperties(param,category, CopyOptions.create().ignoreNullValue()); return categoryManager.updateById(category).toDto(); } @@ -66,7 +92,7 @@ public class CategoryService { /** * 根据 id 获取相应的类目 */ - public CategoryDto getById(Long id){ + public CategoryDto findById(Long id){ return categoryManager.findById(id).map(Category::toDto).orElseThrow(DataNotExistException::new); } @@ -74,14 +100,82 @@ public class CategoryService { * 获取类目树 */ public List findTree() { - List dtos = this.findAll(); - return CategoryTreeHandler.build(dtos); + List categories = categoryManager.findAll().stream() + .sorted(Comparator.comparingDouble(Category::getSortNo)) + .collect(Collectors.toList()); + return CategoryTreeUtil.build(categories); + } + + /** + * 判断类目是否已经存在 + */ + public boolean existsByName(String name) { + return categoryManager.existsName(name); + } + + /** + * 判断类目是否已经存在 + */ + public boolean existsByName(String name, Long id) { + return categoryManager.existsName(name,id); } /** * 根据 id 删除相应的类目 */ - public void deleteById(Long id){ + public void delete(Long id){ + // 判断是否还有子类目 + if (categoryManager.existedByChildren(id)){ + throw new BizException("无法删除, 还有子类目"); + } categoryManager.deleteById(id); } + + /** + * 查询已经绑定的品牌id + */ + public List findBindBrandIds(Long categoryId){ + return categoryBrandManager.findAllByCategoryId(categoryId).stream() + .map(CategoryBrand::getBrandId) + .collect(Collectors.toList()); + } + + /** + * 绑定品牌 + */ + @Transactional(rollbackFor = Exception.class) + public void bindBrand(CategoryBrandParam param){ + // 先删后增 + categoryBrandManager.deleteByCategoryId(param.getCategoryId()); + if (CollUtil.isNotEmpty(param.getBrandIds())){ + List collect = param.getBrandIds().stream() + .map(id -> new CategoryBrand().setCategoryId(param.getCategoryId()).setBrandId(id)) + .collect(Collectors.toList()); + categoryBrandManager.saveAll(collect); + } + } + + /** + * 查询绑定的规格id集合 + */ + public List findBindSpecIds(Long categoryId){ + return categorySpecificationManager.findAllByCategoryId(categoryId).stream() + .map(CategorySpecification::getSpecificationId) + .collect(Collectors.toList()); + } + + /** + * 绑定规格 + */ + @Transactional(rollbackFor = Exception.class) + public void bindSpec(CategorySpecParam param){ + // 删旧增新 + categorySpecificationManager.deleteByCategoryId(param.getCategoryId()); + if (CollUtil.isNotEmpty(param.getSpecIds())) { + List collect = param.getSpecIds().stream() + .map(id -> new CategorySpecification().setCategoryId(param.getCategoryId()).setSpecificationId(id)) + .collect(Collectors.toList()); + categorySpecificationManager.saveAll(collect); + } + } } diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/SpecificationService.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/SpecificationService.java new file mode 100644 index 0000000000000000000000000000000000000000..f1de6ddaf62eae067184bcac91b1d8986840eb90 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/service/SpecificationService.java @@ -0,0 +1,77 @@ +package cn.bootx.goods.core.category.service; + +import cn.bootx.common.core.exception.DataNotExistException; +import cn.bootx.common.core.rest.PageResult; +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.core.util.ResultConvertUtil; +import cn.bootx.common.mybatisplus.util.MpUtil; +import cn.bootx.goods.core.category.dao.SpecificationManager; +import cn.bootx.goods.core.category.entity.Specification; +import cn.bootx.goods.dto.category.SpecificationDto; +import cn.bootx.goods.param.category.SpecificationParam; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 规格 + * @author xxm + * @date 2022-05-09 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class SpecificationService { + private final SpecificationManager specificationManager; + + /** + * 添加 + */ + public void add(SpecificationParam param){ + Specification specification = Specification.init(param); + specificationManager.save(specification); + } + + /** + * 修改 + */ + public SpecificationDto update(SpecificationParam param){ + Specification specification = specificationManager.findById(param.getId()).orElseThrow(DataNotExistException::new); + + BeanUtil.copyProperties(param,specification, CopyOptions.create().ignoreNullValue()); + return specificationManager.updateById(specification).toDto(); + } + + /** + * 分页 + */ + public PageResult page(PageParam pageParam,SpecificationParam specificationParam){ + return MpUtil.convert2DtoPageResult(specificationManager.page(pageParam,specificationParam)); + } + + /** + * 获取单条 + */ + public SpecificationDto findById(Long id){ + return specificationManager.findById(id).map(Specification::toDto).orElseThrow(DataNotExistException::new); + } + + /** + * 获取全部 + */ + public List findAll(){ + return ResultConvertUtil.dtoListConvert(specificationManager.findAll()); + } + + /** + * 删除 + */ + public void delete(Long id){ + specificationManager.deleteById(id); + } + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/handler/CategoryTreeHandler.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/util/CategoryTreeUtil.java similarity index 57% rename from bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/handler/CategoryTreeHandler.java rename to bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/util/CategoryTreeUtil.java index e4b29f464c4cfb13b3abbe8044125c2f4cbec56d..1bbcdd9680c727c015f025ae7aff3f285ce842dd 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/handler/CategoryTreeHandler.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/util/CategoryTreeUtil.java @@ -1,29 +1,30 @@ -package cn.bootx.goods.core.category.handler; +package cn.bootx.goods.core.category.util; -import cn.bootx.goods.dto.category.CategoryDto; +import cn.bootx.goods.core.category.entity.Category; import cn.bootx.goods.dto.category.CategoryTreeNode; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * 类目树构建 * @author xxm * @date 2020/11/20 */ -public class CategoryTreeHandler{ +public class CategoryTreeUtil { /** * 构建类目树 */ - public static List build(List dtos) { + public static List build(List categories) { List tree = new ArrayList<>(); - for (CategoryDto dto : dtos) { + for (Category category : categories) { // 顶级类目 - if (CategoryDto.ID_ROOT == dto.getPid()) { - CategoryTreeNode treeNode = new CategoryTreeNode(dto); - findChildren(treeNode, dtos); + if (Objects.isNull(category.getPid())) { + CategoryTreeNode treeNode = new CategoryTreeNode(category); + findChildren(treeNode, categories); tree.add(treeNode); } } @@ -33,14 +34,14 @@ public class CategoryTreeHandler{ /** * 递归查找子节点 */ - private static void findChildren(CategoryTreeNode treeNode, List dtos) { - for (CategoryDto dto : dtos) { - if (treeNode.getId().equals(dto.getPid())) { + private static void findChildren(CategoryTreeNode treeNode, List categories) { + for (Category category : categories) { + if (Objects.equals(treeNode.getId(),category.getPid())) { if (treeNode.getChildren() == null) { treeNode.setChildren(new ArrayList<>()); } - CategoryTreeNode childNode = new CategoryTreeNode(dto); - findChildren(childNode, dtos); + CategoryTreeNode childNode = new CategoryTreeNode(category); + findChildren(childNode, categories); treeNode.getChildren().add(childNode); } } diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/handler/Descartes.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/util/Descartes.java similarity index 96% rename from bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/handler/Descartes.java rename to bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/util/Descartes.java index 5ad12a280aca5996430004637104e4b846dea487..851cbc5193fa79e0c0272a9b23867fa845a51f58 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/handler/Descartes.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/category/util/Descartes.java @@ -1,4 +1,4 @@ -package cn.bootx.goods.core.category.handler; +package cn.bootx.goods.core.category.util; import java.util.ArrayList; import java.util.List; diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/convert/GoodsConvert.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/convert/GoodsConvert.java index 36fddf7bd6c8948dc0632b82ca2d57cbf43aac2a..bae25a381822891f9e1e4e1f3e6acbdc66fda5f5 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/convert/GoodsConvert.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/convert/GoodsConvert.java @@ -18,7 +18,5 @@ public interface GoodsConvert { Goods convert(GoodsParam in); - Goods convert(GoodsDto in); - GoodsDto convert(Goods in); } diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/dao/GoodsManager.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/dao/GoodsManager.java index 4b63e28004ce3700161aa5903a2f14f7255ded7b..4cb11692c93299b081c6eff037d36bdc12b43de4 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/dao/GoodsManager.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/dao/GoodsManager.java @@ -1,7 +1,12 @@ package cn.bootx.goods.core.goods.dao; +import cn.bootx.common.core.rest.param.PageParam; +import cn.bootx.common.mybatisplus.base.MpIdEntity; import cn.bootx.common.mybatisplus.impl.BaseManager; +import cn.bootx.common.mybatisplus.util.MpUtil; import cn.bootx.goods.core.goods.entity.Goods; +import cn.bootx.goods.param.goods.GoodsParam; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -19,4 +24,14 @@ public class GoodsManager extends BaseManager { public List findByCid(Long cid) { return findAllByField(Goods::getCid,cid); } + + /** + * 分页 + */ + public Page page(PageParam param, GoodsParam query){ + Page mpPage = MpUtil.getMpPage(param, Goods.class); + return this.lambdaQuery() + .orderByDesc(MpIdEntity::getId) + .page(mpPage); + } } diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/Goods.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/Goods.java index b26c1f59d5d399cdd1e74fe4e80dfb2df448380c..449edc35a751b0b4f229c82168759f0c846e339d 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/Goods.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/Goods.java @@ -33,7 +33,7 @@ public class Goods extends MpBaseEntity implements EntityBaseFunction private String name; /** 描述*/ - private String description; + private String remark; /** banner图片 多个图片逗号分隔 */ private String bannerUri; @@ -50,10 +50,6 @@ public class Goods extends MpBaseEntity implements EntityBaseFunction /** 状态(1:可用,0:不可用) */ private int state; - public static Goods init(GoodsDto in){ - return GoodsConvert.CONVERT.convert(in); - } - public static Goods init(GoodsParam in){ return GoodsConvert.CONVERT.convert(in); } diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/GoodsGallery.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/GoodsGallery.java new file mode 100644 index 0000000000000000000000000000000000000000..5a98ed059673dc419f49458c756a96a4ae19cac5 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/GoodsGallery.java @@ -0,0 +1,37 @@ +package cn.bootx.goods.core.goods.entity; + +import cn.bootx.common.mybatisplus.base.MpBaseEntity; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** +* 商品相册 +* @author xxm +* @date 2022/5/9 +*/ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@TableName("gc_goods_gallery") +public class GoodsGallery extends MpBaseEntity { + + /** 商品id */ + private Long goodsId; + + /** 缩略图 */ + private String thumbnail; + + /** 小图 */ + private String small; + + /** 原图 */ + private String original; + + /** 是否主图 */ + private Boolean main; + + /** 排序 */ + private Double sortNo; +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/GoodsWords.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/GoodsWords.java new file mode 100644 index 0000000000000000000000000000000000000000..f1cf56fa9aac6fc397b69d7d03102929b78f6a8a --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/entity/GoodsWords.java @@ -0,0 +1,16 @@ +package cn.bootx.goods.core.goods.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.experimental.Accessors; + +/** +* 商品关键字 +* @author xxm +* @date 2022/5/9 +*/ +@Data +@Accessors(chain = true) +@TableName("gc_goods_words") +public class GoodsWords { +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/service/GoodsService.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/service/GoodsService.java index df71156996e201ffaaea158989e3d1ce35646ffd..15815168c6957e5d44afca8e28b4f7f922d8d7f4 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/service/GoodsService.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/goods/service/GoodsService.java @@ -1,7 +1,10 @@ package cn.bootx.goods.core.goods.service; import cn.bootx.common.core.exception.DataNotExistException; +import cn.bootx.common.core.rest.PageResult; +import cn.bootx.common.core.rest.param.PageParam; import cn.bootx.common.core.util.ResultConvertUtil; +import cn.bootx.common.mybatisplus.util.MpUtil; import cn.bootx.goods.core.goods.dao.GoodsManager; import cn.bootx.goods.core.goods.entity.Goods; import cn.bootx.goods.core.sku.dao.GoodsSkuManager; @@ -27,7 +30,6 @@ public class GoodsService { private final GoodsManager goodsManager; private final GoodsSkuManager goodsSkuManager; - /** * 新增商品 */ @@ -43,6 +45,12 @@ public class GoodsService { return ResultConvertUtil.dtoListConvert(goodsManager.findAll()); } + /** + * 分页 + */ + public PageResult page(PageParam param,GoodsParam query){ + return MpUtil.convert2DtoPageResult(goodsManager.page(param,query)); + } /** * 查询商品详情 diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/service/OperateInventoryService.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/service/OperateInventoryService.java index 3824c9206d4fe1c2450fd1b30a3a9b9e02bfc147..89ead833a425e62cd2b29bd9f6cb31f0acba0b65 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/service/OperateInventoryService.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/service/OperateInventoryService.java @@ -28,7 +28,6 @@ public class OperateInventoryService { /** * 预占指定 SKU 的库存,返回授权码,需要在调用释放或扣减库存API时使用 - * 使用分布式事务 */ @Transactional(rollbackFor = Exception.class) public LockInventoryDto lockInventory(Long skuId, int count) { diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/task/InventoryTask.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/task/InventoryTask.java deleted file mode 100644 index f819ab43566a6e553a106991612f4e0bd6c0dab2..0000000000000000000000000000000000000000 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/task/InventoryTask.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.bootx.goods.core.inventory.task; - -import cn.bootx.common.redis.RedisClient; -import lombok.RequiredArgsConstructor; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.stereotype.Component; - -/** -* 库存定时任务 -* @author xxm -* @date 2021/4/16 -*/ -@EnableScheduling -@Component -@RequiredArgsConstructor -public class InventoryTask { - private final InventoryTaskService inventoryTaskService; - private final RedisClient redisClient; - - // 分布式锁, 保证同一时间只会有一个在执行 - private final String REDIS_LOCK_KEY = "lock:expireInventory"; - /** - * 过期token任务, 释放库存 一分钟执行一次 - */ -// @Scheduled(fixedRate = 1000*60) - public void expireTokensTask(){ - if (redisClient.setIfAbsent(REDIS_LOCK_KEY,"",20*1000)){ - inventoryTaskService.expireTokens(); - } - } - -} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/BrandDto.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/BrandDto.java new file mode 100644 index 0000000000000000000000000000000000000000..23811bdc4f5707ca0be933bf6415c12bf424dad8 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/BrandDto.java @@ -0,0 +1,29 @@ +package cn.bootx.goods.dto.category; + +import cn.bootx.common.core.rest.dto.BaseDto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 品牌 + * @author xxm + * @date 2022-05-09 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Schema(title = "品牌") +@Accessors(chain = true) +public class BrandDto extends BaseDto { + + @Schema(description = "品牌名称") + private String name; + @Schema(description = "品牌图标") + private String logo; + @Schema(description = "是否启用") + private Boolean enable; + @Schema(description = "描述") + private String remark; + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryDto.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryDto.java index c5db89c86a294922f5cc2feecb467ed9f4d3825d..f1e081cb4b5036e41b0930f625f155743ca900ad 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryDto.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryDto.java @@ -1,7 +1,9 @@ package cn.bootx.goods.dto.category; +import cn.bootx.common.core.rest.dto.BaseDto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; @@ -12,17 +14,13 @@ import java.io.Serializable; * @author xxm * @date 2020/11/19 */ +@EqualsAndHashCode(callSuper = true) @Data @Accessors(chain = true) @Schema(title = "类目DTO") -public class CategoryDto implements Serializable { +public class CategoryDto extends BaseDto implements Serializable { private static final long serialVersionUID = -6395120064541083702L; - /** 根类目 id */ - public static final long ID_ROOT = 0L; - - private Long id; - @Schema(description="上级类目id") private Long pid; @@ -30,12 +28,18 @@ public class CategoryDto implements Serializable { private String name; @Schema(description="类目描述") - private String description; + private String remark; + + @Schema(description="是否启用") + private Boolean enable; + + @Schema(description="排序,默认0") + private Double sortNo; - @Schema(description="序号,默认0") - private int ordinal; + @Schema(description= "层级") + private Integer level; - @Schema(description= "是否叶子节点") - private boolean leaf; + @Schema(description= " 图标/图片地址") + private String image; } \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryParameterDto.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryParameterDto.java new file mode 100644 index 0000000000000000000000000000000000000000..f8be6d9b52b210dfe7dd6e5b2bf1f39b332e2735 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryParameterDto.java @@ -0,0 +1,40 @@ +package cn.bootx.goods.dto.category; + +import cn.bootx.common.core.rest.dto.BaseDto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.util.ArrayList; +import java.util.List; + +/** + * 类目参数 + * @author xxm + * @date 2022-05-09 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Schema(title = "类目参数") +@Accessors(chain = true) +public class CategoryParameterDto extends BaseDto { + + @Schema(description = "品牌名称") + private String name; + @Schema(description = "类型") + private String type; + @Schema(description = "选择值(列表)") + private List options = new ArrayList<>(); + @Schema(description = "是否必填") + private Boolean required; + @Schema(description = "排序") + private Double sortNo; + @Schema(description = "参数组id") + private Long groupId; + @Schema(description = "类目id") + private Long categoryId; + @Schema(description = "描述") + private String remark; + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryParameterGroupDto.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryParameterGroupDto.java new file mode 100644 index 0000000000000000000000000000000000000000..8701c87698d7b9536d89d2f40c34c93f2c632ec5 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryParameterGroupDto.java @@ -0,0 +1,29 @@ +package cn.bootx.goods.dto.category; + +import cn.bootx.common.core.rest.dto.BaseDto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 类目参数组 + * @author xxm + * @date 2022-05-09 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Schema(title = "类目参数组") +@Accessors(chain = true) +public class CategoryParameterGroupDto extends BaseDto { + + @Schema(description = "参数组名称") + private String name; + @Schema(description = "排序") + private Double sortNo; + @Schema(description = "类目id") + private Long categoryId; + @Schema(description = "描述") + private String remark; + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryTreeNode.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryTreeNode.java index 9488f2c161855eb9b2048a83eb4fb5b0ff0de12e..9004d0bbb9335563c5601a36d8cb21d655d52670 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryTreeNode.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/CategoryTreeNode.java @@ -1,5 +1,7 @@ package cn.bootx.goods.dto.category; +import cn.bootx.goods.core.category.entity.Category; +import cn.hutool.core.bean.BeanUtil; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.NoArgsConstructor; @@ -22,17 +24,32 @@ import java.util.List; public class CategoryTreeNode implements Serializable { private static final long serialVersionUID = -1587023420309803676L; - @Schema(description= "是否叶节点") - private CategoryDto data; + + @Schema(description="主键") + private Long id; + + @Schema(description="类目名称") + private String name; + + @Schema(description="类目描述") + private String remark; + + @Schema(description="排序,默认0") + private Double sortNo; + + @Schema(description="是否启用") + private Boolean enable; + + @Schema(description= "层级") + private Integer level; + + @Schema(description= " 图标/图片地址") + private String image; @Schema(description="子节点列表") private List children; - public CategoryTreeNode(CategoryDto dto) { - this.data = dto; - } - - public Long getId() { - return data.getId(); + public CategoryTreeNode(Category category) { + BeanUtil.copyProperties(category,this); } } \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/SpecificationDto.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/SpecificationDto.java new file mode 100644 index 0000000000000000000000000000000000000000..f6f75c41dfa84a29a4e0300b58d1c81d4e1df16b --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/category/SpecificationDto.java @@ -0,0 +1,34 @@ +package cn.bootx.goods.dto.category; + +import cn.bootx.common.core.rest.dto.BaseDto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.util.ArrayList; +import java.util.List; + +/** + * 规格 + * @author xxm + * @date 2022-05-09 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Schema(title = "规格") +@Accessors(chain = true) +public class SpecificationDto extends BaseDto { + + @Schema(description = "规格名称") + private String name; + @Schema(description = "类型") + private String type; + @Schema(description = "列表选择值") + private List options = new ArrayList<>(); + @Schema(description = "状态") + private String state; + @Schema(description = "描述") + private String remark; + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/goods/GoodsDto.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/goods/GoodsDto.java index 4b2795c90c24ea8f1145b6a2784eaf84d8350cdb..3eb80bb3aab755d8d2db76d40b9714ccc8091ea5 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/goods/GoodsDto.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/dto/goods/GoodsDto.java @@ -3,7 +3,6 @@ package cn.bootx.goods.dto.goods; import cn.bootx.common.core.rest.dto.BaseDto; import cn.bootx.goods.dto.sku.GoodsSkuDto; import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema;; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @@ -11,6 +10,8 @@ import lombok.experimental.Accessors; import java.io.Serializable; import java.util.List; +; + /** * @author xxm * @date 2020/11/20 @@ -32,7 +33,7 @@ public class GoodsDto extends BaseDto implements Serializable { private String name; @Schema(description= "商品描述") - private String description; + private String remark; /** banner图片 多个图片逗号分隔 */ private String bannerUri; diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/mq/InventoryExpiredListener.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/mq/InventoryExpiredListener.java new file mode 100644 index 0000000000000000000000000000000000000000..c19c9607e84852b787095ce81c9a8b414ea83bff --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/mq/InventoryExpiredListener.java @@ -0,0 +1,27 @@ +package cn.bootx.goods.mq; + +import cn.bootx.common.redis.listener.RedisKeyExpiredListener; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 库存解锁事件 + * @author xxm + * @date 2022/5/9 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class InventoryExpiredListener implements RedisKeyExpiredListener { + + @Override + public String getPrefixKey() { + return "inventory:lock"; + } + + @Override + public void onMessage(String key) { + log.info("过期key: "+key); + } +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/BrandParam.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/BrandParam.java new file mode 100644 index 0000000000000000000000000000000000000000..9b85e32a7483f08f50691526291cf0bdc5aff527 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/BrandParam.java @@ -0,0 +1,28 @@ +package cn.bootx.goods.param.category; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 品牌 + * @author xxm + * @date 2022-05-09 + */ +@Data +@Schema(title = "品牌") +@Accessors(chain = true) +public class BrandParam { + + @Schema(description= "品牌主键") + private Long id; + @Schema(description = "类目名称") + private String name; + @Schema(description = "品牌图标") + private String logo; + @Schema(description = "是否启用") + private Boolean enable; + @Schema(description = "描述") + private String remark; + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryBrandParam.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryBrandParam.java new file mode 100644 index 0000000000000000000000000000000000000000..cf8fdc9ed2b9bd8a6438fb97898481e650811d61 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryBrandParam.java @@ -0,0 +1,26 @@ +package cn.bootx.goods.param.category; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** +* 类目绑定品牌参数 +* @author xxm +* @date 2022/5/13 +*/ +@Data +@Accessors(chain = true) +@Schema(title = "类目绑定品牌参数") +public class CategoryBrandParam { + + @NotNull + @Schema(description = "类目id") + private Long categoryId; + + @Schema(description = "品牌ids") + private List brandIds; +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParam.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParam.java index 5b8dea8ef44a23639e27cb650fe38409200aeb15..ec278bba82655752f19a7c95bae925d5b9b91c8a 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParam.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParam.java @@ -18,21 +18,26 @@ import java.io.Serializable; public class CategoryParam implements Serializable { private static final long serialVersionUID = 88503981680088056L; + + @Schema(description="主键") private Long id; - @Schema(description= "上级类目id") + @Schema(description="上级类目id") private Long pid; - @Schema(description= "类目名称", required = true) + @Schema(description="类目名称", required = true) private String name; @Schema(description="类目描述") - private String description; + private String remark; + + @Schema(description="是否启用") + private Boolean enable; - @Schema(description="序号,默认0") - private int ordinal; + @Schema(description="排序,默认0") + private Double sortNo; - @Schema(description= "是否叶子节点") - private boolean leaf; + @Schema(description= " 图标/图片地址") + private String image; } \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParameterGroupParam.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParameterGroupParam.java new file mode 100644 index 0000000000000000000000000000000000000000..21ac2db1c556647a51a50b559e8ada88b403ca51 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParameterGroupParam.java @@ -0,0 +1,33 @@ +package cn.bootx.goods.param.category; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * 类目参数组 + * @author xxm + * @date 2022-05-09 + */ +@Data +@Schema(title = "类目参数组") +@Accessors(chain = true) +public class CategoryParameterGroupParam { + + @Schema(description= "主键") + private Long id; + @NotEmpty + @Schema(description = "参数组名称") + private String name; + @Schema(description = "排序") + private Double sortNo; + @NotNull + @Schema(description = "类目id") + private Long categoryId; + @Schema(description = "描述") + private String remark; + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParameterParam.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParameterParam.java new file mode 100644 index 0000000000000000000000000000000000000000..74612a99bc503130921df8a2f93574d5cc7b1149 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategoryParameterParam.java @@ -0,0 +1,46 @@ +package cn.bootx.goods.param.category; + +import cn.bootx.common.core.validation.ValidationGroup; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 类目参数 + * @author xxm + * @date 2022-05-09 + */ +@Data +@Schema(title = "类目参数") +@Accessors(chain = true) +public class CategoryParameterParam { + + @NotNull(groups = ValidationGroup.edit.class) + @Schema(description= "主键") + private Long id; + @NotNull(groups = ValidationGroup.add.class) + @Schema(description = "参数名称") + private String name; + @NotEmpty + @Schema(description = "手动输入or列表选择") + private String type; + @Schema(description = "选择值(列表)") + private List options; + @Schema(description = "是否必填") + private Boolean required; + @Schema(description = "排序") + private Double sortNo; + @NotNull + @Schema(description = "参数组id") + private Long groupId; + @NotNull + @Schema(description = "类目id") + private Long categoryId; + @Schema(description = "描述") + private String remark; + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategorySpecParam.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategorySpecParam.java new file mode 100644 index 0000000000000000000000000000000000000000..abdade1220d48b473b4e734cebddfc5cdbc8f927 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/CategorySpecParam.java @@ -0,0 +1,24 @@ +package cn.bootx.goods.param.category; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** +* @author xxm +* @date 2022/5/13 +*/ +@Data +@Accessors(chain = true) +@Schema(title = "类目规格绑定") +public class CategorySpecParam { + @NotNull + @Schema(description = "类目id") + private Long categoryId; + + @Schema(description = "品牌ids") + private List specIds; +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/SpecificationParam.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/SpecificationParam.java new file mode 100644 index 0000000000000000000000000000000000000000..5ec67e28061310469954ec48fd44e2c9ed287711 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/category/SpecificationParam.java @@ -0,0 +1,32 @@ +package cn.bootx.goods.param.category; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 规格 + * @author xxm + * @date 2022-05-09 + */ +@Data +@Schema(title = "规格") +@Accessors(chain = true) +public class SpecificationParam { + + @Schema(description= "主键") + private Long id; + @Schema(description = "规格名称") + private String name; + @Schema(description = "类型") + private String type; + @Schema(description = "列表选择值") + private List options; + @Schema(description = "状态") + private String state; + @Schema(description = "描述") + private String remark; + +} \ No newline at end of file diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/goods/GoodsParam.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/goods/GoodsParam.java index 95c9914a310bff0b89bd5fb5f45ffc583a010cf2..91f1e5604fd74c7bdcdcefd96186bd6f9447f3d2 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/goods/GoodsParam.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/param/goods/GoodsParam.java @@ -1,12 +1,13 @@ package cn.bootx.goods.param.goods; import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema;; import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; +; + /** * @author xxm * @date 2021/2/2 @@ -30,7 +31,7 @@ public class GoodsParam implements Serializable { private String name; @Schema(description= "商品描述") - private String description; + private String remark; @Schema(description= "附加信息") private String addition; diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/task/InventoryTask.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/task/InventoryTask.java new file mode 100644 index 0000000000000000000000000000000000000000..0eb917c5791843631577526070e66e24366d0c71 --- /dev/null +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/task/InventoryTask.java @@ -0,0 +1,22 @@ +package cn.bootx.goods.task; + +import lombok.RequiredArgsConstructor; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.springframework.stereotype.Component; + +/** +* 库存定时任务 +* @author xxm +* @date 2021/4/16 +*/ +@Component +@RequiredArgsConstructor +public class InventoryTask implements Job { + private final InventoryTaskService inventoryTaskService; + + @Override + public void execute(JobExecutionContext context) { + inventoryTaskService.expireTokens(); + } +} diff --git a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/task/InventoryTaskService.java b/bootx-services/service-goods/src/main/java/cn/bootx/goods/task/InventoryTaskService.java similarity index 98% rename from bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/task/InventoryTaskService.java rename to bootx-services/service-goods/src/main/java/cn/bootx/goods/task/InventoryTaskService.java index 3e87a778ab5caa00e10da746fad31cae98f60b50..56bbfc07bb9d9be0956bd8cc11542eafa75e6d95 100644 --- a/bootx-services/service-goods/src/main/java/cn/bootx/goods/core/inventory/task/InventoryTaskService.java +++ b/bootx-services/service-goods/src/main/java/cn/bootx/goods/task/InventoryTaskService.java @@ -1,4 +1,4 @@ -package cn.bootx.goods.core.inventory.task; +package cn.bootx.goods.task; import cn.bootx.goods.core.inventory.dao.InventoryTokenRepository; import cn.bootx.goods.core.inventory.manager.InventoryTokenManager; diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/code/CachingCode.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/code/CachingCode.java index 184be8b12b03a420119292c2f106c36d6a3b48cf..ef6cbc9d69fd05131a92f074c1372622301d1faf 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/code/CachingCode.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/code/CachingCode.java @@ -7,18 +7,12 @@ package cn.bootx.iam.code; */ public interface CachingCode { - /** 请求对应权限缓存 */ - String PERMISSION_PATH = "iam:permission:path"; - - /** 菜单对应权限缓存 */ - String PERMISSION_MENU = "iam:permission:menu"; + /** 直接放行的请求权限 */ + String IGNORE_PATH = "iam:ignore:path"; /** 用户请求权限关系缓存 */ String USER_PATH = "iam:user:path"; - /** 用户菜单权限关系缓存 */ - String USER_MENU = "iam:user:menu"; - /** 用户数据权限关系缓存 */ String USER_DATA_SCOPE = "iam:user:data:scope"; } diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/ClientController.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/ClientController.java index 617d6904bf872ec566bbc084df37250dce0ff95f..5575a92cfce00537ebc8eb5b92e8528bdf555c0a 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/ClientController.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/ClientController.java @@ -66,6 +66,12 @@ public class ClientController { return Res.ok(clientService.findAll()); } + @Operation( summary = "查询有独立菜单和权限的终端列表") + @GetMapping(value = "/findAllByAlonePrem") + public ResResult> findAllByAlonePrem(){ + return Res.ok(clientService.findAllByAlonePrem()); + } + @Operation( summary = "分页查询终端") @GetMapping(value = "/page") public ResResult> page(PageParam pageParam, ClientParam clientParam){ diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/PermMenuController.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/PermMenuController.java index aa830200d83ec8e03584e26d4b470e8dd1658d0a..bdc9fcd9e0d5c83255027e566f807f5532519382 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/PermMenuController.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/PermMenuController.java @@ -39,14 +39,14 @@ public class PermMenuController { @Operation(summary = "获取菜单树") @GetMapping("/menuTree") - public ResResult> menuTree(){ - return Res.ok(rolePermissionService.findMenuTree()); + public ResResult> menuTree(String clientCode){ + return Res.ok(rolePermissionService.findMenuTree(clientCode)); } @Operation(summary = "获取全部树") @GetMapping("/allTree") - public ResResult> allTree(){ - return Res.ok(rolePermissionService.findAllTree()); + public ResResult> allTree(String clientCode){ + return Res.ok(rolePermissionService.findAllTree(clientCode)); } @Operation(summary = "资源列表") diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/RoleMenuController.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/RoleMenuController.java index f52a2f48e0259a74a2f2293faaafb681fca9ed84..334bc05f02d516ffc600a9f931e48e79c9a28d53 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/RoleMenuController.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/controller/RoleMenuController.java @@ -28,26 +28,26 @@ public class RoleMenuController { @Operation(summary = "保存请求权限关系") @PostMapping("/save") public ResResult save(@RequestBody RolePermissionParam param){ - roleMenuService.save(param.getRoleId(),param.getPermissionIds()); + roleMenuService.save(param.getRoleId(),param.getClientCode(),param.getPermissionIds()); return Res.ok(true); } @Operation(summary = "获取权限菜单id列表,不包含资源权限") @GetMapping("/findMenuIds") - public ResResult> findMenuIds(){ - return Res.ok(roleMenuService.findMenuIds()); + public ResResult> findMenuIds(String clientCode){ + return Res.ok(roleMenuService.findMenuIds(clientCode)); } @Operation(summary = "根据角色id获取关联权限id集合(包含资源和菜单)") @GetMapping("/findPermissionIdsByRole") - public ResResult> findPermissionIdsByRole(Long roleId){ - return Res.ok(roleMenuService.findPermissionIdsByRole(roleId)); + public ResResult> findPermissionIdsByRole(Long roleId,String clientCode){ + return Res.ok(roleMenuService.findPermissionIdsByRole(roleId,clientCode)); } @IgnoreAuth @Operation(summary = "获取菜单和资源权限") @GetMapping("/getPermissions") - public ResResult getPermissions(){ - return Res.ok(roleMenuService.getPermissions()); + public ResResult getPermissions(String clientCode){ + return Res.ok(roleMenuService.getPermissions(clientCode)); } } diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/auth/login/PasswordLoginHandler.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/auth/login/PasswordLoginHandler.java index b73ce3b2c0eb55b04e51943d49a78b29096b009f..e62eb89b60dad063ba68f9c831efc6b8fee09c50 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/auth/login/PasswordLoginHandler.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/auth/login/PasswordLoginHandler.java @@ -83,7 +83,7 @@ public class PasswordLoginHandler implements UsernamePasswordAuthentication { // 管理员跳过各种校验 if (!userDetail.isAdmin()) { // 账号状态 - if (!Objects.equals(userDetail.getStatus(), UserStatusCode.LOCK)) { + if (Objects.equals(userDetail.getStatus(), UserStatusCode.LOCK)) { throw new LoginFailureException(username, "密码多次输入错误,已被冻结"); } if (!Objects.equals(userDetail.getStatus(), UserStatusCode.NORMAL)) { diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/client/dao/ClientManager.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/client/dao/ClientManager.java index c123d477fae8e120c6da58b960eb38f2fab410e0..9d923558769b3659f5820659c76ed74843fa1493 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/client/dao/ClientManager.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/client/dao/ClientManager.java @@ -14,6 +14,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; /** @@ -46,6 +47,11 @@ public class ClientManager extends BaseManager { .page(mpPage); } + @Permission(dataScope = false,selectField = false) + public List findAllByAlonePrem(){ + return findAllByField(Client::isAlonePrem,true); + } + /** * 超级查询 */ diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/client/entity/Client.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/client/entity/Client.java index 657875abf607c462cbf4776d355ee0948d19241c..0fe01de0452cf050bde21282e5dbfbd703bab141 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/client/entity/Client.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/client/entity/Client.java @@ -30,6 +30,9 @@ public class Client extends MpBaseEntity implements EntityBaseFunction findAllByAlonePrem(){ + return ResultConvertUtil.dtoListConvert(clientManager.findAllByAlonePrem()); + } + /** * 删除 */ diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/dept/service/DeptUtilService.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/dept/service/DeptUtilService.java index dfd0860bec490b3efe076389522970c45fafcfba..480caaa99eeabeb97ee2157f6307fe66f2d75564 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/dept/service/DeptUtilService.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/dept/service/DeptUtilService.java @@ -6,13 +6,11 @@ import cn.bootx.iam.core.dept.dao.DeptManager; import cn.bootx.iam.core.dept.entity.Dept; import cn.bootx.iam.dto.dept.DeptTreeResult; import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.*; -import java.util.stream.Collectors; /** * 部门规则工具类 @@ -83,22 +81,19 @@ public class DeptUtilService { * 构造部门树状结构 */ public List buildTreeList(List recordList) { - // 查出没有父级的部门 - List collect = recordList.stream() - .filter(dept -> Objects.isNull(dept.getParentId())) - .map(dept -> { - DeptTreeResult deptTreeResult = new DeptTreeResult(); - BeanUtil.copyProperties(dept, deptTreeResult); - return deptTreeResult; - }).collect(Collectors.toList()); - - // 查询子部门 - for (DeptTreeResult dept : collect) { - this.findChildren(dept,recordList); - } // 排序 - collect.sort(Comparator.comparing(DeptTreeResult::getSortNo)); - return collect; + recordList.sort(Comparator.comparing(Dept::getSortNo)); + List tree = new ArrayList<>(); + for (Dept dept : recordList) { + // 查出没有父级的部门 + if (Objects.isNull(dept.getParentId())){ + DeptTreeResult deptTreeResult = new DeptTreeResult(); + BeanUtil.copyProperties(dept, deptTreeResult); + this.findChildren(deptTreeResult,recordList); + tree.add(deptTreeResult); + } + } + return tree; } /** @@ -117,24 +112,5 @@ public class DeptUtilService { treeNode.getChildren().add(childNode); } } - // 排序 - if (CollUtil.isNotEmpty(treeNode.getChildren())){ - treeNode.getChildren().sort(Comparator.comparing(DeptTreeResult::getSortNo)); - } - } - - - /** - * 根据id查找出下属类目的id - * @author xxm - * @date 2020/2/2 18:01 - */ - public static void findChildrenById(Long id, List categories, Set ids){ - for (Dept category : categories) { - if (Objects.equals(category.getParentId(),id)){ - ids.add(category.getId()); - findChildrenById(category.getId(),categories,ids); - } - } } } diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/dao/PermMenuManager.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/dao/PermMenuManager.java index 820e2444a25f9b4043ed84bb89e34a0c7355e14c..271cd5714e78d825ebfaadd1bcc5878bdb73def2 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/dao/PermMenuManager.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/dao/PermMenuManager.java @@ -33,4 +33,9 @@ public class PermMenuManager extends BaseManager { public List findAllByParentId(Long parentId) { return findAllByField(PermMenu::getParentId,parentId); } + + public List findAllByClientCode(String clientCode) { + return findAllByField(PermMenu::getClientCode,clientCode); + } + } diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/dao/PermPathManager.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/dao/PermPathManager.java index 758d478271ccfac9d9214d8cde952d2635ddd4d0..3806c506df19f74a6611e657574037dc0af2b9fa 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/dao/PermPathManager.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/dao/PermPathManager.java @@ -11,6 +11,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; +import java.util.List; + /** * 权限 * @author xxm @@ -31,4 +33,14 @@ public class PermPathManager extends BaseManager { .page(mpPage); } + + /** + * 查询未被启用的请求路径权限 + */ + public List findByNotEnableAndRequestType(String requestType){ + return lambdaQuery() + .eq(PermPath::isEnable,false) + .eq(PermPath::getRequestType,requestType) + .list(); + } } diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/entity/PermMenu.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/entity/PermMenu.java index f4591a02d20831b649d13d703c8ea2f4e88cf8be..879ddc9296a6b1b15539580316b63cd09bbf9847 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/entity/PermMenu.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/entity/PermMenu.java @@ -5,11 +5,14 @@ import cn.bootx.common.mybatisplus.base.MpBaseEntity; import cn.bootx.iam.core.permission.convert.PermConvert; import cn.bootx.iam.dto.permission.PermMenuDto; import cn.bootx.iam.param.permission.PermMenuParam; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; +import static com.baomidou.mybatisplus.annotation.FieldStrategy.IGNORED; + /** * 权限配置 * @author xxm @@ -22,8 +25,12 @@ import lombok.experimental.Accessors; public class PermMenu extends MpBaseEntity implements EntityBaseFunction { /** 父id */ + @TableField(updateStrategy = IGNORED) private Long parentId; + /** 关联终端code */ + private String clientCode; + /** 菜单标题 */ private String title; diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/service/PermMenuService.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/service/PermMenuService.java index 35ddc10d7fac4f9bd95015793b36a80a874130ed..84fb778d904832609c21aa6a1c8b63d5d1b12787 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/service/PermMenuService.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/service/PermMenuService.java @@ -58,15 +58,16 @@ public class PermMenuService { */ @Transactional(rollbackFor = Exception.class) public PermMenuDto update(PermMenuParam param){ - PermMenu permission = permMenuManager.findById(param.getId()) + PermMenu permMenu = permMenuManager.findById(param.getId()) .orElseThrow(() -> new BizException("菜单权限不存在")); - BeanUtil.copyProperties(param,permission, CopyOptions.create().ignoreNullValue()); + permMenu.setClientCode(null); + BeanUtil.copyProperties(param,permMenu, CopyOptions.create().ignoreNullValue()); // 判断是否是一级菜单,是的话清空父菜单ID - if(PermissionCode.MENU_TYPE_TOP.equals(permission.getMenuType())) { - permission.setParentId(null); + if(PermissionCode.MENU_TYPE_TOP.equals(permMenu.getMenuType())) { + permMenu.setParentId(null); } - return permMenuManager.updateById(permission).toDto(); + return permMenuManager.updateById(permMenu).toDto(); } /** @@ -85,6 +86,13 @@ public class PermMenuService { return ResultConvertUtil.dtoListConvert(permMenuManager.findAll()); } + /** + * 列表(根据终端id) + */ + public List findAllByClientCode(String clientCode) { + return ResultConvertUtil.dtoListConvert(permMenuManager.findAllByClientCode(clientCode)); + } + /** * 根据id集合查询 */ diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/service/PermPathService.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/service/PermPathService.java index 4c267fae700e768d26a3e15c699f7a5c066d1459..5b9a20ba67eafff3ea81de5175351607d3c86539 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/service/PermPathService.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/permission/service/PermPathService.java @@ -20,6 +20,7 @@ import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.util.StrUtil; import lombok.AllArgsConstructor; import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -28,6 +29,7 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import static cn.bootx.iam.code.CachingCode.IGNORE_PATH; import static cn.bootx.iam.code.CachingCode.USER_PATH; @@ -55,7 +57,7 @@ public class PermPathService { /** * 更新权限信息 */ - @CacheEvict(value = {USER_PATH},allEntries = true) + @CacheEvict(value = {USER_PATH,IGNORE_PATH},allEntries = true) public PermPathDto update(PermPathParam param){ PermPath permPath = permPathManager.findById(param.getId()) .orElseThrow(() -> new BizException("信息不存在")); @@ -68,13 +70,23 @@ public class PermPathService { /** * 删除 */ - @CacheEvict(value = {USER_PATH},allEntries = true) + @CacheEvict(value = {USER_PATH,IGNORE_PATH},allEntries = true) @Transactional(rollbackFor = Exception.class) public void delete(Long id){ rolePathManager.deleteByPermission(id); permPathManager.deleteById(id); } + /** + * 获取指请求定类型未启用访问控制的请求路径 + */ + @Cacheable(value = {IGNORE_PATH}, key = "#requestType") + public List findIgnorePathByRequestType(String requestType){ + return permPathManager.findByNotEnableAndRequestType(requestType).stream() + .map(PermPath::getPath) + .collect(Collectors.toList()); + } + /** * 获取单条 */ @@ -109,6 +121,7 @@ public class PermPathService { */ @Transactional(rollbackFor = Exception.class) @OperateLog(title = "同步系统请求资源") + @CacheEvict(value = {USER_PATH},allEntries = true) @Async("asyncExecutor") public void syncSystem() { List requestPaths = requestPathService.getRequestPaths(); diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/dao/RoleMenuManager.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/dao/RoleMenuManager.java index 186e4cfd40f768a1f9cd8e625c496b4c77ad1cbb..66152f75558599626ab7dc2810590a203fb372bc 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/dao/RoleMenuManager.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/dao/RoleMenuManager.java @@ -8,11 +8,11 @@ import org.springframework.stereotype.Repository; import java.util.List; -/** -* 角色权限关系 -* @author xxm -* @date 2021/8/3 -*/ +/** + * 角色权限关系 + * @author xxm + * @date 2021/8/3 + */ @Slf4j @Repository @RequiredArgsConstructor @@ -30,7 +30,11 @@ public class RoleMenuManager extends BaseManager { return findAllByFields(RoleMenu::getRoleId,roleIds); } - public List findAllByRole(Long roleId) { - return findAllByField(RoleMenu::getRoleId,roleId); + public List findAllByRoleAndClientCode(Long roleId,String clientCode) { + return lambdaQuery() + .eq(RoleMenu::getRoleId,roleId) + .eq(RoleMenu::getClientCode,clientCode) + .list(); + } } diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/entity/RoleMenu.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/entity/RoleMenu.java index c55fbdea2a74697087d8f50570a9cbc177ab2344..26fbc502a31da03f516c2d7590c8f917e41bd73d 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/entity/RoleMenu.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/entity/RoleMenu.java @@ -24,13 +24,20 @@ public class RoleMenu extends MpIdEntity { */ private Long roleId; + /** + * 终端类型 + */ + private String clientCode; + /** * 菜单权限id */ private Long permissionId; - public RoleMenu(Long roleId, Long permissionId) { + + public RoleMenu(Long roleId, String clientCode, Long permissionId) { this.roleId = roleId; + this.clientCode = clientCode; this.permissionId = permissionId; } } diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/service/RoleMenuService.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/service/RoleMenuService.java index 0f5020be37ef11da553d966358c32a965d701485..29e8976308f828d27700dd6079b16bf3f80cf33b 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/service/RoleMenuService.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/upms/service/RoleMenuService.java @@ -41,9 +41,9 @@ public class RoleMenuService { * 保存角色菜单授权 */ @Transactional(rollbackFor = Exception.class) - public void save(Long roleId, List permissionIds){ + public void save(Long roleId, String clientCode, List permissionIds){ // 先删后增 - List RoleMenus = roleMenuManager.findAllByRole(roleId); + List RoleMenus = roleMenuManager.findAllByRoleAndClientCode(roleId,clientCode); List roleMenuIds = RoleMenus.stream().map(RoleMenu::getPermissionId).collect(Collectors.toList()); // 需要删除的 List deleteIds = RoleMenus.stream() @@ -53,7 +53,7 @@ public class RoleMenuService { List roleMenus = permissionIds.stream() .filter(id->!roleMenuIds.contains(id)) - .map(permissionId -> new RoleMenu(roleId, permissionId)) + .map(permissionId -> new RoleMenu(roleId, clientCode,permissionId)) .collect(Collectors.toList()); roleMenuManager.deleteByIds(deleteIds); roleMenuManager.saveAll(roleMenus); @@ -63,8 +63,8 @@ public class RoleMenuService { /** * 根据角色查询对应的权限id */ - public List findPermissionIdsByRole(Long roleId){ - List rolePermissions = roleMenuManager.findAllByRole(roleId); + public List findPermissionIdsByRole(Long roleId,String clientCode){ + List rolePermissions = roleMenuManager.findAllByRoleAndClientCode(roleId,clientCode); return rolePermissions.stream() .map(RoleMenu::getPermissionId) .collect(Collectors.toList()); @@ -73,8 +73,8 @@ public class RoleMenuService { /** * 获取菜单权限树, 不包含资源权限 */ - public List findMenuTree(){ - List permissions = this.findPermissions(); + public List findMenuTree(String clientCode){ + List permissions = this.findPermissions(clientCode); List permissionsByNotButton = permissions.stream() .filter(o -> !Objects.equals(PermissionCode.MENU_TYPE_RESOURCE, o.getMenuType())) .collect(Collectors.toList()); @@ -84,15 +84,15 @@ public class RoleMenuService { /** * 获取权限树, 包含菜单和资源权限 */ - public List findAllTree(){ - return this.recursiveBuildTree(this.findPermissions(), null); + public List findAllTree(String clientCode){ + return this.recursiveBuildTree(this.findPermissions(clientCode), null); } /** * 获取权限菜单id列表,不包含资源权限 */ - public List findMenuIds() { - List permissions = this.findPermissions(); + public List findMenuIds(String clientCode) { + List permissions = this.findPermissions(clientCode); return permissions.stream() .filter(o -> !Objects.equals(PermissionCode.MENU_TYPE_RESOURCE, o.getMenuType())) .map(PermMenuDto::getId) @@ -102,8 +102,8 @@ public class RoleMenuService { /** * 获取权限id列表,包含菜单和资源权限 */ - public List findPermissionIds() { - List permissions = this.findPermissions(); + public List findPermissionIds(String clientCode) { + List permissions = this.findPermissions(clientCode); return permissions.stream() .map(PermMenuDto::getId) .collect(Collectors.toList()); @@ -112,8 +112,8 @@ public class RoleMenuService { /** * 获取菜单和资源权限 */ - public MenuAndResourceDto getPermissions(){ - List permissions = this.findPermissions(); + public MenuAndResourceDto getPermissions(String clientCode){ + List permissions = this.findPermissions(clientCode); List resourcePerms = permissions.stream() .filter(o -> Objects.equals(PermissionCode.MENU_TYPE_RESOURCE, o.getMenuType())) .map(PermMenuDto::getPermCode) @@ -129,13 +129,13 @@ public class RoleMenuService { /** * 获取权限信息列表 */ - private List findPermissions(){ + private List findPermissions(String clientCode){ UserDetail userDetail = SecurityUtil.getCurrentUser().orElseThrow(NotLoginException::new); List permissions; //系统管理员,获取全部的权限 if (userDetail.isAdmin()) { - permissions = permMenuService.findAll(); + permissions = permMenuService.findAllByClientCode(clientCode); } else { // 非管理员获取自身拥有的权限 permissions = this.findPermissionsByUser(userDetail.getId()); diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/user/entity/UserInfo.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/user/entity/UserInfo.java index 285e99748f99bd147358c1b9fb6faf47c1339be5..f04579559ccb470c03925c38c4a07d41d54a752c 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/user/entity/UserInfo.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/core/user/entity/UserInfo.java @@ -8,12 +8,17 @@ import cn.bootx.iam.code.UserStatusCode; import cn.bootx.iam.core.user.convert.UserConvert; import cn.bootx.iam.dto.user.UserInfoDto; import cn.bootx.iam.param.user.UserInfoParam; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; /** * 用户的核心信息 @@ -41,6 +46,9 @@ public class UserInfo extends MpBaseEntity implements EntityBaseFunction collect = Arrays.stream(this.getClientIds().split(",")) + .collect(Collectors.toList()); + userInfoDto.setClientIdList(collect); + } + return userInfoDto; + } + + public static UserInfo init(UserInfoParam param) { + UserInfo userInfo = UserConvert.CONVERT.convert(param); + if (CollUtil.isNotEmpty(param.getClientIdList())){ + String clientIds= String.join(",", param.getClientIdList()); + userInfo.setClientIds(clientIds); + } + return userInfo; } public UserDetail toUserDetail(){ @@ -71,7 +94,4 @@ public class UserInfo extends MpBaseEntity implements EntityBaseFunction clientIdList = new ArrayList<>(); + @Schema(description= "注册来源") private String source; @@ -61,12 +68,19 @@ public class UserInfoDto extends BaseDto implements Serializable { private LocalDateTime registerTime; public UserDetail toUserDetail(){ + List clientIds = new ArrayList<>(); + if (CollUtil.isNotEmpty(this.getClientIdList())){ + clientIds = this.getClientIdList().stream() + .map(Long::valueOf) + .collect(Collectors.toList()); + } return new UserDetail() .setId(this.getId()) .setPassword(this.password) .setUsername(this.getUsername()) .setName(this.name) .setAdmin(this.admin) + .setClientIds(clientIds) .setStatus(this.status); } } diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/handler/IgnorePathRouterCheck.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/handler/IgnorePathRouterCheck.java new file mode 100644 index 0000000000000000000000000000000000000000..685829af25df7150402a2b7aece69c1447d9cd5d --- /dev/null +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/handler/IgnorePathRouterCheck.java @@ -0,0 +1,38 @@ +package cn.bootx.iam.handler; + +import cn.bootx.common.spring.util.WebServletUtil; +import cn.bootx.iam.core.permission.service.PermPathService; +import cn.bootx.starter.auth.authentication.RouterCheck; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; + +import java.util.List; + +/** + * 跳过不启用权限控制的路径 + * @author xxm + * @date 2022/5/27 + */ +@Component +@RequiredArgsConstructor +public class IgnorePathRouterCheck implements RouterCheck { + private final PermPathService pathService; + private final AntPathMatcher matcher = new AntPathMatcher(); + + @Override + public int sortNo() { + return 2; + } + + @Override + public boolean check(Object handler) { + String method = WebServletUtil.getMethod(); + String path = WebServletUtil.getPath(); + // 获取不启用权限控制的路径 + List ignorePaths = pathService.findIgnorePathByRequestType(method); + + return ignorePaths.stream() + .anyMatch(pattern->matcher.match(pattern, path)); + } +} diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/handler/PathRouterCheck.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/handler/UserPathRouterCheck.java similarity index 86% rename from bootx-services/service-iam/src/main/java/cn/bootx/iam/handler/PathRouterCheck.java rename to bootx-services/service-iam/src/main/java/cn/bootx/iam/handler/UserPathRouterCheck.java index dc93a53ef5ef44bcee9eb7bfd8dc15a2059c3fa9..fe61a3b23b08edb3958cef0298b0fc0c7f4e7084 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/handler/PathRouterCheck.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/handler/UserPathRouterCheck.java @@ -13,18 +13,19 @@ import java.util.List; import java.util.Optional; /** - * 路径路由拦截 + * 用户路径路由拦截 * @author xxm * @date 2021/12/21 */ @Component @RequiredArgsConstructor -public class PathRouterCheck implements RouterCheck { +public class UserPathRouterCheck implements RouterCheck { private final RolePathService rolePathService; private final AntPathMatcher matcher = new AntPathMatcher(); + @Override public int sortNo() { - return 1; + return 10; } @Override @@ -37,10 +38,6 @@ public class PathRouterCheck implements RouterCheck { return false; } UserDetail userDetail = UserDetailOpt.get(); - // 管理员有所有的权限 - if (userDetail.isAdmin()){ - return true; - } List paths = rolePathService.findSimplePathsByUser(method,userDetail.getId()); return paths.stream() .anyMatch(pattern->matcher.match(pattern, path)); diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/client/ClientParam.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/client/ClientParam.java index 0b7c71061b11efd190ecfa964ae185271dc025d8..d5a464d4a3534d0f55062a7772db0b9e29f39bfb 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/client/ClientParam.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/client/ClientParam.java @@ -26,6 +26,9 @@ public class ClientParam { @Schema(description = "是否可用") private boolean enable; + @Schema(description = "是否有独立菜单和权限") + private boolean alonePrem; + @Schema(description = "是否启用验证码") private boolean captcha; diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/permission/PermMenuParam.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/permission/PermMenuParam.java index 759ea6d0068f2c2c5fb825d50ed52664ae03d220..58604fedccf9b37ad20347209c7f031dc9e5c521 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/permission/PermMenuParam.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/permission/PermMenuParam.java @@ -1,9 +1,14 @@ package cn.bootx.iam.param.permission; +import cn.bootx.common.core.validation.ValidationGroup; +import cn.bootx.common.core.validation.ValidationGroup.edit; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.experimental.Accessors; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; import java.io.Serializable; /** @@ -16,12 +21,18 @@ import java.io.Serializable; public class PermMenuParam implements Serializable { private static final long serialVersionUID = 3017200753543614579L; + @Null(groups = { edit.class}) + @NotNull(groups = {ValidationGroup.add.class}) @Schema(description = "主键") private Long id; @Schema(description = "父id") private Long parentId; + @NotEmpty(groups = {ValidationGroup.add.class, edit.class}) + @Schema(description = "关联终端code") + private String clientCode; + @Schema(description = "菜单标题") private String title; diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/upms/RolePermissionParam.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/upms/RolePermissionParam.java index 59e914dc035812cfccd5e84c2d28083b75130d79..2e5794f1874355127a104b9f4c70d92f8e86b665 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/upms/RolePermissionParam.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/upms/RolePermissionParam.java @@ -1,13 +1,14 @@ package cn.bootx.iam.param.upms; import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema;; import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; import java.util.List; +; + /** * @author xxm * @date 2021/6/9 @@ -21,6 +22,10 @@ public class RolePermissionParam implements Serializable { @Schema(description= "角色的ID") private Long roleId; + @Schema(description= "终端code") + private String clientCode; + @Schema(description= "权限id") private List permissionIds; + } diff --git a/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/user/UserInfoParam.java b/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/user/UserInfoParam.java index db8b99ec292dddc4482ee28442420e2c07fe4c8a..2a9a9bcc209bd4e67e599e2dcee87c4c36e012d2 100644 --- a/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/user/UserInfoParam.java +++ b/bootx-services/service-iam/src/main/java/cn/bootx/iam/param/user/UserInfoParam.java @@ -6,6 +6,7 @@ import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; +import java.util.List; /** * @author xxm @@ -32,6 +33,9 @@ public class UserInfoParam implements Serializable { @Schema(description= "邮箱") private String email; + @Schema(description= "终端id列表") + private List clientIdList; + @Schema(description= "头像") private String avatar; diff --git a/bootx-services/service-payment/pom.xml b/bootx-services/service-payment/pom.xml index 11387550cf8f7fa7bbda784a4d4a782d3e21b9b2..756d09d60d773ad5940ca54d4270218e9e12c6ab 100644 --- a/bootx-services/service-payment/pom.xml +++ b/bootx-services/service-payment/pom.xml @@ -14,7 +14,7 @@ jar - 2.8.0 + 2.8.1 diff --git a/bootx-services/service-payment/src/main/java/cn/bootx/payment/code/PaymentEventCode.java b/bootx-services/service-payment/src/main/java/cn/bootx/payment/code/PaymentEventCode.java index 4743bf563aba67e65fd58124f0609491a47da8e6..bfaf129b00cbd87f88952d2633105638b3987d39 100644 --- a/bootx-services/service-payment/src/main/java/cn/bootx/payment/code/PaymentEventCode.java +++ b/bootx-services/service-payment/src/main/java/cn/bootx/payment/code/PaymentEventCode.java @@ -7,7 +7,4 @@ public interface PaymentEventCode { /** 支付完成 */ String PAY_COMPLETE = "pay.complete"; - - /** 支付撤销 */ - String PAY_CANCEL = "pay.cancel"; } diff --git a/bootx-services/service-sales/src/main/java/cn/bootx/sales/controller/StrategyController.java b/bootx-services/service-sales/src/main/java/cn/bootx/sales/controller/StrategyController.java index 7aeebf37ed5821c9670116d3be19d2f22fe98215..e0e90c661e9e7b6afb907ffcec72a71387ad2860 100644 --- a/bootx-services/service-sales/src/main/java/cn/bootx/sales/controller/StrategyController.java +++ b/bootx-services/service-sales/src/main/java/cn/bootx/sales/controller/StrategyController.java @@ -14,9 +14,9 @@ import org.springframework.web.bind.annotation.*; import java.util.List; /** -* @author xxm -* @date 2020/10/17 -*/ + * @author xxm + * @date 2020/10/17 + */ @Tag(name ="策略定义") @RestController @RequestMapping("/strategy") @@ -26,8 +26,9 @@ public class StrategyController { @Operation(summary = "添加策略") @PostMapping("/add") - public ResResult add(@RequestBody StrategyParam param){ - return Res.ok(strategyService.add(param)); + public ResResult add(@RequestBody StrategyParam param){ + strategyService.add(param); + return Res.ok(); } @Operation(summary = "更新策略") diff --git a/bootx-services/service-sales/src/main/java/cn/bootx/sales/core/check/config/entity/CheckRuleConfig.java b/bootx-services/service-sales/src/main/java/cn/bootx/sales/core/check/config/entity/CheckRuleConfig.java index 61e84e4e3ad5dfedd1967389fd1e407223642c46..5fc8594306c46a1e2be7ec7026454a79751a13af 100644 --- a/bootx-services/service-sales/src/main/java/cn/bootx/sales/core/check/config/entity/CheckRuleConfig.java +++ b/bootx-services/service-sales/src/main/java/cn/bootx/sales/core/check/config/entity/CheckRuleConfig.java @@ -57,7 +57,7 @@ public class CheckRuleConfig extends MpBaseEntity implements EntityBaseFunction< /** * 类型 - * @see StrategyCode + * @see StrategyCode#ENGINE_SYSTEM */ @TableField(exist = false) private int engineType; diff --git a/bootx-services/service-sales/src/main/java/cn/bootx/sales/core/strategy/entity/Strategy.java b/bootx-services/service-sales/src/main/java/cn/bootx/sales/core/strategy/entity/Strategy.java index 064ffae330752f026b4fd3de7063730530dcfa4d..f2b28a9285235f9439a7ebac048e865dc5a8c815 100644 --- a/bootx-services/service-sales/src/main/java/cn/bootx/sales/core/strategy/entity/Strategy.java +++ b/bootx-services/service-sales/src/main/java/cn/bootx/sales/core/strategy/entity/Strategy.java @@ -33,17 +33,18 @@ public class Strategy extends MpBaseEntity implements EntityBaseFunctionspring-boot-starter-undertow - - org.springframework.boot - spring-boot-starter-data-mongodb - - - - - cn.bootx.platform - service-goods - ${bootx-platform.version} - - - - - cn.bootx.platform - service-payment - ${bootx-platform.version} - - - - - cn.bootx.platform - service-sales - ${bootx-platform.version} - - - - - cn.bootx.platform - service-order - ${bootx-platform.version} - - - - - cn.bootx.platform - service-iam - ${bootx-platform.version} - - - - - cn.bootx.platform - service-notice - ${bootx-platform.version} - - - + cn.bootx.platform - service-baseapi + module-eshop ${bootx-platform.version} diff --git a/bootx-start/src/main/resources/application-dev.yml b/bootx-start/src/main/resources/application-dev.yml index de0c249e472bca151dfec53c5a8041ad1d899adf..cd635c44429b887457d6af3dda3640b3a65e8b9a 100644 --- a/bootx-start/src/main/resources/application-dev.yml +++ b/bootx-start/src/main/resources/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 8080 + port: 9999 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver diff --git a/bootx-start/src/main/resources/logback-spring.xml b/bootx-start/src/main/resources/logback-spring.xml index 2c3301482fe78283866e18aaced28f5e7c1f8665..c2c568cf9c2cd79931d0bf8f5d8fa4edadd6757f 100644 --- a/bootx-start/src/main/resources/logback-spring.xml +++ b/bootx-start/src/main/resources/logback-spring.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/pom.xml b/pom.xml index f9de6407b0692ac3c6a416c49cf5c36b855527d4..1cbd430eb329b21f66de4b03af517c053d3a48c9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 2.6.7 + 2.7.0 @@ -24,6 +24,7 @@ bootx-services bootx-start bootx-demo + bootx-modules @@ -35,9 +36,9 @@ 1.1.0-beta-1-SNAPSHOT 2.12.6 - 1.2.3 + 1.2.11 2.3.0 - 1.29.0 + 1.30.0 3.5.1 2.2.0 1.6.8