diff --git a/dolphin-commons/dolphin-common-core/pom.xml b/dolphin-commons/dolphin-common-core/pom.xml index 9524288..6498bd9 100644 --- a/dolphin-commons/dolphin-common-core/pom.xml +++ b/dolphin-commons/dolphin-common-core/pom.xml @@ -35,6 +35,9 @@ lombok + ${java.version} + ${java.version} + UTF-8 diff --git a/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/BusinessException.java b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/BusinessException.java index 789c419..f7270cd 100644 --- a/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/BusinessException.java +++ b/dolphin-commons/dolphin-common-core/src/main/java/day/gitlab/dolphin/common/core/exception/BusinessException.java @@ -7,6 +7,11 @@ public class BusinessException extends RuntimeException { private final int code; + public BusinessException(String message) { + super(message); + this.code = 500; + } + public BusinessException(int code, String message) { super(message); this.code = code; diff --git a/dolphin-commons/dolphin-common-mybatis/pom.xml b/dolphin-commons/dolphin-common-mybatis/pom.xml index 739927e..1410ae0 100644 --- a/dolphin-commons/dolphin-common-mybatis/pom.xml +++ b/dolphin-commons/dolphin-common-mybatis/pom.xml @@ -43,6 +43,9 @@ lombok + ${java.version} + ${java.version} + UTF-8 diff --git a/dolphin-commons/dolphin-common-security/pom.xml b/dolphin-commons/dolphin-common-security/pom.xml index 985952f..547dea9 100644 --- a/dolphin-commons/dolphin-common-security/pom.xml +++ b/dolphin-commons/dolphin-common-security/pom.xml @@ -52,6 +52,9 @@ lombok + ${java.version} + ${java.version} + UTF-8 diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnoreInitializer.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnoreInitializer.java index 3936a74..8e81a2b 100644 --- a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnoreInitializer.java +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/annotation/AuthorityIgnoreInitializer.java @@ -43,7 +43,7 @@ public class AuthorityIgnoreInitializer implements ApplicationContextAware { return s.startsWith("/") ? prefixUrl + s : prefixUrl + "/" + s; }) .map(IgnoreUrl::new) - .forEach(url -> this.ignoreUrls.add(url)); + .forEach(this.ignoreUrls::add); } for (RequestMappingInfo mappingInfo : handlerMethods.keySet()) { @@ -59,9 +59,6 @@ public class AuthorityIgnoreInitializer implements ApplicationContextAware { continue; } - System.out.println("beanClass:" + beanClass.getCanonicalName()); - System.out.println("method:" + handlerMethod.getMethod().getName() + " -> " + mappingInfo.getPatternValues()); - List urlPrefix = Arrays.stream(requestMapping.method()) .map(RequestMethod::name) .map(StringBuffer::new) @@ -81,9 +78,7 @@ public class AuthorityIgnoreInitializer implements ApplicationContextAware { urlPrefix.stream() .flatMap(sub -> mappingInfo.getPatternValues().stream().filter(StringUtils::hasText).map(s -> sub + s)) .map(IgnoreUrl::new) - .forEach(url -> this.ignoreUrls.add(url)); - - System.out.println("ignoreUrls: " + ignoreUrls); + .forEach(this.ignoreUrls::add); } } diff --git a/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/JwtInfo.java b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/JwtInfo.java new file mode 100644 index 0000000..0de4d5e --- /dev/null +++ b/dolphin-commons/dolphin-common-security/src/main/java/day/gitlab/dolphin/common/security/jwt/JwtInfo.java @@ -0,0 +1,12 @@ +package day.gitlab.dolphin.common.security.jwt; + +import day.gitlab.dolphin.common.security.config.SecurityConfig; +import org.springframework.stereotype.Component; + +@Component +public class JwtInfo extends Jwt { + + public JwtInfo(SecurityConfig securityConfig) { + super(securityConfig.getSecret(), securityConfig.getExpire(), securityConfig.getRefreshTokenExpire()); + } +} diff --git a/dolphin-compose/pom.xml b/dolphin-compose/pom.xml index 9d7a4d4..7a6c7fd 100644 --- a/dolphin-compose/pom.xml +++ b/dolphin-compose/pom.xml @@ -72,6 +72,9 @@ lombok + ${java.version} + ${java.version} + UTF-8 diff --git a/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/DolphinAuthenticationProvider.java b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/DolphinAuthenticationProvider.java deleted file mode 100644 index eed41ee..0000000 --- a/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/DolphinAuthenticationProvider.java +++ /dev/null @@ -1,26 +0,0 @@ -package day.gitlab.dolphin.authorize; - -import day.gitlab.dolphin.common.security.AuthenticationProvider; -import day.gitlab.dolphin.common.security.UserPrincipal; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.List; - -@Component -public class DolphinAuthenticationProvider implements AuthenticationProvider { - - @Override - public UserPrincipal getUserPrincipal(String userId) { - UserPrincipal userPrincipal = new UserPrincipal(); - userPrincipal.setId(userId); - userPrincipal.setUsername(userId); - userPrincipal.setNickname(userId); - return userPrincipal; - } - - @Override - public List getUserAuthorities(String userId) { - return new ArrayList<>(); - } -} diff --git a/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/controller/AuthorizeController.java b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/controller/AuthorizeController.java new file mode 100644 index 0000000..df33daf --- /dev/null +++ b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/controller/AuthorizeController.java @@ -0,0 +1,25 @@ +package day.gitlab.dolphin.authorize.controller; + +import day.gitlab.dolphin.authorize.entity.dto.LoginDTO; +import day.gitlab.dolphin.authorize.service.AuthorizeService; +import day.gitlab.dolphin.common.core.entity.Result; +import day.gitlab.dolphin.common.security.annotation.AuthorityIgnore; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/authorize") +public class AuthorizeController { + + @Resource + private AuthorizeService authorizeService; + + @AuthorityIgnore + @PostMapping("/login") + public Result login(@RequestBody LoginDTO loginDTO) { + return Result.success(authorizeService.login(loginDTO)); + } +} diff --git a/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/entity/dto/LoginDTO.java b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/entity/dto/LoginDTO.java new file mode 100644 index 0000000..c867800 --- /dev/null +++ b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/entity/dto/LoginDTO.java @@ -0,0 +1,11 @@ +package day.gitlab.dolphin.authorize.entity.dto; + +import lombok.Data; + +@Data +public class LoginDTO { + + private String username; + + private String password; +} diff --git a/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/entity/vo/LoginVO.java b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/entity/vo/LoginVO.java new file mode 100644 index 0000000..18b8e66 --- /dev/null +++ b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/entity/vo/LoginVO.java @@ -0,0 +1,11 @@ +package day.gitlab.dolphin.authorize.entity.vo; + +import lombok.Data; + +@Data +public class LoginVO { + + private String accessToken; + + private String refreshToken; +} diff --git a/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/service/AuthorizeService.java b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/service/AuthorizeService.java new file mode 100644 index 0000000..ff0dff6 --- /dev/null +++ b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/service/AuthorizeService.java @@ -0,0 +1,10 @@ +package day.gitlab.dolphin.authorize.service; + +import day.gitlab.dolphin.authorize.entity.dto.LoginDTO; +import day.gitlab.dolphin.authorize.entity.vo.LoginVO; +import day.gitlab.dolphin.common.security.AuthenticationProvider; + +public interface AuthorizeService extends AuthenticationProvider { + + LoginVO login(LoginDTO loginDTO); +} diff --git a/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/service/impl/AuthorizeServiceImpl.java b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/service/impl/AuthorizeServiceImpl.java new file mode 100644 index 0000000..b09ce1b --- /dev/null +++ b/dolphin-compose/src/main/java/day/gitlab/dolphin/authorize/service/impl/AuthorizeServiceImpl.java @@ -0,0 +1,71 @@ +package day.gitlab.dolphin.authorize.service.impl; + +import cn.hutool.v7.crypto.digest.BCrypt; +import com.mybatisflex.core.query.QueryCondition; +import day.gitlab.dolphin.authorize.entity.dto.LoginDTO; +import day.gitlab.dolphin.authorize.entity.vo.LoginVO; +import day.gitlab.dolphin.authorize.service.AuthorizeService; +import day.gitlab.dolphin.common.core.exception.BusinessException; +import day.gitlab.dolphin.common.security.UserPrincipal; +import day.gitlab.dolphin.common.security.jwt.JwtInfo; +import day.gitlab.dolphin.rbac.entity.Role; +import day.gitlab.dolphin.rbac.entity.User; +import day.gitlab.dolphin.rbac.entity.table.UserTableDef; +import day.gitlab.dolphin.rbac.mapper.UserMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class AuthorizeServiceImpl implements AuthorizeService { + + @Resource + private UserMapper userMapper; + + @Resource + private JwtInfo jwtInfo; + + @Override + public UserPrincipal getUserPrincipal(String userId) { + User user = userMapper.selectOneById(userId); + + return UserPrincipal.builder() + .id(user.getId()) + .username(user.getUsername()) + .nickname(user.getNickname()) + .build(); + } + + @Override + public List getUserAuthorities(String userId) { + User user = userMapper.selectOneWithRelationsById(userId); + + List roles = user.getRoles(); + if (roles == null || roles.isEmpty()) { + return Collections.emptyList(); + } + + return roles.stream().map(Role::getCode).collect(Collectors.toList()); + } + + @Override + public LoginVO login(LoginDTO loginDTO) { + QueryCondition queryCondition = UserTableDef.USER.USERNAME.eq(loginDTO.getUsername()); + User user = userMapper.selectOneByCondition(queryCondition); + + if (user == null || !BCrypt.checkpw(loginDTO.getPassword(), user.getPassword())) { + throw new BusinessException("User name or password is incorrect"); + } + if (!"1".equalsIgnoreCase(user.getEnabled())) { + throw new BusinessException("User has been disabled"); + } + + LoginVO loginVO = new LoginVO(); + loginVO.setAccessToken(jwtInfo.generateAccessToken(user.getId())); + loginVO.setRefreshToken(jwtInfo.generateRefreshToken(user.getId())); + return loginVO; + } +} diff --git a/dolphin-modules/dolphin-module-core/pom.xml b/dolphin-modules/dolphin-module-core/pom.xml index a999b5b..641aa75 100644 --- a/dolphin-modules/dolphin-module-core/pom.xml +++ b/dolphin-modules/dolphin-module-core/pom.xml @@ -55,6 +55,9 @@ lombok + ${java.version} + ${java.version} + UTF-8 diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/controller/DictionaryController.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/controller/DictionaryController.java new file mode 100644 index 0000000..046407c --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/controller/DictionaryController.java @@ -0,0 +1,95 @@ +package day.gitlab.dolphin.core.controller; + +import com.mybatisflex.core.paginate.Page; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.beans.factory.annotation.Autowired; +import day.gitlab.dolphin.core.entity.Dictionary; +import day.gitlab.dolphin.core.service.DictionaryService; +import org.springframework.web.bind.annotation.RestController; +import java.util.List; + +/** + * 字典 控制层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@RestController +@RequestMapping("/dictionary") +public class DictionaryController { + + @Autowired + private DictionaryService dictionaryService; + + /** + * 保存字典。 + * + * @param dictionary 字典 + * @return {@code true} 保存成功,{@code false} 保存失败 + */ + @PostMapping("save") + public boolean save(@RequestBody Dictionary dictionary) { + return dictionaryService.save(dictionary); + } + + /** + * 根据主键删除字典。 + * + * @param id 主键 + * @return {@code true} 删除成功,{@code false} 删除失败 + */ + @DeleteMapping("remove/{id}") + public boolean remove(@PathVariable String id) { + return dictionaryService.removeById(id); + } + + /** + * 根据主键更新字典。 + * + * @param dictionary 字典 + * @return {@code true} 更新成功,{@code false} 更新失败 + */ + @PutMapping("update") + public boolean update(@RequestBody Dictionary dictionary) { + return dictionaryService.updateById(dictionary); + } + + /** + * 查询所有字典。 + * + * @return 所有数据 + */ + @GetMapping("list") + public List list() { + return dictionaryService.list(); + } + + /** + * 根据主键获取字典。 + * + * @param id 字典主键 + * @return 字典详情 + */ + @GetMapping("getInfo/{id}") + public Dictionary getInfo(@PathVariable String id) { + return dictionaryService.getById(id); + } + + /** + * 分页查询字典。 + * + * @param page 分页对象 + * @return 分页对象 + */ + @GetMapping("page") + public Page page(Page page) { + return dictionaryService.page(page); + } + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/controller/DictionaryItemController.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/controller/DictionaryItemController.java new file mode 100644 index 0000000..d0c3bc6 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/controller/DictionaryItemController.java @@ -0,0 +1,95 @@ +package day.gitlab.dolphin.core.controller; + +import com.mybatisflex.core.paginate.Page; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.beans.factory.annotation.Autowired; +import day.gitlab.dolphin.core.entity.DictionaryItem; +import day.gitlab.dolphin.core.service.DictionaryItemService; +import org.springframework.web.bind.annotation.RestController; +import java.util.List; + +/** + * 字典项 控制层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@RestController +@RequestMapping("/dictionaryItem") +public class DictionaryItemController { + + @Autowired + private DictionaryItemService dictionaryItemService; + + /** + * 保存字典项。 + * + * @param dictionaryItem 字典项 + * @return {@code true} 保存成功,{@code false} 保存失败 + */ + @PostMapping("save") + public boolean save(@RequestBody DictionaryItem dictionaryItem) { + return dictionaryItemService.save(dictionaryItem); + } + + /** + * 根据主键删除字典项。 + * + * @param id 主键 + * @return {@code true} 删除成功,{@code false} 删除失败 + */ + @DeleteMapping("remove/{id}") + public boolean remove(@PathVariable String id) { + return dictionaryItemService.removeById(id); + } + + /** + * 根据主键更新字典项。 + * + * @param dictionaryItem 字典项 + * @return {@code true} 更新成功,{@code false} 更新失败 + */ + @PutMapping("update") + public boolean update(@RequestBody DictionaryItem dictionaryItem) { + return dictionaryItemService.updateById(dictionaryItem); + } + + /** + * 查询所有字典项。 + * + * @return 所有数据 + */ + @GetMapping("list") + public List list() { + return dictionaryItemService.list(); + } + + /** + * 根据主键获取字典项。 + * + * @param id 字典项主键 + * @return 字典项详情 + */ + @GetMapping("getInfo/{id}") + public DictionaryItem getInfo(@PathVariable String id) { + return dictionaryItemService.getById(id); + } + + /** + * 分页查询字典项。 + * + * @param page 分页对象 + * @return 分页对象 + */ + @GetMapping("page") + public Page page(Page page) { + return dictionaryItemService.page(page); + } + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/Dictionary.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/Dictionary.java new file mode 100644 index 0000000..0c89c81 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/Dictionary.java @@ -0,0 +1,63 @@ +package day.gitlab.dolphin.core.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.sql.Timestamp; + +import java.io.Serial; + +import lombok.Builder; +import lombok.Data; + +/** + * 字典 实体类。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Data +@Builder +@Table("sys_core_dictionary") +public class Dictionary implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id + private String id; + + /** + * 字典名称 + */ + private String name; + + /** + * 字典代码 + */ + private String code; + + /** + * 字典类型: enum-枚举、tree-树型 + */ + private String type; + + /** + * 字典描述 + */ + private String description; + + /** + * 创建时间 + */ + private Timestamp createTime; + + /** + * 修改时间 + */ + private Timestamp updateTime; + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/DictionaryItem.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/DictionaryItem.java new file mode 100644 index 0000000..74bbcf4 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/DictionaryItem.java @@ -0,0 +1,73 @@ +package day.gitlab.dolphin.core.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.sql.Timestamp; + +import java.io.Serial; + +import lombok.Builder; +import lombok.Data; + +/** + * 字典项 实体类。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Data +@Builder +@Table("sys_core_dictionary_item") +public class DictionaryItem implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id + private String id; + + /** + * 字典ID + */ + private String dictionaryId; + + /** + * 父级ID,如果为空则为根节点 + */ + private String parentId; + + /** + * 字典项名称 + */ + private String name; + + /** + * 字典项代码 + */ + private String code; + + /** + * 字典项排序,升序排列 + */ + private Integer sort; + + /** + * 字典项描述 + */ + private String description; + + /** + * 创建时间 + */ + private Timestamp createTime; + + /** + * 修改时间 + */ + private Timestamp updateTime; + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/table/DictionaryItemTableDef.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/table/DictionaryItemTableDef.java new file mode 100644 index 0000000..7ec8cf6 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/table/DictionaryItemTableDef.java @@ -0,0 +1,92 @@ +package day.gitlab.dolphin.core.entity.table; + +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.table.TableDef; + +import java.io.Serial; + +/** + * 字典项 表定义层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public class DictionaryItemTableDef extends TableDef { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 字典项 + */ + public static final DictionaryItemTableDef DICTIONARY_ITEM = new DictionaryItemTableDef(); + + /** + * 主键 + */ + public final QueryColumn ID = new QueryColumn(this, "id"); + + /** + * 字典项代码 + */ + public final QueryColumn CODE = new QueryColumn(this, "code"); + + /** + * 字典项名称 + */ + public final QueryColumn NAME = new QueryColumn(this, "name"); + + /** + * 字典项排序,升序排列 + */ + public final QueryColumn SORT = new QueryColumn(this, "sort"); + + /** + * 父级ID,如果为空则为根节点 + */ + public final QueryColumn PARENT_ID = new QueryColumn(this, "parent_id"); + + /** + * 创建时间 + */ + public final QueryColumn CREATE_TIME = new QueryColumn(this, "create_time"); + + /** + * 修改时间 + */ + public final QueryColumn UPDATE_TIME = new QueryColumn(this, "update_time"); + + /** + * 字典项描述 + */ + public final QueryColumn DESCRIPTION = new QueryColumn(this, "description"); + + /** + * 字典ID + */ + public final QueryColumn DICTIONARY_ID = new QueryColumn(this, "dictionary_id"); + + /** + * 所有字段。 + */ + public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*"); + + /** + * 默认字段,不包含逻辑删除或者 large 等字段。 + */ + public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, DICTIONARY_ID, PARENT_ID, NAME, CODE, SORT, DESCRIPTION, CREATE_TIME, UPDATE_TIME}; + + public DictionaryItemTableDef() { + super("", "sys_core_dictionary_item"); + } + + private DictionaryItemTableDef(String schema, String name, String alisa) { + super(schema, name, alisa); + } + + public DictionaryItemTableDef as(String alias) { + String key = getNameWithSchema() + "." + alias; + return getCache(key, k -> new DictionaryItemTableDef("", "sys_core_dictionary_item", alias)); + } + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/table/DictionaryTableDef.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/table/DictionaryTableDef.java new file mode 100644 index 0000000..6e7f4f9 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/entity/table/DictionaryTableDef.java @@ -0,0 +1,82 @@ +package day.gitlab.dolphin.core.entity.table; + +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.table.TableDef; + +import java.io.Serial; + +/** + * 字典 表定义层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public class DictionaryTableDef extends TableDef { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 字典 + */ + public static final DictionaryTableDef DICTIONARY = new DictionaryTableDef(); + + /** + * 主键 + */ + public final QueryColumn ID = new QueryColumn(this, "id"); + + /** + * 字典代码 + */ + public final QueryColumn CODE = new QueryColumn(this, "code"); + + /** + * 字典名称 + */ + public final QueryColumn NAME = new QueryColumn(this, "name"); + + /** + * 字典类型: enum-枚举、tree-树型 + */ + public final QueryColumn TYPE = new QueryColumn(this, "type"); + + /** + * 创建时间 + */ + public final QueryColumn CREATE_TIME = new QueryColumn(this, "create_time"); + + /** + * 修改时间 + */ + public final QueryColumn UPDATE_TIME = new QueryColumn(this, "update_time"); + + /** + * 字典描述 + */ + public final QueryColumn DESCRIPTION = new QueryColumn(this, "description"); + + /** + * 所有字段。 + */ + public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*"); + + /** + * 默认字段,不包含逻辑删除或者 large 等字段。 + */ + public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, NAME, CODE, TYPE, DESCRIPTION, CREATE_TIME, UPDATE_TIME}; + + public DictionaryTableDef() { + super("", "sys_core_dictionary"); + } + + private DictionaryTableDef(String schema, String name, String alisa) { + super(schema, name, alisa); + } + + public DictionaryTableDef as(String alias) { + String key = getNameWithSchema() + "." + alias; + return getCache(key, k -> new DictionaryTableDef("", "sys_core_dictionary", alias)); + } + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/mapper/DictionaryItemMapper.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/mapper/DictionaryItemMapper.java new file mode 100644 index 0000000..1785dc7 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/mapper/DictionaryItemMapper.java @@ -0,0 +1,16 @@ +package day.gitlab.dolphin.core.mapper; + +import org.apache.ibatis.annotations.Mapper; +import com.mybatisflex.core.BaseMapper; +import day.gitlab.dolphin.core.entity.DictionaryItem; + +/** + * 字典项 映射层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Mapper +public interface DictionaryItemMapper extends BaseMapper { + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/mapper/DictionaryMapper.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/mapper/DictionaryMapper.java new file mode 100644 index 0000000..9798dd8 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/mapper/DictionaryMapper.java @@ -0,0 +1,16 @@ +package day.gitlab.dolphin.core.mapper; + +import org.apache.ibatis.annotations.Mapper; +import com.mybatisflex.core.BaseMapper; +import day.gitlab.dolphin.core.entity.Dictionary; + +/** + * 字典 映射层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Mapper +public interface DictionaryMapper extends BaseMapper { + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/DictionaryItemService.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/DictionaryItemService.java new file mode 100644 index 0000000..9443ea2 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/DictionaryItemService.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.core.service; + +import com.mybatisflex.core.service.IService; +import day.gitlab.dolphin.core.entity.DictionaryItem; + +/** + * 字典项 服务层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public interface DictionaryItemService extends IService { + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/DictionaryService.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/DictionaryService.java new file mode 100644 index 0000000..078eca9 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/DictionaryService.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.core.service; + +import com.mybatisflex.core.service.IService; +import day.gitlab.dolphin.core.entity.Dictionary; + +/** + * 字典 服务层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public interface DictionaryService extends IService { + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/impl/DictionaryItemServiceImpl.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/impl/DictionaryItemServiceImpl.java new file mode 100644 index 0000000..2b6decc --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/impl/DictionaryItemServiceImpl.java @@ -0,0 +1,18 @@ +package day.gitlab.dolphin.core.service.impl; + +import com.mybatisflex.spring.service.impl.ServiceImpl; +import day.gitlab.dolphin.core.entity.DictionaryItem; +import day.gitlab.dolphin.core.mapper.DictionaryItemMapper; +import day.gitlab.dolphin.core.service.DictionaryItemService; +import org.springframework.stereotype.Service; + +/** + * 字典项 服务层实现。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Service +public class DictionaryItemServiceImpl extends ServiceImpl implements DictionaryItemService{ + +} diff --git a/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/impl/DictionaryServiceImpl.java b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/impl/DictionaryServiceImpl.java new file mode 100644 index 0000000..255ee52 --- /dev/null +++ b/dolphin-modules/dolphin-module-core/src/main/java/day/gitlab/dolphin/core/service/impl/DictionaryServiceImpl.java @@ -0,0 +1,18 @@ +package day.gitlab.dolphin.core.service.impl; + +import com.mybatisflex.spring.service.impl.ServiceImpl; +import day.gitlab.dolphin.core.entity.Dictionary; +import day.gitlab.dolphin.core.mapper.DictionaryMapper; +import day.gitlab.dolphin.core.service.DictionaryService; +import org.springframework.stereotype.Service; + +/** + * 字典 服务层实现。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Service +public class DictionaryServiceImpl extends ServiceImpl implements DictionaryService{ + +} diff --git a/dolphin-modules/dolphin-module-rbac/pom.xml b/dolphin-modules/dolphin-module-rbac/pom.xml index 41c2064..a3fb649 100644 --- a/dolphin-modules/dolphin-module-rbac/pom.xml +++ b/dolphin-modules/dolphin-module-rbac/pom.xml @@ -37,6 +37,9 @@ lombok + ${java.version} + ${java.version} + UTF-8 diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/DepartmentController.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/DepartmentController.java new file mode 100644 index 0000000..4c75a38 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/DepartmentController.java @@ -0,0 +1,95 @@ +package day.gitlab.dolphin.rbac.controller; + +import com.mybatisflex.core.paginate.Page; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.beans.factory.annotation.Autowired; +import day.gitlab.dolphin.rbac.entity.Department; +import day.gitlab.dolphin.rbac.service.DepartmentService; +import org.springframework.web.bind.annotation.RestController; +import java.util.List; + +/** + * 部门表 控制层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@RestController +@RequestMapping("/department") +public class DepartmentController { + + @Autowired + private DepartmentService departmentService; + + /** + * 保存部门表。 + * + * @param department 部门表 + * @return {@code true} 保存成功,{@code false} 保存失败 + */ + @PostMapping("save") + public boolean save(@RequestBody Department department) { + return departmentService.save(department); + } + + /** + * 根据主键删除部门表。 + * + * @param id 主键 + * @return {@code true} 删除成功,{@code false} 删除失败 + */ + @DeleteMapping("remove/{id}") + public boolean remove(@PathVariable String id) { + return departmentService.removeById(id); + } + + /** + * 根据主键更新部门表。 + * + * @param department 部门表 + * @return {@code true} 更新成功,{@code false} 更新失败 + */ + @PutMapping("update") + public boolean update(@RequestBody Department department) { + return departmentService.updateById(department); + } + + /** + * 查询所有部门表。 + * + * @return 所有数据 + */ + @GetMapping("list") + public List list() { + return departmentService.list(); + } + + /** + * 根据主键获取部门表。 + * + * @param id 部门表主键 + * @return 部门表详情 + */ + @GetMapping("getInfo/{id}") + public Department getInfo(@PathVariable String id) { + return departmentService.getById(id); + } + + /** + * 分页查询部门表。 + * + * @param page 分页对象 + * @return 分页对象 + */ + @GetMapping("page") + public Page page(Page page) { + return departmentService.page(page); + } + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RegionController.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RegionController.java index b0daa4c..1527dda 100644 --- a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RegionController.java +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RegionController.java @@ -1,14 +1,95 @@ package day.gitlab.dolphin.rbac.controller; -import day.gitlab.dolphin.rbac.service.RegionService; -import jakarta.annotation.Resource; +import com.mybatisflex.core.paginate.Page; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.beans.factory.annotation.Autowired; +import day.gitlab.dolphin.rbac.entity.Region; +import day.gitlab.dolphin.rbac.service.RegionService; import org.springframework.web.bind.annotation.RestController; +import java.util.List; +/** + * 区划项 控制层。 + * + * @author jiangyc + * @since 2025-11-28 + */ @RestController @RequestMapping("/region") public class RegionController { - @Resource + @Autowired private RegionService regionService; + + /** + * 保存区划项。 + * + * @param region 区划项 + * @return {@code true} 保存成功,{@code false} 保存失败 + */ + @PostMapping("save") + public boolean save(@RequestBody Region region) { + return regionService.save(region); + } + + /** + * 根据主键删除区划项。 + * + * @param id 主键 + * @return {@code true} 删除成功,{@code false} 删除失败 + */ + @DeleteMapping("remove/{id}") + public boolean remove(@PathVariable String id) { + return regionService.removeById(id); + } + + /** + * 根据主键更新区划项。 + * + * @param region 区划项 + * @return {@code true} 更新成功,{@code false} 更新失败 + */ + @PutMapping("update") + public boolean update(@RequestBody Region region) { + return regionService.updateById(region); + } + + /** + * 查询所有区划项。 + * + * @return 所有数据 + */ + @GetMapping("list") + public List list() { + return regionService.list(); + } + + /** + * 根据主键获取区划项。 + * + * @param id 区划项主键 + * @return 区划项详情 + */ + @GetMapping("getInfo/{id}") + public Region getInfo(@PathVariable String id) { + return regionService.getById(id); + } + + /** + * 分页查询区划项。 + * + * @param page 分页对象 + * @return 分页对象 + */ + @GetMapping("page") + public Page page(Page page) { + return regionService.page(page); + } + } diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RoleController.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RoleController.java new file mode 100644 index 0000000..5ae2e71 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/RoleController.java @@ -0,0 +1,95 @@ +package day.gitlab.dolphin.rbac.controller; + +import com.mybatisflex.core.paginate.Page; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.beans.factory.annotation.Autowired; +import day.gitlab.dolphin.rbac.entity.Role; +import day.gitlab.dolphin.rbac.service.RoleService; +import org.springframework.web.bind.annotation.RestController; +import java.util.List; + +/** + * 角色表 控制层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@RestController +@RequestMapping("/role") +public class RoleController { + + @Autowired + private RoleService roleService; + + /** + * 保存角色表。 + * + * @param role 角色表 + * @return {@code true} 保存成功,{@code false} 保存失败 + */ + @PostMapping("save") + public boolean save(@RequestBody Role role) { + return roleService.save(role); + } + + /** + * 根据主键删除角色表。 + * + * @param id 主键 + * @return {@code true} 删除成功,{@code false} 删除失败 + */ + @DeleteMapping("remove/{id}") + public boolean remove(@PathVariable String id) { + return roleService.removeById(id); + } + + /** + * 根据主键更新角色表。 + * + * @param role 角色表 + * @return {@code true} 更新成功,{@code false} 更新失败 + */ + @PutMapping("update") + public boolean update(@RequestBody Role role) { + return roleService.updateById(role); + } + + /** + * 查询所有角色表。 + * + * @return 所有数据 + */ + @GetMapping("list") + public List list() { + return roleService.list(); + } + + /** + * 根据主键获取角色表。 + * + * @param id 角色表主键 + * @return 角色表详情 + */ + @GetMapping("getInfo/{id}") + public Role getInfo(@PathVariable String id) { + return roleService.getById(id); + } + + /** + * 分页查询角色表。 + * + * @param page 分页对象 + * @return 分页对象 + */ + @GetMapping("page") + public Page page(Page page) { + return roleService.page(page); + } + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/UserController.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/UserController.java new file mode 100644 index 0000000..a8d5fbd --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/controller/UserController.java @@ -0,0 +1,95 @@ +package day.gitlab.dolphin.rbac.controller; + +import com.mybatisflex.core.paginate.Page; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.beans.factory.annotation.Autowired; +import day.gitlab.dolphin.rbac.entity.User; +import day.gitlab.dolphin.rbac.service.UserService; +import org.springframework.web.bind.annotation.RestController; +import java.util.List; + +/** + * 用户表 控制层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@RestController +@RequestMapping("/user") +public class UserController { + + @Autowired + private UserService userService; + + /** + * 保存用户表。 + * + * @param user 用户表 + * @return {@code true} 保存成功,{@code false} 保存失败 + */ + @PostMapping("save") + public boolean save(@RequestBody User user) { + return userService.save(user); + } + + /** + * 根据主键删除用户表。 + * + * @param id 主键 + * @return {@code true} 删除成功,{@code false} 删除失败 + */ + @DeleteMapping("remove/{id}") + public boolean remove(@PathVariable String id) { + return userService.removeById(id); + } + + /** + * 根据主键更新用户表。 + * + * @param user 用户表 + * @return {@code true} 更新成功,{@code false} 更新失败 + */ + @PutMapping("update") + public boolean update(@RequestBody User user) { + return userService.updateById(user); + } + + /** + * 查询所有用户表。 + * + * @return 所有数据 + */ + @GetMapping("list") + public List list() { + return userService.list(); + } + + /** + * 根据主键获取用户表。 + * + * @param id 用户表主键 + * @return 用户表详情 + */ + @GetMapping("getInfo/{id}") + public User getInfo(@PathVariable String id) { + return userService.getById(id); + } + + /** + * 分页查询用户表。 + * + * @param page 分页对象 + * @return 分页对象 + */ + @GetMapping("page") + public Page page(Page page) { + return userService.page(page); + } + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Department.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Department.java new file mode 100644 index 0000000..b54323c --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Department.java @@ -0,0 +1,73 @@ +package day.gitlab.dolphin.rbac.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.sql.Timestamp; + +import java.io.Serial; + +import lombok.Builder; +import lombok.Data; + +/** + * 部门表 实体类。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Data +@Builder +@Table("sys_rbac_department") +public class Department implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id + private String id; + + /** + * 区划ID + */ + private String regionId; + + /** + * 上级部门ID + */ + private String parentId; + + /** + * 部门名称 + */ + private String name; + + /** + * 部门代码 + */ + private String code; + + /** + * 部门排序 + */ + private Integer sort; + + /** + * 描述 + */ + private String description; + + /** + * 创建时间 + */ + private Timestamp createTime; + + /** + * 修改时间 + */ + private Timestamp updateTime; + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Region.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Region.java index f0e506b..a2535e5 100644 --- a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Region.java +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Region.java @@ -1,39 +1,88 @@ package day.gitlab.dolphin.rbac.entity; import com.mybatisflex.annotation.Id; -import com.mybatisflex.annotation.KeyType; import com.mybatisflex.annotation.Table; -import com.mybatisflex.core.keygen.KeyGenerators; -import lombok.Data; - +import java.io.Serializable; import java.sql.Timestamp; -@Data -@Table("sys_rbac_region") -public class Region { +import java.io.Serial; - @Id(keyType = KeyType.Generator, value = KeyGenerators.flexId) +import lombok.Builder; +import lombok.Data; + +/** + * 区划项 实体类。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Data +@Builder +@Table("sys_rbac_region") +public class Region implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id private String id; + /** + * 上级区划ID + */ private String parentId; + /** + * 上级区划代码 + */ private String parentCode; + /** + * 主区划ID + */ private String rootId; + /** + * 主区划代码 + */ private String rootCode; + /** + * 区划名称 + */ private String name; + /** + * 区划代码 + */ private String code; + /** + * 区划扩展代码 + */ private String extCode; + /** + * 区划排序 + */ private Integer sort; + /** + * 区划描述 + */ private String description; + /** + * 创建时间 + */ private Timestamp createTime; + /** + * 修改时间 + */ private Timestamp updateTime; + } diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Role.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Role.java new file mode 100644 index 0000000..778d4c1 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/Role.java @@ -0,0 +1,63 @@ +package day.gitlab.dolphin.rbac.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.sql.Timestamp; + +import java.io.Serial; + +import lombok.Builder; +import lombok.Data; + +/** + * 角色表 实体类。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Data +@Builder +@Table("sys_rbac_role") +public class Role implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id + private String id; + + /** + * 角色名称 + */ + private String name; + + /** + * 角色代码 + */ + private String code; + + /** + * 角色排序 + */ + private Integer sort; + + /** + * 描述 + */ + private String description; + + /** + * 创建时间 + */ + private Timestamp createTime; + + /** + * 修改时间 + */ + private Timestamp updateTime; + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/User.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/User.java index 4bfec07..c9d7e3e 100644 --- a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/User.java +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/User.java @@ -1,19 +1,74 @@ package day.gitlab.dolphin.rbac.entity; import com.mybatisflex.annotation.Id; -import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.RelationOneToMany; import com.mybatisflex.annotation.Table; -import com.mybatisflex.core.keygen.KeyGenerators; +import java.io.Serializable; +import java.sql.Timestamp; +import java.io.Serial; +import java.util.List; + +import lombok.Builder; +import lombok.Data; + +/** + * 用户表 实体类。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Data +@Builder @Table("sys_rbac_user") -public class User { +public class User implements Serializable { - @Id(keyType = KeyType.Generator, value = KeyGenerators.flexId) + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id private String id; + /** + * 用户名称 + */ private String username; + /** + * 用户昵称 + */ + private String nickname; + + /** + * 用户密码 + */ private String password; - private String nickname; + /** + * 是否启用:0-未启用/1-启用 + */ + private String enabled; + + /** + * 描述 + */ + private String description; + + /** + * 创建时间 + */ + private Timestamp createTime; + + /** + * 修改时间 + */ + private Timestamp updateTime; + + @RelationOneToMany(joinTable = "sys_rbac_user_role", + selfField = "id", joinSelfColumn = "user_id", + targetField = "id", joinTargetColumn = "role_id") + private List roles; } diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/DepartmentTableDef.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/DepartmentTableDef.java new file mode 100644 index 0000000..ba4c407 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/DepartmentTableDef.java @@ -0,0 +1,92 @@ +package day.gitlab.dolphin.rbac.entity.table; + +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.table.TableDef; + +import java.io.Serial; + +/** + * 部门表 表定义层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public class DepartmentTableDef extends TableDef { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 部门表 + */ + public static final DepartmentTableDef DEPARTMENT = new DepartmentTableDef(); + + /** + * 主键 + */ + public final QueryColumn ID = new QueryColumn(this, "id"); + + /** + * 部门代码 + */ + public final QueryColumn CODE = new QueryColumn(this, "code"); + + /** + * 部门名称 + */ + public final QueryColumn NAME = new QueryColumn(this, "name"); + + /** + * 部门排序 + */ + public final QueryColumn SORT = new QueryColumn(this, "sort"); + + /** + * 上级部门ID + */ + public final QueryColumn PARENT_ID = new QueryColumn(this, "parent_id"); + + /** + * 区划ID + */ + public final QueryColumn REGION_ID = new QueryColumn(this, "region_id"); + + /** + * 创建时间 + */ + public final QueryColumn CREATE_TIME = new QueryColumn(this, "create_time"); + + /** + * 修改时间 + */ + public final QueryColumn UPDATE_TIME = new QueryColumn(this, "update_time"); + + /** + * 描述 + */ + public final QueryColumn DESCRIPTION = new QueryColumn(this, "description"); + + /** + * 所有字段。 + */ + public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*"); + + /** + * 默认字段,不包含逻辑删除或者 large 等字段。 + */ + public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, REGION_ID, PARENT_ID, NAME, CODE, SORT, DESCRIPTION, CREATE_TIME, UPDATE_TIME}; + + public DepartmentTableDef() { + super("", "sys_rbac_department"); + } + + private DepartmentTableDef(String schema, String name, String alisa) { + super(schema, name, alisa); + } + + public DepartmentTableDef as(String alias) { + String key = getNameWithSchema() + "." + alias; + return getCache(key, k -> new DepartmentTableDef("", "sys_rbac_department", alias)); + } + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/RegionTableDef.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/RegionTableDef.java new file mode 100644 index 0000000..b5eca1d --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/RegionTableDef.java @@ -0,0 +1,107 @@ +package day.gitlab.dolphin.rbac.entity.table; + +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.table.TableDef; + +import java.io.Serial; + +/** + * 区划项 表定义层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public class RegionTableDef extends TableDef { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 区划项 + */ + public static final RegionTableDef REGION = new RegionTableDef(); + + /** + * 主键 + */ + public final QueryColumn ID = new QueryColumn(this, "id"); + + /** + * 区划代码 + */ + public final QueryColumn CODE = new QueryColumn(this, "code"); + + /** + * 区划名称 + */ + public final QueryColumn NAME = new QueryColumn(this, "name"); + + /** + * 区划排序 + */ + public final QueryColumn SORT = new QueryColumn(this, "sort"); + + /** + * 主区划ID + */ + public final QueryColumn ROOT_ID = new QueryColumn(this, "root_id"); + + /** + * 区划扩展代码 + */ + public final QueryColumn EXT_CODE = new QueryColumn(this, "ext_code"); + + /** + * 上级区划ID + */ + public final QueryColumn PARENT_ID = new QueryColumn(this, "parent_id"); + + /** + * 主区划代码 + */ + public final QueryColumn ROOT_CODE = new QueryColumn(this, "root_code"); + + /** + * 创建时间 + */ + public final QueryColumn CREATE_TIME = new QueryColumn(this, "create_time"); + + /** + * 上级区划代码 + */ + public final QueryColumn PARENT_CODE = new QueryColumn(this, "parent_code"); + + /** + * 修改时间 + */ + public final QueryColumn UPDATE_TIME = new QueryColumn(this, "update_time"); + + /** + * 区划描述 + */ + public final QueryColumn DESCRIPTION = new QueryColumn(this, "description"); + + /** + * 所有字段。 + */ + public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*"); + + /** + * 默认字段,不包含逻辑删除或者 large 等字段。 + */ + public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, PARENT_ID, PARENT_CODE, ROOT_ID, ROOT_CODE, NAME, CODE, EXT_CODE, SORT, DESCRIPTION, CREATE_TIME, UPDATE_TIME}; + + public RegionTableDef() { + super("", "sys_rbac_region"); + } + + private RegionTableDef(String schema, String name, String alisa) { + super(schema, name, alisa); + } + + public RegionTableDef as(String alias) { + String key = getNameWithSchema() + "." + alias; + return getCache(key, k -> new RegionTableDef("", "sys_rbac_region", alias)); + } + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/RoleTableDef.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/RoleTableDef.java new file mode 100644 index 0000000..818a8b1 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/RoleTableDef.java @@ -0,0 +1,82 @@ +package day.gitlab.dolphin.rbac.entity.table; + +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.table.TableDef; + +import java.io.Serial; + +/** + * 角色表 表定义层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public class RoleTableDef extends TableDef { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 角色表 + */ + public static final RoleTableDef ROLE = new RoleTableDef(); + + /** + * 主键 + */ + public final QueryColumn ID = new QueryColumn(this, "id"); + + /** + * 角色代码 + */ + public final QueryColumn CODE = new QueryColumn(this, "code"); + + /** + * 角色名称 + */ + public final QueryColumn NAME = new QueryColumn(this, "name"); + + /** + * 角色排序 + */ + public final QueryColumn SORT = new QueryColumn(this, "sort"); + + /** + * 创建时间 + */ + public final QueryColumn CREATE_TIME = new QueryColumn(this, "create_time"); + + /** + * 修改时间 + */ + public final QueryColumn UPDATE_TIME = new QueryColumn(this, "update_time"); + + /** + * 描述 + */ + public final QueryColumn DESCRIPTION = new QueryColumn(this, "description"); + + /** + * 所有字段。 + */ + public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*"); + + /** + * 默认字段,不包含逻辑删除或者 large 等字段。 + */ + public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, NAME, CODE, SORT, DESCRIPTION, CREATE_TIME, UPDATE_TIME}; + + public RoleTableDef() { + super("", "sys_rbac_role"); + } + + private RoleTableDef(String schema, String name, String alisa) { + super(schema, name, alisa); + } + + public RoleTableDef as(String alias) { + String key = getNameWithSchema() + "." + alias; + return getCache(key, k -> new RoleTableDef("", "sys_rbac_role", alias)); + } + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/UserTableDef.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/UserTableDef.java new file mode 100644 index 0000000..5975701 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/entity/table/UserTableDef.java @@ -0,0 +1,87 @@ +package day.gitlab.dolphin.rbac.entity.table; + +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.table.TableDef; + +import java.io.Serial; + +/** + * 用户表 表定义层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public class UserTableDef extends TableDef { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 用户表 + */ + public static final UserTableDef USER = new UserTableDef(); + + /** + * 主键 + */ + public final QueryColumn ID = new QueryColumn(this, "id"); + + /** + * 是否启用:0-未启用/1-启用 + */ + public final QueryColumn ENABLED = new QueryColumn(this, "enabled"); + + /** + * 用户昵称 + */ + public final QueryColumn NICKNAME = new QueryColumn(this, "nickname"); + + /** + * 用户密码 + */ + public final QueryColumn PASSWORD = new QueryColumn(this, "password"); + + /** + * 用户名称 + */ + public final QueryColumn USERNAME = new QueryColumn(this, "username"); + + /** + * 创建时间 + */ + public final QueryColumn CREATE_TIME = new QueryColumn(this, "create_time"); + + /** + * 修改时间 + */ + public final QueryColumn UPDATE_TIME = new QueryColumn(this, "update_time"); + + /** + * 描述 + */ + public final QueryColumn DESCRIPTION = new QueryColumn(this, "description"); + + /** + * 所有字段。 + */ + public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*"); + + /** + * 默认字段,不包含逻辑删除或者 large 等字段。 + */ + public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, USERNAME, NICKNAME, PASSWORD, ENABLED, DESCRIPTION, CREATE_TIME, UPDATE_TIME}; + + public UserTableDef() { + super("", "sys_rbac_user"); + } + + private UserTableDef(String schema, String name, String alisa) { + super(schema, name, alisa); + } + + public UserTableDef as(String alias) { + String key = getNameWithSchema() + "." + alias; + return getCache(key, k -> new UserTableDef("", "sys_rbac_user", alias)); + } + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/DepartmentMapper.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/DepartmentMapper.java new file mode 100644 index 0000000..d7c90cd --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/DepartmentMapper.java @@ -0,0 +1,16 @@ +package day.gitlab.dolphin.rbac.mapper; + +import org.apache.ibatis.annotations.Mapper; +import com.mybatisflex.core.BaseMapper; +import day.gitlab.dolphin.rbac.entity.Department; + +/** + * 部门表 映射层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Mapper +public interface DepartmentMapper extends BaseMapper { + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RegionMapper.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RegionMapper.java index ff75fef..ea065a6 100644 --- a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RegionMapper.java +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RegionMapper.java @@ -1,9 +1,16 @@ package day.gitlab.dolphin.rbac.mapper; +import org.apache.ibatis.annotations.Mapper; import com.mybatisflex.core.BaseMapper; import day.gitlab.dolphin.rbac.entity.Region; -import org.apache.ibatis.annotations.Mapper; +/** + * 区划项 映射层。 + * + * @author jiangyc + * @since 2025-11-28 + */ @Mapper public interface RegionMapper extends BaseMapper { + } diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RoleMapper.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RoleMapper.java new file mode 100644 index 0000000..b57cb1f --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/RoleMapper.java @@ -0,0 +1,16 @@ +package day.gitlab.dolphin.rbac.mapper; + +import org.apache.ibatis.annotations.Mapper; +import com.mybatisflex.core.BaseMapper; +import day.gitlab.dolphin.rbac.entity.Role; + +/** + * 角色表 映射层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Mapper +public interface RoleMapper extends BaseMapper { + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/UserMapper.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/UserMapper.java new file mode 100644 index 0000000..c4e504f --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/mapper/UserMapper.java @@ -0,0 +1,22 @@ +package day.gitlab.dolphin.rbac.mapper; + +import com.mybatisflex.core.query.QueryCondition; +import day.gitlab.dolphin.rbac.entity.table.UserTableDef; +import org.apache.ibatis.annotations.Mapper; +import com.mybatisflex.core.BaseMapper; +import day.gitlab.dolphin.rbac.entity.User; + +/** + * 用户表 映射层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Mapper +public interface UserMapper extends BaseMapper { + + default User findByUsername(String username) { + QueryCondition queryCondition = UserTableDef.USER.USERNAME.eq(username); + return selectOneByCondition(queryCondition); + } +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/DepartmentService.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/DepartmentService.java new file mode 100644 index 0000000..a3ce1ac --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/DepartmentService.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.rbac.service; + +import com.mybatisflex.core.service.IService; +import day.gitlab.dolphin.rbac.entity.Department; + +/** + * 部门表 服务层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public interface DepartmentService extends IService { + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RegionService.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RegionService.java index 13efcec..b03a796 100644 --- a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RegionService.java +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RegionService.java @@ -3,5 +3,12 @@ package day.gitlab.dolphin.rbac.service; import com.mybatisflex.core.service.IService; import day.gitlab.dolphin.rbac.entity.Region; +/** + * 区划项 服务层。 + * + * @author jiangyc + * @since 2025-11-28 + */ public interface RegionService extends IService { + } diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RoleService.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RoleService.java new file mode 100644 index 0000000..7454b67 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/RoleService.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.rbac.service; + +import com.mybatisflex.core.service.IService; +import day.gitlab.dolphin.rbac.entity.Role; + +/** + * 角色表 服务层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public interface RoleService extends IService { + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/UserService.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/UserService.java new file mode 100644 index 0000000..b150a98 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/UserService.java @@ -0,0 +1,14 @@ +package day.gitlab.dolphin.rbac.service; + +import com.mybatisflex.core.service.IService; +import day.gitlab.dolphin.rbac.entity.User; + +/** + * 用户表 服务层。 + * + * @author jiangyc + * @since 2025-11-28 + */ +public interface UserService extends IService { + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/DepartmentServiceImpl.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/DepartmentServiceImpl.java new file mode 100644 index 0000000..100cd9c --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/DepartmentServiceImpl.java @@ -0,0 +1,18 @@ +package day.gitlab.dolphin.rbac.service.impl; + +import com.mybatisflex.spring.service.impl.ServiceImpl; +import day.gitlab.dolphin.rbac.entity.Department; +import day.gitlab.dolphin.rbac.mapper.DepartmentMapper; +import day.gitlab.dolphin.rbac.service.DepartmentService; +import org.springframework.stereotype.Service; + +/** + * 部门表 服务层实现。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Service +public class DepartmentServiceImpl extends ServiceImpl implements DepartmentService{ + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RegionServiceImpl.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RegionServiceImpl.java index 1c8267f..ad4e372 100644 --- a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RegionServiceImpl.java +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RegionServiceImpl.java @@ -6,6 +6,13 @@ import day.gitlab.dolphin.rbac.mapper.RegionMapper; import day.gitlab.dolphin.rbac.service.RegionService; import org.springframework.stereotype.Service; +/** + * 区划项 服务层实现。 + * + * @author jiangyc + * @since 2025-11-28 + */ @Service -public class RegionServiceImpl extends ServiceImpl implements RegionService { +public class RegionServiceImpl extends ServiceImpl implements RegionService{ + } diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RoleServiceImpl.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000..c5c736b --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/RoleServiceImpl.java @@ -0,0 +1,18 @@ +package day.gitlab.dolphin.rbac.service.impl; + +import com.mybatisflex.spring.service.impl.ServiceImpl; +import day.gitlab.dolphin.rbac.entity.Role; +import day.gitlab.dolphin.rbac.mapper.RoleMapper; +import day.gitlab.dolphin.rbac.service.RoleService; +import org.springframework.stereotype.Service; + +/** + * 角色表 服务层实现。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Service +public class RoleServiceImpl extends ServiceImpl implements RoleService{ + +} diff --git a/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/UserServiceImpl.java b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..52f3579 --- /dev/null +++ b/dolphin-modules/dolphin-module-rbac/src/main/java/day/gitlab/dolphin/rbac/service/impl/UserServiceImpl.java @@ -0,0 +1,18 @@ +package day.gitlab.dolphin.rbac.service.impl; + +import com.mybatisflex.spring.service.impl.ServiceImpl; +import day.gitlab.dolphin.rbac.entity.User; +import day.gitlab.dolphin.rbac.mapper.UserMapper; +import day.gitlab.dolphin.rbac.service.UserService; +import org.springframework.stereotype.Service; + +/** + * 用户表 服务层实现。 + * + * @author jiangyc + * @since 2025-11-28 + */ +@Service +public class UserServiceImpl extends ServiceImpl implements UserService{ + +} diff --git a/pom.xml b/pom.xml index 931d73b..3d0b030 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ pom - 25 + 21 3.5.8 1.11.4 0.13.0