├── bin ├── reinstall.bat ├── run.bat └── jar.sh ├── newbie-generator ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── newbie │ │ │ └── generator │ │ │ ├── mapper │ │ │ ├── MysqlGeneratorMapper.java │ │ │ ├── Postgresql16GeneratorMapper.java │ │ │ ├── GenConfigMapper.java │ │ │ └── GeneratorMapper.java │ │ │ ├── domain │ │ │ ├── GenerateBody.java │ │ │ ├── FieldInfo.java │ │ │ ├── TableInfo.java │ │ │ ├── ColumnInfo.java │ │ │ ├── GeneratorConfig.java │ │ │ └── GenConfigEntity.java │ │ │ ├── service │ │ │ ├── GeneratorService.java │ │ │ ├── IGenConfigService.java │ │ │ └── impl │ │ │ │ ├── GeneratorServiceImpl.java │ │ │ │ └── GenConfigServiceImpl.java │ │ │ ├── controller │ │ │ ├── GeneratorController.java │ │ │ └── GenConfigController.java │ │ │ └── config │ │ │ └── DbConfig.java │ │ └── resources │ │ ├── mapping.json │ │ ├── generator.properties │ │ ├── templates │ │ ├── entity.java.ftl │ │ ├── api.js.ftl │ │ ├── service.java.ftl │ │ ├── mapper.java.ftl │ │ ├── menu.sql.ftl │ │ ├── serviceImpl.java.ftl │ │ ├── dataForm.vue.ftl │ │ ├── controller.java.ftl │ │ └── mapper.xml.ftl │ │ └── mapper │ │ ├── MysqlGeneratorMapper.xml │ │ └── Postgresql16GeneratorMapper.xml └── pom.xml ├── newbie-system ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── newbie │ │ │ └── system │ │ │ ├── domain │ │ │ ├── body │ │ │ │ ├── SysRoleMenuBody.java │ │ │ │ ├── SysUserRoleBody.java │ │ │ │ └── SysUserBody.java │ │ │ └── vo │ │ │ │ ├── SysMenuVO.java │ │ │ │ ├── SysRoleVO.java │ │ │ │ └── SysDeptVO.java │ │ │ ├── constant │ │ │ └── SysMenuConstant.java │ │ │ ├── service │ │ │ ├── SysRoleMenuService.java │ │ │ ├── SysRoleService.java │ │ │ ├── SysDictTypeService.java │ │ │ ├── impl │ │ │ │ ├── SysRoleMenuServiceImpl.java │ │ │ │ ├── SysDictDataServiceImpl.java │ │ │ │ ├── SysDictTypeServiceImpl.java │ │ │ │ ├── SysRoleServiceImpl.java │ │ │ │ ├── SysUserRoleServiceImpl.java │ │ │ │ ├── SysLogLoginServiceImpl.java │ │ │ │ └── SysLogOperateServiceImpl.java │ │ │ ├── SysLogOperateService.java │ │ │ ├── SysDictDataService.java │ │ │ ├── SysLogLoginService.java │ │ │ ├── SysMenuService.java │ │ │ ├── SysDeptService.java │ │ │ ├── SysUserRoleService.java │ │ │ └── SysUserService.java │ │ │ └── mapper │ │ │ ├── SysDeptMapper.java │ │ │ ├── SysMenuMapper.java │ │ │ ├── SysDictTypeMapper.java │ │ │ ├── SysLogLoginMapper.java │ │ │ ├── SysRoleMenuMapper.java │ │ │ ├── SysLogOperateMapper.java │ │ │ ├── SysRoleMapper.java │ │ │ ├── SysUserRoleMapper.java │ │ │ ├── SysUserMapper.java │ │ │ └── SysDictDataMapper.java │ │ └── resources │ │ └── mapper │ │ ├── SysUserRoleMapper.xml │ │ ├── SysRoleMapper.xml │ │ └── SysDictDataMapper.xml └── pom.xml ├── newbie-weblog ├── src │ └── main │ │ └── java │ │ └── com │ │ └── newbie │ │ └── weblog │ │ ├── enums │ │ └── WebLogStrategyEnum.java │ │ ├── config │ │ └── WebLogConfigProperties.java │ │ ├── conditional │ │ ├── AllApiStrategyConditional.java │ │ └── DefaultStrategyConditional.java │ │ └── aspect │ │ ├── WebLogAspectAdvice.java │ │ ├── WebLogAspect.java │ │ └── AllApiWebLogAspect.java └── pom.xml ├── newbie-file ├── src │ └── main │ │ └── java │ │ └── com │ │ └── newbie │ │ └── file │ │ ├── enums │ │ └── FileServiceSchemeEnum.java │ │ ├── config │ │ ├── MinioConfigProperties.java │ │ └── FileServiceConfig.java │ │ ├── domain │ │ ├── body │ │ │ └── FileBody.java │ │ └── vo │ │ │ └── FileVO.java │ │ └── service │ │ └── FileService.java └── pom.xml ├── newbie-security ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── newbie │ │ │ └── security │ │ │ ├── domain │ │ │ ├── vo │ │ │ │ ├── Captcha.java │ │ │ │ └── ImageCaptcha.java │ │ │ ├── body │ │ │ │ ├── LoginBody.java │ │ │ │ └── PasswordBody.java │ │ │ ├── Route.java │ │ │ └── RouteMeta.java │ │ │ ├── service │ │ │ ├── CaptchaService.java │ │ │ ├── SecurityService.java │ │ │ └── impl │ │ │ │ └── ImageCaptchaServiceImpl.java │ │ │ ├── config │ │ │ ├── StpInterfaceImpl.java │ │ │ └── SaTokenConfigure.java │ │ │ └── mapper │ │ │ └── SecurityMapper.java │ │ └── resources │ │ └── mapper │ │ └── SecurityMapper.xml └── pom.xml ├── newbie-admin ├── src │ ├── main │ │ ├── resources │ │ │ ├── application-apidoc.yml │ │ │ ├── application.yml │ │ │ ├── banner.txt │ │ │ ├── application-prod.yml │ │ │ └── application-dev.yml │ │ └── java │ │ │ └── com │ │ │ └── newbie │ │ │ ├── lifecycle │ │ │ ├── DisposableBeanImpl.java │ │ │ └── CommandLineRunnerImpl.java │ │ │ ├── NewbieApplication.java │ │ │ └── controller │ │ │ ├── file │ │ │ └── FileController.java │ │ │ ├── system │ │ │ ├── SysDeptController.java │ │ │ ├── SysMenuController.java │ │ │ ├── SysRoleMenuController.java │ │ │ ├── SysUserController.java │ │ │ └── SysRoleController.java │ │ │ └── monitor │ │ │ ├── SysLogOperateController.java │ │ │ └── SysLogLoginController.java │ └── test │ │ └── java │ │ └── com │ │ └── newbie │ │ └── ApplicationTest.java └── pom.xml ├── newbie-common ├── src │ └── main │ │ └── java │ │ └── com │ │ └── newbie │ │ └── common │ │ ├── annotation │ │ ├── IgnoreWebLog.java │ │ └── WebLog.java │ │ ├── constant │ │ ├── SecurityConstant.java │ │ └── LoginMethodConstant.java │ │ ├── domain │ │ ├── entity │ │ │ ├── SysRoleMenu.java │ │ │ ├── SysUserRole.java │ │ │ ├── SysDictType.java │ │ │ ├── SysRole.java │ │ │ ├── SysDictData.java │ │ │ ├── SysDept.java │ │ │ ├── SysUser.java │ │ │ ├── BaseEntity.java │ │ │ ├── SysLogOperate.java │ │ │ ├── SysLogLogin.java │ │ │ └── SysMenu.java │ │ ├── JvmInfo.java │ │ ├── DisksInfo.java │ │ ├── NetworkInfo.java │ │ ├── LoginUser.java │ │ ├── OSRuntimeInfo.java │ │ └── OSInfo.java │ │ ├── util │ │ ├── ServletUtils.java │ │ ├── R.java │ │ ├── CamelCaseConverter.java │ │ └── SecurityUtils.java │ │ ├── enums │ │ └── CommonStatusEnum.java │ │ ├── config │ │ ├── RedisConfig.java │ │ ├── MetaObjectHandlerImpl.java │ │ └── MybatisPlusConfig.java │ │ ├── exception │ │ └── NewbieException.java │ │ └── handle │ │ └── GlobalExceptionHandle.java └── pom.xml ├── .gitignore ├── LICENSE └── README.md /bin/reinstall.bat: -------------------------------------------------------------------------------- 1 | cd .. 2 | mvn clean install -Dmaven.test.skip=true -------------------------------------------------------------------------------- /bin/run.bat: -------------------------------------------------------------------------------- 1 | cd ../newbie-admin/target 2 | title NewbieBoot3 3 | java -jar newbie-admin-0.0.1-SNAPSHOT.jar -Dserver.port=8080 -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/mapper/MysqlGeneratorMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.mapper; 2 | 3 | import org.apache.ibatis.annotations.Mapper; 4 | 5 | @Mapper 6 | public interface MysqlGeneratorMapper extends GeneratorMapper{ 7 | } 8 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/domain/GenerateBody.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.domain; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class GenerateBody { 7 | private String[] tableNames; 8 | private String configId; 9 | } 10 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/mapper/Postgresql16GeneratorMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.mapper; 2 | 3 | import org.apache.ibatis.annotations.Mapper; 4 | 5 | @Mapper 6 | public interface Postgresql16GeneratorMapper extends GeneratorMapper{ 7 | 8 | } 9 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/domain/body/SysRoleMenuBody.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.domain.body; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | @Data 8 | public class SysRoleMenuBody { 9 | private String roleId; 10 | private List menuIds; 11 | } 12 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/domain/body/SysUserRoleBody.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.domain.body; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | @Data 8 | public class SysUserRoleBody { 9 | private List userIds; 10 | private List roleIds; 11 | } 12 | -------------------------------------------------------------------------------- /newbie-weblog/src/main/java/com/newbie/weblog/enums/WebLogStrategyEnum.java: -------------------------------------------------------------------------------- 1 | package com.newbie.weblog.enums; 2 | 3 | /** 4 | * WebLog策略枚举 5 | */ 6 | public enum WebLogStrategyEnum { 7 | /** 8 | * 默认 9 | * 记录带有 WebLog 注解的接口的日志 10 | */ 11 | DEFAULT, 12 | /** 13 | * 记录所有接口的日志 14 | */ 15 | ALL_API 16 | } 17 | -------------------------------------------------------------------------------- /newbie-file/src/main/java/com/newbie/file/enums/FileServiceSchemeEnum.java: -------------------------------------------------------------------------------- 1 | package com.newbie.file.enums; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * 6 | * @Author: ZhangYuGe 7 | * @Email 398698424@qq.com 8 | * @Date: 2024/4/30 下午3:43 9 | * @Descriptions: 文件服务方案枚举 10 | */ 11 | public enum FileServiceSchemeEnum { 12 | DEFAULT // 服务器本地磁盘 13 | , 14 | MINIO // 使用minio 15 | } 16 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/domain/vo/Captcha.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.domain.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Calendar; 6 | 7 | /** 8 | * Created by IntelliJ IDEA. 9 | * 10 | * @Author: ZhangYuGe 11 | * @Email 398698424@qq.com 12 | * @Date: 2024/4/23 上午11:14 13 | * @Descriptions: unknown 14 | */ 15 | @Data 16 | public class Captcha { 17 | } 18 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/domain/vo/SysMenuVO.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.domain.vo; 2 | 3 | import com.newbie.common.domain.entity.SysMenu; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | import java.util.List; 8 | 9 | @EqualsAndHashCode(callSuper = true) 10 | @Data 11 | public class SysMenuVO extends SysMenu { 12 | private List children; 13 | } 14 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/domain/vo/SysRoleVO.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.domain.vo; 2 | 3 | import com.newbie.common.domain.entity.SysRole; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import java.util.List; 8 | 9 | @Getter 10 | @Setter 11 | public class SysRoleVO extends SysRole { 12 | /** 13 | * 菜单 id 列表 14 | */ 15 | private List menuIds; 16 | } 17 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/domain/vo/SysDeptVO.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.domain.vo; 2 | 3 | import com.newbie.common.domain.entity.SysDept; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | import java.util.List; 8 | 9 | 10 | @EqualsAndHashCode(callSuper = true) 11 | @Data 12 | public class SysDeptVO extends SysDept { 13 | 14 | /** 子节点 */ 15 | private List children; 16 | } 17 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/constant/SysMenuConstant.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.constant; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * 6 | * @Author: ZhangYuGe 7 | * @Email 398698424@qq.com 8 | * @Date: 2024/4/17 上午10:15 9 | * @Descriptions: 系统菜单常量 10 | */ 11 | public class SysMenuConstant { 12 | public static final String MENU_TYPE_BUTTON = "0"; 13 | 14 | public static final String MENU_TYPE_MENU = "1"; 15 | } 16 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/domain/body/SysUserBody.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.domain.body; 2 | 3 | import com.newbie.common.domain.entity.SysUser; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | import java.util.List; 8 | 9 | 10 | @EqualsAndHashCode(callSuper = true) 11 | @Data 12 | public class SysUserBody extends SysUser { 13 | private String loginPwd; 14 | private List rolesIds; 15 | } 16 | -------------------------------------------------------------------------------- /newbie-admin/src/main/resources/application-apidoc.yml: -------------------------------------------------------------------------------- 1 | # springdoc-openapi项目配置 2 | springdoc: 3 | group-configs: 4 | - group: '文件服务' 5 | # paths-to-match: '/file/**' 6 | packages-to-scan: com.newbie.controller.file 7 | - group: '系统管理' 8 | packages-to-scan: com.newbie.controller.system 9 | - group: '安全控制' 10 | packages-to-scan: com.newbie.controller.security 11 | 12 | # knife4j的增强配置,不需要增强可以不配 13 | knife4j: 14 | enable: false -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysRoleMenuService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.newbie.common.domain.entity.SysRoleMenu; 5 | 6 | /** 7 | * @author 39869 8 | * @description 针对表【sys_role_menu(角色菜单关系表)】的数据库操作Service 9 | * @createDate 2024-04-16 15:30:47 10 | */ 11 | public interface SysRoleMenuService extends IService { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/annotation/IgnoreWebLog.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 此注解使用在 controller 层 7 | * 可以使用在类上或者方法上 8 | * 使用在类上时,此 controller 类下的所有接口方法不记录日志 9 | * 使用在方法上,此接口方法不记录日志 10 | */ 11 | @Target({ElementType.TYPE, ElementType.METHOD}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | @Inherited 15 | public @interface IgnoreWebLog {} 16 | -------------------------------------------------------------------------------- /newbie-admin/src/test/java/com/newbie/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.newbie; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * 9 | * @Author: ZhangYuGe 10 | * @Email 398698424@qq.com 11 | * @Date: 2024/5/25 下午3:09 12 | * @Descriptions: 应用测试 13 | */ 14 | @SpringBootTest 15 | public class ApplicationTest { 16 | 17 | @Test 18 | void test(){ 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/constant/SecurityConstant.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.constant; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * 6 | * @Author: ZhangYuGe 7 | * @Email 398698424@qq.com 8 | * @Date: 2024/4/18 下午1:02 9 | * @Descriptions: 安全控制常量 10 | */ 11 | public class SecurityConstant { 12 | // 系统管理员用户名 13 | public static final String ADMIN_USER_NAME = "admin"; 14 | // 系统用户登录缓存key 15 | public static final String SYS_USER_KEY = "user"; 16 | } 17 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/annotation/WebLog.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 此注解使用在 controller 层 7 | * 可以使用在类上或者方法上 8 | * 使用在类上时,此 controller 类下的所有接口方法记录日志 9 | * 使用在方法上,此接口方法记录日志 10 | */ 11 | @Target({ElementType.TYPE, ElementType.METHOD}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | @Inherited 15 | public @interface WebLog { 16 | String description() default ""; 17 | } 18 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/domain/FieldInfo.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 字段信息 7 | */ 8 | @Data 9 | public class FieldInfo { 10 | private String name; // 字段名 11 | private String type; // 类型 12 | private String comment; // 注释 13 | private Boolean pk; // 是否主键 14 | private String colName; // 数据库列名 15 | private String getMethodName; // get方法名 16 | private String setMethodName; // set方法名 17 | } 18 | -------------------------------------------------------------------------------- /newbie-file/src/main/java/com/newbie/file/config/MinioConfigProperties.java: -------------------------------------------------------------------------------- 1 | package com.newbie.file.config; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * 8 | * @Author: ZhangYuGe 9 | * @Email 398698424@qq.com 10 | * @Date: 2024/4/30 下午3:41 11 | * @Descriptions: minio配置参数 12 | */ 13 | @Data 14 | public class MinioConfigProperties { 15 | private String endPoint; 16 | private String accessKey; 17 | private String secretKey; 18 | private String bucket; 19 | } 20 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/domain/TableInfo.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serial; 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | /** 10 | * 表信息 11 | */ 12 | @Data 13 | public class TableInfo implements Serializable { 14 | @Serial 15 | private static final long serialVersionUID = 1L; 16 | 17 | private String name; // 表名 18 | private String comment; // 表注释 19 | private List columns; // 字段列表 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/mapper/GenConfigMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.newbie.generator.domain.GenConfigEntity; 6 | import jakarta.annotation.Nullable; 7 | import org.apache.ibatis.annotations.Mapper; 8 | 9 | import java.io.Serializable; 10 | import java.util.List; 11 | 12 | @Mapper 13 | public interface GenConfigMapper extends BaseMapper { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysDeptMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.newbie.common.domain.entity.SysDept; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | * @author 39869 9 | * @description 针对表【sys_dept(部门表)】的数据库操作Mapper 10 | * @createDate 2024-04-16 23:21:27 11 | * @Entity generator.domain.SysDept 12 | */ 13 | @Mapper 14 | public interface SysDeptMapper extends BaseMapper { 15 | 16 | } 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysMenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.newbie.common.domain.entity.SysMenu; 6 | import org.apache.ibatis.annotations.Mapper; 7 | 8 | /** 9 | * @author 39869 10 | * @description 针对表【sys_menu(系统菜单表)】的数据库操作Mapper 11 | * @createDate 2024-04-16 15:12:01 12 | * @Entity generator.domain.SysMenu 13 | */ 14 | @Mapper 15 | public interface SysMenuMapper extends BaseMapper { 16 | 17 | } 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/domain/vo/ImageCaptcha.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.domain.vo; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * 9 | * @Author: ZhangYuGe 10 | * @Email 398698424@qq.com 11 | * @Date: 2024/4/23 上午10:49 12 | * @Descriptions: unknown 13 | */ 14 | @EqualsAndHashCode(callSuper = true) 15 | @Data 16 | public class ImageCaptcha extends Captcha{ 17 | private String checkCodeKey; // 验证码key 18 | private String imageBase64; // 验证码图片base64 19 | } 20 | -------------------------------------------------------------------------------- /newbie-file/src/main/java/com/newbie/file/domain/body/FileBody.java: -------------------------------------------------------------------------------- 1 | package com.newbie.file.domain.body; 2 | 3 | import lombok.Data; 4 | import org.springframework.web.multipart.MultipartFile; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * Created by IntelliJ IDEA. 11 | * 12 | * @Author: ZhangYuGe 13 | * @Email 398698424@qq.com 14 | * @Date: 2024/4/30 上午9:12 15 | * @Descriptions: unknown 16 | */ 17 | @Data 18 | public class FileBody { 19 | private List file; // 文件列表 20 | private Map params; // 其它参数 21 | } 22 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysDictTypeMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.newbie.common.domain.entity.SysDictType; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | * @author 39869 9 | * @description 针对表【sys_dict_type(系统字典类型)】的数据库操作Mapper 10 | * @createDate 2024-04-16 23:21:27 11 | * @Entity generator.domain.SysDictType 12 | */ 13 | @Mapper 14 | public interface SysDictTypeMapper extends BaseMapper { 15 | 16 | } 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysLogLoginMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.newbie.common.domain.entity.SysLogLogin; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | * @author 39869 9 | * @description 针对表【sys_log_login(系统登录日志)】的数据库操作Mapper 10 | * @createDate 2024-05-20 16:09:37 11 | * @Entity generator.domain.SysLogLogin 12 | */ 13 | @Mapper 14 | public interface SysLogLoginMapper extends BaseMapper { 15 | 16 | } 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/domain/body/LoginBody.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.domain.body; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * 8 | * @Author: ZhangYuGe 9 | * @Email 398698424@qq.com 10 | * @Date: 2024/4/16 12:18 11 | * @Descriptions: 登录请求体 12 | */ 13 | @Data 14 | public class LoginBody { 15 | private String utext; // 用户名 16 | private String ptext; // 密码 17 | private Long tokenTimeout; // token有效期,单位:秒 18 | private String checkCode; // 验证码 19 | private String checkCodeKey; // 验证码缓存的key 20 | } 21 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysRoleMenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.newbie.common.domain.entity.SysRoleMenu; 6 | import org.apache.ibatis.annotations.Mapper; 7 | 8 | /** 9 | * @author 39869 10 | * @description 针对表【sys_role_menu(角色菜单关系表)】的数据库操作Mapper 11 | * @createDate 2024-04-16 15:12:01 12 | * @Entity generator.domain.SysRoleMenu 13 | */ 14 | @Mapper 15 | public interface SysRoleMenuMapper extends BaseMapper { 16 | 17 | } 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/lifecycle/DisposableBeanImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.lifecycle; 2 | 3 | import org.springframework.beans.factory.DisposableBean; 4 | import org.springframework.stereotype.Component; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * 9 | * @Author: ZhangYuGe 10 | * @Email 398698424@qq.com 11 | * @Date: 2024/4/17 下午4:29 12 | * @Descriptions: unknown 13 | */ 14 | @Component 15 | public class DisposableBeanImpl implements DisposableBean { 16 | @Override 17 | public void destroy() { 18 | System.err.println("退出程序"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysLogOperateMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.newbie.common.domain.entity.SysLogOperate; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | * @author 39869 9 | * @description 针对表【sys_log_operat(系统操作日志)】的数据库操作Mapper 10 | * @createDate 2024-05-18 18:03:34 11 | * @Entity generator.domain.SysLogOperat 12 | */ 13 | @Mapper 14 | public interface SysLogOperateMapper extends BaseMapper { 15 | 16 | } 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysRoleService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.newbie.common.domain.entity.SysRole; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author 39869 10 | * @description 针对表【sys_role(角色表)】的数据库操作Service 11 | * @createDate 2024-04-16 15:30:47 12 | */ 13 | public interface SysRoleService extends IService { 14 | 15 | /** 16 | * 批量删除 17 | * @param idList ID列表 18 | */ 19 | void deleteBatch(List idList); 20 | } 21 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/domain/ColumnInfo.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serial; 6 | import java.io.Serializable; 7 | 8 | /** 9 | * 表字段信息 10 | */ 11 | @Data 12 | public class ColumnInfo implements Serializable { 13 | @Serial 14 | private static final long serialVersionUID = 1L; 15 | private String name; // 字段名 16 | private String nullable; // 是否可以为null,1是,0否 17 | private String type; // 数据类型 18 | private String pk; // 是否为主键字段,1是,0否 19 | private String comment; // 字段注释 20 | 21 | } 22 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/domain/body/PasswordBody.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.domain.body; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * 8 | * @Author: ZhangYuGe 9 | * @Email 398698424@qq.com 10 | * @Date: 2024/4/16 16:13 11 | * @Descriptions: unknown 12 | */ 13 | @Data 14 | public class PasswordBody { 15 | private String userId; // 用户ID 16 | private String otext; // 原密码 17 | private String ntext; // 新密码 18 | private String ctext; // 确认密码 19 | private Boolean immediatelyKick; // 立即踢出,修改用户密码时,修改成功后是否立即踢下线 20 | } 21 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/constant/LoginMethodConstant.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.constant; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * 6 | * @Author: ZhangYuGe 7 | * @Email 398698424@qq.com 8 | * @Date: 2024/5/20 下午5:19 9 | * @Descriptions: 登录方式 10 | */ 11 | public class LoginMethodConstant { 12 | public static final String USERNAME = "username"; // 用户名密码方式登录 13 | public static final String PHONE_SMS="phone_sms"; // 手机号短信验证码方式登录 14 | public static final String EMAIL="email"; // 邮箱登录 15 | public static final String OAUTH2="oauth2"; // oauth2登录 16 | } 17 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysRoleMenu.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | * 角色菜单关系表 9 | * @TableName sys_role_menu 10 | */ 11 | @EqualsAndHashCode(callSuper = true) 12 | @TableName(value ="sys_role_menu") 13 | @Data 14 | public class SysRoleMenu extends BaseEntity { 15 | 16 | 17 | /** 18 | * 角色ID 19 | */ 20 | private String roleId; 21 | 22 | /** 23 | * 菜单ID 24 | */ 25 | private String menuId; 26 | } -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysUserRole.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | * 用户和角色关系表 9 | * @TableName sys_user_role 10 | */ 11 | @EqualsAndHashCode(callSuper = true) 12 | @TableName(value ="sys_user_role") 13 | @Data 14 | public class SysUserRole extends BaseEntity { 15 | 16 | /** 17 | * 用户ID 18 | */ 19 | private String userId; 20 | 21 | /** 22 | * 角色ID 23 | */ 24 | private String roleId; 25 | 26 | } -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysDictTypeService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | import com.newbie.common.domain.entity.SysDictType; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author 39869 10 | * @description 针对表【sys_dict_type(系统字典类型)】的数据库操作Service 11 | * @createDate 2024-04-16 23:21:27 12 | */ 13 | public interface SysDictTypeService extends IService { 14 | 15 | /** 16 | * 批量删除字典类型 17 | * @param idList 字典类型ID列表 18 | */ 19 | void deleteBatch(List idList); 20 | } 21 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "packageMapping":{ 3 | "Date": "java.util.Date", 4 | "BigDecimal": "java.math.BigDecimal" 5 | }, 6 | "typeMapping":{ 7 | "varchar":"String", 8 | "int":"Integer", 9 | "int2":"Integer", 10 | "int4":"Integer", 11 | "int8":"Long", 12 | "timestamp":"Date", 13 | "datetime":"Date", 14 | "date":"Date", 15 | "float4":"Float", 16 | "float8":"Double", 17 | "numeric":"BigDecimal", 18 | "text":"String", 19 | "bool":"Boolean", 20 | "boolean":"Boolean", 21 | "bpchar":"String", 22 | "char": "String" 23 | } 24 | } -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/service/GeneratorService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.service; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.newbie.generator.domain.GenerateBody; 6 | import com.newbie.generator.domain.TableInfo; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * 代码生成器服务接口 13 | */ 14 | public interface GeneratorService { 15 | void generatorCode(GenerateBody generateBody, HttpServletResponse response); 16 | IPage getDbTableList(IPage page,TableInfo tableInfo); 17 | } 18 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/JvmInfo.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * JAVA/JVM信息 7 | */ 8 | @Data 9 | public class JvmInfo 10 | { 11 | /** 12 | * 当前JVM占用的内存总数(M) 13 | */ 14 | private long total; 15 | 16 | /** 17 | * JVM最大可用内存总数(M) 18 | */ 19 | private long max; 20 | 21 | /** 22 | * JVM空闲内存(M) 23 | */ 24 | private long free; 25 | 26 | /** 27 | * JDK版本 28 | */ 29 | private String version; 30 | 31 | /** 32 | * JDK路径 33 | */ 34 | private String home; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /newbie-file/src/main/java/com/newbie/file/domain/vo/FileVO.java: -------------------------------------------------------------------------------- 1 | package com.newbie.file.domain.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * Created by IntelliJ IDEA. 9 | * 10 | * @Author: ZhangYuGe 11 | * @Email 398698424@qq.com 12 | * @Date: 2024/4/30 上午9:54 13 | * @Descriptions: unknown 14 | */ 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class FileVO { 19 | private String originalName; // 文件原名称 20 | private String filePath; // 文件路径 21 | private Long fileSize; // 文件大小 22 | private String fileType; // 文件类型 23 | } 24 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/domain/GeneratorConfig.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 生成器配置 7 | */ 8 | @Data 9 | public class GeneratorConfig { 10 | private String commentAuthor; // 作者名-注释 11 | private String commentEmail; // 邮箱-注释 12 | private String commentDate; // 日期格式-注释 13 | private String outputDir; // 生成文件的输出目录 14 | private String packageParent; // 父级包名 15 | private String moduleName; // 模块名 16 | private String prefix; // 需要忽略的表前缀,多个以逗号分割 17 | private Boolean enableSpringdoc; // 使用接口文档 18 | private Boolean enableApiAuth; // 开启接口权限控制 19 | private Boolean enableDrawer; // 数据表单使用抽屉组件,默认使用dialog 20 | } 21 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/service/CaptchaService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.service; 2 | 3 | import com.newbie.security.domain.vo.Captcha; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * 8 | * @Author: ZhangYuGe 9 | * @Email 398698424@qq.com 10 | * @Date: 2024/4/23 上午11:12 11 | * @Descriptions: 验证码服务 12 | */ 13 | public interface CaptchaService { 14 | /** 15 | * 创建验证码 16 | * @param key 验证码缓存的key 17 | * @return 18 | */ 19 | Captcha create(String key); 20 | 21 | /** 22 | * 校验验证码 23 | * @param userInputCode 验证码 24 | * @param key 验证码缓存的key 25 | * @return 是否匹配 26 | */ 27 | boolean verify(String key,String userInputCode); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.newbie.common.domain.entity.SysRole; 6 | import org.apache.ibatis.annotations.Mapper; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author 39869 12 | * @description 针对表【sys_role(角色表)】的数据库操作Mapper 13 | * @createDate 2024-04-16 15:12:01 14 | * @Entity generator.domain.SysRole 15 | */ 16 | @Mapper 17 | public interface SysRoleMapper extends BaseMapper { 18 | 19 | /** 20 | * 根据用户ID角色列表 21 | * @param userId 用户ID 22 | * @return 角色列表 23 | */ 24 | List selectListByUserId(String userId); 25 | } 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/impl/SysRoleMenuServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | 5 | import com.newbie.common.domain.entity.SysRoleMenu; 6 | import com.newbie.system.mapper.SysRoleMenuMapper; 7 | import com.newbie.system.service.SysRoleMenuService; 8 | import org.springframework.stereotype.Service; 9 | 10 | /** 11 | * @author 39869 12 | * @description 针对表【sys_role_menu(角色菜单关系表)】的数据库操作Service实现 13 | * @createDate 2024-04-16 15:30:47 14 | */ 15 | @Service 16 | public class SysRoleMenuServiceImpl extends ServiceImpl 17 | implements SysRoleMenuService { 18 | 19 | } 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysLogOperateService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.newbie.common.domain.entity.SysLogOperate; 5 | 6 | /** 7 | * @author 39869 8 | * @description 针对表【sys_log_operat(系统操作日志)】的数据库操作Service 9 | * @createDate 2024-05-18 18:03:34 10 | */ 11 | public interface SysLogOperateService extends IService { 12 | 13 | /** 14 | * 保存操作日志 15 | * @param targetFun 目标类方法 16 | * @param startTimeMillis 开始时间戳 17 | * @param throwable 异常对象 18 | */ 19 | void saveSysLogOperate(String targetFun,long startTimeMillis,Throwable throwable); 20 | 21 | void saveSysLogOperate(String targetFun,long startTimeMillis); 22 | } 23 | -------------------------------------------------------------------------------- /newbie-admin/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | servlet: 4 | context-path: / 5 | shutdown: graceful 6 | spring: 7 | profiles: 8 | active: dev,apidoc 9 | main: 10 | # 相同的bean是否覆盖 11 | allow-bean-definition-overriding: true 12 | jackson: 13 | # 日期格式统一配置 14 | date-format: yyyy-MM-dd HH:mm:ss 15 | # 时区配置 16 | time-zone: Asia/Shanghai 17 | application: 18 | name: NewbieAdmin 19 | version: 0.0.1 20 | servlet: 21 | multipart: 22 | max-file-size: 200MB 23 | maxRequestSize: 200MB 24 | web: 25 | resources: 26 | static-locations: classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/, file:${newbie.file.file-location} 27 | mybatis-plus: 28 | global-config: 29 | banner: false 30 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/DisksInfo.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 磁盘信息封装类 7 | * 8 | */ 9 | @Data 10 | public class DisksInfo { 11 | 12 | /** 13 | * 文件系统的挂载点 14 | */ 15 | private String dirName; 16 | 17 | /** 18 | * 文件系统名称 19 | */ 20 | private String sysTypeName; 21 | 22 | /** 23 | * 文件系统的类型(FAT,NTFS,etx2,ext4等) 24 | */ 25 | private String typeName; 26 | 27 | /** 28 | * 总大小 29 | */ 30 | private long total; 31 | 32 | /** 33 | * 剩余大小 34 | */ 35 | private long free; 36 | 37 | /** 38 | * 已经使用量 39 | */ 40 | private long used; 41 | 42 | /** 43 | * 资源的使用率 44 | */ 45 | private double usage = 100; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/NetworkInfo.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 网卡信息包装类 7 | * 8 | */ 9 | @Data 10 | public class NetworkInfo { 11 | 12 | /** 13 | * ipv4地址 14 | */ 15 | private String ipv4Address; 16 | 17 | /** 18 | * ipv6地址 19 | */ 20 | private String ipv6Address; 21 | 22 | /** 23 | * mac地址 24 | */ 25 | private String macAddress; 26 | 27 | /** 28 | * 网卡名称 29 | */ 30 | private String networkName; 31 | 32 | /** 33 | * 发送数据量 34 | */ 35 | private long send; 36 | 37 | /** 38 | * 接受数据量 39 | */ 40 | private long accept; 41 | 42 | /** 43 | * 网卡时间戳 44 | */ 45 | private long timeStamp; 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysDictDataService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | import com.newbie.common.domain.entity.SysDictData; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author 39869 10 | * @description 针对表【sys_dict_data(系统字典数据)】的数据库操作Service 11 | * @createDate 2024-04-16 23:21:27 12 | */ 13 | public interface SysDictDataService extends IService { 14 | 15 | /** 16 | * 根据数据ID修改此数据为默认,此数据同分类下其它数据取消默认 17 | * @param id 数据ID 18 | */ 19 | void updateDictDataAsDefault(String id); 20 | 21 | /** 22 | * 根据分类编码获取数据列表 23 | * @param typeCode 分类编码 24 | * @return 是否成功 25 | */ 26 | List getDictDataListByTypeCode(String typeCode); 27 | } 28 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/domain/Route.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.domain; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by IntelliJ IDEA. 11 | * 12 | * @Author: ZhangYuGe 13 | * @Email 398698424@qq.com 14 | * @Date: 2024/4/16 19:24 15 | * @Descriptions: unknown 16 | */ 17 | @Data 18 | @Builder 19 | public class Route { 20 | private String path; // 路由地址 21 | private String name; // 路由名称 22 | private String component; // 组件路径 23 | private RouteMeta meta; // 路由元信息 24 | private String redirect; // 重定向 25 | 26 | @JsonIgnore 27 | private String id; 28 | @JsonIgnore 29 | private String pid; 30 | private List children; 31 | } 32 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/domain/RouteMeta.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.domain; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * 9 | * @Author: ZhangYuGe 10 | * @Email 398698424@qq.com 11 | * @Date: 2024/4/16 19:25 12 | * @Descriptions: 路由元数据 13 | */ 14 | @Data 15 | @Builder 16 | public class RouteMeta { 17 | private String title; // 标题。(必填) 18 | private String icon; // 图标 19 | private Boolean isHide; // 是否隐藏 20 | private Boolean hideChildren; // 隐藏子级 21 | private String iframeLink; // iframe 链接 22 | private Boolean isOuter; // 是否大屏页面 23 | private Integer sortNo; // 排序号 24 | private Boolean isKeep; // 是否缓存页面 25 | private String transition; // 过渡动画 26 | private Boolean fixedTab; // 固定在tabs 27 | } 28 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysDictType.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | * 系统字典类型 9 | * @TableName sys_dict_type 10 | */ 11 | @EqualsAndHashCode(callSuper = true) 12 | @TableName(value ="sys_dict_type") 13 | @Data 14 | public class SysDictType extends BaseEntity{ 15 | 16 | 17 | /** 18 | * 字典类型名称 19 | */ 20 | private String typeName; 21 | 22 | /** 23 | * 类型编码 24 | */ 25 | private String typeCode; 26 | 27 | /** 28 | * 状态(1正常 0禁用) 29 | */ 30 | private String status; 31 | 32 | /** 33 | * 排序字段 34 | */ 35 | private Integer sort; 36 | 37 | /** 38 | * 备注 39 | */ 40 | private String remark; 41 | 42 | } -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysLogLoginService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.newbie.common.domain.entity.SysLogLogin; 5 | /** 6 | * @author 39869 7 | * @description 针对表【sys_log_login(系统登录日志)】的数据库操作Service 8 | * @createDate 2024-05-20 16:09:37 9 | */ 10 | public interface SysLogLoginService extends IService { 11 | 12 | void saveLoginLog(String username,long startTimeMillis,String type,String loginMethod); 13 | 14 | 15 | /** 16 | * 存登录日志 17 | * @param username 用户名 18 | * @param startTimeMillis 开始时间戳 19 | * @param type 1 登入,0 登出 20 | * @param loginMethod 登录方式 21 | * @param e 异常对象 22 | */ 23 | void saveLoginLog(String username,long startTimeMillis,String type,String loginMethod, Throwable e); 24 | } 25 | -------------------------------------------------------------------------------- /newbie-weblog/src/main/java/com/newbie/weblog/config/WebLogConfigProperties.java: -------------------------------------------------------------------------------- 1 | package com.newbie.weblog.config; 2 | 3 | import com.newbie.weblog.enums.WebLogStrategyEnum; 4 | import lombok.Data; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Data 9 | @Configuration 10 | @ConfigurationProperties("newbie.weblog") 11 | public class WebLogConfigProperties { 12 | 13 | /** 14 | * 是否启用日志记录 15 | */ 16 | private Boolean enable = false; 17 | 18 | /** 19 | * 记录日志策略 20 | */ 21 | private WebLogStrategyEnum defaultStrategy = WebLogStrategyEnum.DEFAULT; 22 | 23 | /** 24 | * 指定环境生效,不指定则所有环境生效 25 | */ 26 | private String env; 27 | 28 | /** 29 | * 仅在异常时记录日志 30 | */ 31 | private Boolean onlyError = false; 32 | } 33 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysUserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.newbie.common.domain.entity.SysUserRole; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author 39869 13 | * @description 针对表【sys_user_role(用户和角色关系表)】的数据库操作Mapper 14 | * @createDate 2024-04-16 15:12:01 15 | * @Entity generator.domain.SysUserRole 16 | */ 17 | @Mapper 18 | public interface SysUserRoleMapper extends BaseMapper { 19 | void removeByUserIdAndRoleIds(@Param("userId") String userId, @Param("roleIds") List roleIds); 20 | 21 | void removeByRoleIdAndUserIds(@Param("roleId") String roleId, @Param("userIds") List userIds); 22 | } 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/generator.properties: -------------------------------------------------------------------------------- 1 | # 数据源 2 | datasource.url=jdbc:mysql://localhost:3306/newbie3?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8&allowMultiQueries=true 3 | datasource.username=root 4 | datasource.password=root 5 | # 禁止自动打开目录 6 | global.disableOpenDir=true 7 | # 输入到目录路径 8 | global.outputDir=D:/project/demo/codegen/nb-system/src/main/java/ 9 | # 作者 10 | global.author=ZhangYuGe 11 | # 注释日期格式 12 | global.commentDate=yyyy-MM-dd HH:mm:ss 13 | #接口文档 14 | global.enableSpringdoc=true 15 | # 父包名 16 | package.parent=com.newbie 17 | # 模块名 18 | package.moduleName=system 19 | # 表名,可多个,逗号分隔 20 | strategy.include=t_student 21 | # 表前缀,可多个,逗号分隔 22 | strategy.tablePrefix=t_,c_ 23 | # 邮箱 24 | newbie.email=398698424@qq.com 25 | # 开启接口鉴权 26 | newbie.enableApiAuth=true 27 | # 数据表单使用抽屉组件,默认使用dialog 28 | newbie.enableDrawer=false 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysRole.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | * 角色表 9 | * @TableName sys_role 10 | */ 11 | @EqualsAndHashCode(callSuper = true) 12 | @TableName(value ="sys_role") 13 | @Data 14 | public class SysRole extends BaseEntity { 15 | 16 | 17 | /** 18 | * 角色名称 19 | */ 20 | private String roleName; 21 | 22 | /** 23 | * 角色编码 24 | */ 25 | private String roleCode; 26 | 27 | /** 28 | * 排序顺序 29 | */ 30 | private Integer sort; 31 | 32 | /** 33 | * 角色状态(1正常 0停用) 34 | */ 35 | private String status; 36 | 37 | /** 38 | * 首页路由地址 39 | */ 40 | private String homePath; 41 | 42 | /** 43 | * 备注 44 | */ 45 | private String remark; 46 | 47 | } -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/templates/entity.java.ftl: -------------------------------------------------------------------------------- 1 | package ${package.entity}; 2 | 3 | <#list entityImportPackages as pkg> 4 | import ${pkg}; 5 | 6 | 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableId; 9 | import com.baomidou.mybatisplus.annotation.TableName; 10 | import lombok.Data; 11 | 12 | import java.io.Serial; 13 | import java.io.Serializable; 14 | 15 | /** 16 | * Created by NewbieGenerator. 17 | * 18 | * @Author: ${gc.author} 19 | * @Email ${gc.email} 20 | * @Date: ${gc.date} 21 | * @Descriptions: ${comment!} 实体类 22 | */ 23 | @TableName(value = "${tableName}") 24 | @Data 25 | public class ${Entity}Entity implements Serializable { 26 | @Serial 27 | private static final long serialVersionUID = 1L; 28 | <#list fields as field> 29 | <#if field.pk> 30 | @TableId(type = IdType.ASSIGN_ID) 31 | 32 | private ${field.type} ${field.name}; // ${field.comment!} 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /newbie-file/src/main/java/com/newbie/file/service/FileService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.file.service; 2 | 3 | import com.newbie.file.domain.vo.FileVO; 4 | import jakarta.servlet.http.HttpServletResponse; 5 | import org.springframework.web.multipart.MultipartFile; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by IntelliJ IDEA. 11 | * 12 | * @Author: ZhangYuGe 13 | * @Email 398698424@qq.com 14 | * @Date: 2024/4/23 下午6:47 15 | * @Descriptions: 文件服务 16 | */ 17 | public interface FileService { 18 | /** 19 | * 上传文件 20 | * @param files 文件对象列表 21 | * @return 文件路径与名称 22 | */ 23 | List upload(List files); 24 | 25 | 26 | /** 27 | * 下载文件 28 | * 29 | * @param filePath 文件路径 30 | * @param response 31 | */ 32 | void download(String filePath, HttpServletResponse response); 33 | 34 | /** 35 | * 删除文件 36 | * @param filePath 文件路径 37 | */ 38 | void remove(String filePath); 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/NewbieApplication.java: -------------------------------------------------------------------------------- 1 | package com.newbie; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cache.annotation.EnableCaching; 6 | import org.springframework.scheduling.annotation.EnableAsync; 7 | import org.springframework.scheduling.annotation.EnableScheduling; 8 | 9 | /** 10 | * Created by IntelliJ IDEA. 11 | * 12 | * @Author: ZhangYuGe 13 | * @Email 398698424@qq.com 14 | * @Date: 2024/5/6 上午9:56 15 | * @Descriptions: 后台启动类 16 | */ 17 | @SpringBootApplication 18 | @EnableAsync 19 | @EnableCaching 20 | //@EnableScheduling 21 | public class NewbieApplication { 22 | public static void main(String[] args) { 23 | // 当前时间戳 24 | long beginTime = System.currentTimeMillis(); 25 | SpringApplication.run(NewbieApplication.class, args); 26 | System.out.println("启动完成:: " + (System.currentTimeMillis() - beginTime) + "ms"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysUserMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 7 | import com.newbie.common.domain.entity.SysUser; 8 | import org.apache.ibatis.annotations.Mapper; 9 | import org.apache.ibatis.annotations.Param; 10 | 11 | /** 12 | * @author 39869 13 | * @description 针对表【sys_user(系统用户)】的数据库操作Mapper 14 | * @createDate 2024-04-16 15:12:01 15 | * @Entity generator.domain.SysUser 16 | */ 17 | @Mapper 18 | public interface SysUserMapper extends BaseMapper { 19 | IPage queryUserByRoleId(@Param("page") Page page, @Param("sysUser") SysUser sysUser, @Param("roleId") String roleId); 20 | 21 | IPage queryUnUserByRoleId(@Param("page") Page page,@Param("sysUser") SysUser sysUser, @Param("roleId") String roleId); 22 | } 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /newbie-system/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.newbie 8 | newbie-boot3 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | newbie-system 13 | 14 | 15 | 21 16 | 21 17 | UTF-8 18 | 19 | 20 | 21 | 22 | com.newbie 23 | newbie-common 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/mapper/SysDictDataMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.newbie.common.domain.entity.SysDictData; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author 39869 11 | * @description 针对表【sys_dict_data(系统字典数据)】的数据库操作Mapper 12 | * @createDate 2024-04-16 23:21:27 13 | * @Entity generator.domain.SysDictData 14 | */ 15 | @Mapper 16 | public interface SysDictDataMapper extends BaseMapper { 17 | /** 18 | * 根据字典类型编码查询字典数据 19 | * @param typeCode 字典类型编码 20 | * @return 21 | */ 22 | List getDictDataListByTypeCode(String typeCode); 23 | 24 | /** 25 | * 清除字典类型下的默认字典数据 26 | * @param typeId 字典类型id 27 | */ 28 | void clearDefault(String typeId); 29 | 30 | /** 31 | * 设置字典数据为默认字典数据 32 | * @param id 字典数据id 33 | */ 34 | void setDefault(String id); 35 | } 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/util/ServletUtils.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.util; 2 | 3 | import cn.hutool.json.JSONUtil; 4 | import jakarta.servlet.http.HttpServletRequest; 5 | import jakarta.servlet.http.HttpServletResponse; 6 | import lombok.extern.slf4j.Slf4j; 7 | 8 | 9 | import java.io.IOException; 10 | 11 | @Slf4j 12 | public class ServletUtils { 13 | 14 | /** 15 | * 渲染到客户端 16 | * 17 | * @param object 待渲染的实体类,会自动转为json 18 | */ 19 | public static void render(HttpServletRequest request, HttpServletResponse response, Object object) throws IOException { 20 | // 允许跨域 21 | response.setHeader("Access-Control-Allow-Origin", "*"); 22 | // 允许自定义请求头token(允许head跨域) 23 | response.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified"); 24 | response.setHeader("Content-type", "application/json;charset=UTF-8"); 25 | 26 | response.getWriter().print(JSONUtil.toJsonStr(object)); 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysMenuService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | import com.newbie.common.domain.entity.SysMenu; 6 | import com.newbie.system.domain.vo.SysMenuVO; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author 39869 12 | * @description 针对表【sys_menu(系统菜单表)】的数据库操作Service 13 | * @createDate 2024-04-16 15:30:47 14 | */ 15 | public interface SysMenuService extends IService { 16 | /** 17 | * 获取菜单树 18 | */ 19 | List menuTree(SysMenu sysMenu); 20 | 21 | /** 22 | * 新增菜单数据 23 | * @param sysMenu 菜单数据 24 | * @return boolean 25 | */ 26 | boolean addData(SysMenu sysMenu); 27 | 28 | /** 29 | * 修改菜单数据 30 | * @param sysMenu 菜单数据 31 | * @return boolean 32 | */ 33 | boolean updateData(SysMenu sysMenu); 34 | 35 | /** 36 | * 批量删除数据 37 | * @param idList 菜单ID列表 38 | */ 39 | void deleteBatch(List idList); 40 | } 41 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/enums/CommonStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * 8 | * @Author: ZhangYuGe 9 | * @Email 398698424@qq.com 10 | * @Date: 2024/4/16 16:07 11 | * @Descriptions: 通用状态枚举 12 | */ 13 | @Getter 14 | public enum CommonStatusEnum { 15 | NORMAL("1", "正常"), 16 | DISABLED("0", "禁用"), 17 | ; 18 | private final String code; 19 | private final String msg; 20 | 21 | CommonStatusEnum(String code, String msg) { 22 | this.code = code; 23 | this.msg = msg; 24 | } 25 | 26 | /** 27 | * 是否正常状态 28 | * @param code 状态编码 29 | * @return 30 | */ 31 | public static boolean isNormal(String code){ 32 | return NORMAL.getCode().equals(code); 33 | } 34 | 35 | /** 36 | * 是否禁用状态 37 | * @param code 状态编码 38 | * @return 39 | */ 40 | public static boolean isDisabled(String code){ 41 | return DISABLED.getCode().equals(code); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/config/StpInterfaceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.config; 2 | 3 | import cn.dev33.satoken.stp.StpInterface; 4 | import com.newbie.common.domain.LoginUser; 5 | import com.newbie.common.util.SecurityUtils; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by IntelliJ IDEA. 12 | * 13 | * @Author: ZhangYuGe 14 | * @Email 398698424@qq.com 15 | * @Date: 2024/4/16 21:31 16 | * @Descriptions: 自定义权限加载接口实现类 17 | */ 18 | @Component 19 | public class StpInterfaceImpl implements StpInterface { 20 | @Override 21 | public List getPermissionList(Object loginId, String loginType) { 22 | LoginUser loginUser = SecurityUtils.getCurrentLoginUser(); 23 | return loginUser.getPerms(); 24 | } 25 | 26 | @Override 27 | public List getRoleList(Object loginId, String loginType) { 28 | LoginUser loginUser = SecurityUtils.getCurrentLoginUser(); 29 | return loginUser.getRoles(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/mapper/GeneratorMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.newbie.generator.domain.ColumnInfo; 5 | import com.newbie.generator.domain.TableInfo; 6 | import jakarta.annotation.Nullable; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | import java.util.List; 10 | 11 | public interface GeneratorMapper{ 12 | /** 13 | * 查询所有表信息 14 | * @param page 分页信息 15 | * @param tableInfo 查询条件 名称 16 | * @return List 17 | */ 18 | List selectTableList(@Nullable IPage page, TableInfo tableInfo); 19 | 20 | /** 21 | * 查询表信息 22 | * @param tableName 表名 23 | * @return TableInfo 24 | */ 25 | TableInfo selectTableByName(@Param("tableName") String tableName); 26 | 27 | /** 28 | * 查询表字段信息 29 | * @param tableName 表名 30 | * @return List 31 | */ 32 | List selectColumnList(@Param("tableName") String tableName); 33 | } 34 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/domain/GenConfigEntity.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import com.newbie.common.domain.entity.BaseEntity; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | 8 | import java.io.Serial; 9 | 10 | /** 11 | * 生成器配置 12 | */ 13 | @EqualsAndHashCode(callSuper = true) 14 | @TableName(value = "gen_config") 15 | @Data 16 | public class GenConfigEntity extends BaseEntity { 17 | @Serial 18 | private static final long serialVersionUID = 1L; 19 | private String author; // 作者 20 | private String email; // 邮箱 21 | private String dateFormat; // 日期格式 22 | private String packageParent; // 父级包名 23 | private String moduleName; // 模块名 24 | private String tablePrefix; // 表名前缀,多个以逗号分割 25 | private String enableSpringDoc; // 接口文档,1开启 0关闭 26 | private String enableApiAuth; // 接口权限控制,1开启 0关闭 27 | private String enableDrawer; // ui抽屉组件,1开启 0关闭 28 | private String configName; // 配置名称 29 | private String remark; // 备注 30 | } 31 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysDeptService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | import com.newbie.common.domain.entity.SysDept; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | import com.newbie.system.domain.vo.SysDeptVO; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author 39869 11 | * @description 针对表【sys_dept(部门表)】的数据库操作Service 12 | * @createDate 2024-04-16 23:21:27 13 | */ 14 | public interface SysDeptService extends IService { 15 | 16 | /** 17 | * 查询部门树,当 deptId 有值时,仅查询该部门及子部门 18 | * @param sysDept 查询筛选条件参数 19 | * @return 20 | */ 21 | List getDeptTree(SysDept sysDept); 22 | 23 | 24 | /** 25 | * 新增部门 26 | * @param sysDept 部门数据 27 | * @return 是否成功 28 | */ 29 | boolean addDept(SysDept sysDept); 30 | 31 | /** 32 | * 修改部门 33 | * @param sysDept 部门数据 34 | * @return 是否成功 35 | */ 36 | boolean updateDept(SysDept sysDept); 37 | 38 | /** 39 | * 批量删除部门 40 | * @param idList 部门ID列表 41 | */ 42 | void deleteBatch(List idList); 43 | } 44 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/LoginUser.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import com.newbie.common.domain.entity.SysDept; 5 | import com.newbie.common.domain.entity.SysRole; 6 | import com.newbie.common.domain.entity.SysUser; 7 | import com.newbie.common.constant.SecurityConstant; 8 | import lombok.Data; 9 | import lombok.EqualsAndHashCode; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * 16 | * @Author: ZhangYuGe 17 | * @Email 398698424@qq.com 18 | * @Date: 2024/4/16 17:36 19 | * @Descriptions: unknown 20 | */ 21 | @EqualsAndHashCode(callSuper = true) 22 | @Data 23 | public class LoginUser extends SysUser { 24 | private List roles; // 角色代码列表 25 | private List perms; // 权限标识码列表 26 | private List roleList; // 角色列表 27 | private SysDept dept; // 部门 28 | 29 | /** 30 | * 是否为admin用户 31 | */ 32 | @JsonIgnore 33 | public boolean isAdmin(){ 34 | return SecurityConstant.ADMIN_USER_NAME.equals(this.getUsername()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 zhangyuge 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysDictData.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | * 系统字典数据 9 | * @TableName sys_dict_data 10 | */ 11 | @EqualsAndHashCode(callSuper = true) 12 | @TableName(value ="sys_dict_data") 13 | @Data 14 | public class SysDictData extends BaseEntity { 15 | 16 | 17 | /** 18 | * 标签 19 | */ 20 | private String label; 21 | 22 | /** 23 | * 值 24 | */ 25 | private String value; 26 | 27 | /** 28 | * 字典类型ID 29 | */ 30 | private String typeId; 31 | 32 | /** 33 | * 元素类型 34 | */ 35 | private String eleType; 36 | 37 | /** 38 | * 元素样式类名 39 | */ 40 | private String eleClass; 41 | 42 | /** 43 | * 状态(1正常 0禁用) 44 | */ 45 | private String status; 46 | 47 | /** 48 | * 默认,Y/N 49 | */ 50 | private String def; 51 | 52 | /** 53 | * 排序字段 54 | */ 55 | private Integer sort; 56 | 57 | /** 58 | * 备注 59 | */ 60 | private String remark; 61 | 62 | } -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/service/SecurityService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.service; 2 | 3 | import cn.dev33.satoken.stp.SaTokenInfo; 4 | import com.newbie.security.domain.Route; 5 | import com.newbie.security.domain.body.LoginBody; 6 | import com.newbie.security.domain.body.PasswordBody; 7 | import com.newbie.security.domain.vo.ImageCaptcha; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by IntelliJ IDEA. 13 | * 14 | * @Author: ZhangYuGe 15 | * @Email 398698424@qq.com 16 | * @Date: 2024/4/16 15:35 17 | * @Descriptions: unknown 18 | */ 19 | public interface SecurityService { 20 | /** 21 | * 登录 22 | * @param loginBody 登录请求体参数 23 | * @return token信息 24 | */ 25 | SaTokenInfo login(LoginBody loginBody); 26 | 27 | /** 28 | * 初始化管理员 29 | * @param passwordBody 初始化管理员密码 30 | */ 31 | void initAdmin(PasswordBody passwordBody); 32 | 33 | /** 34 | * 获取菜单列表 35 | * @return 菜单列表 36 | */ 37 | List getMenuList(); 38 | 39 | /** 40 | * 修改密码 41 | * @param passwordBody 修改密码参数 42 | */ 43 | void updatePassword(PasswordBody passwordBody); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /newbie-file/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.newbie 8 | newbie-boot3 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | newbie-file 13 | 14 | 15 | 21 16 | 21 17 | UTF-8 18 | 19 | 20 | 21 | com.newbie 22 | newbie-common 23 | 24 | 25 | 26 | io.minio 27 | minio 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /newbie-generator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.newbie 8 | newbie-boot3 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | newbie-generator 13 | 14 | 15 | 21 16 | 21 17 | UTF-8 18 | 19 | 20 | 21 | com.newbie 22 | newbie-common 23 | 24 | 25 | 26 | org.freemarker 27 | freemarker 28 | 29 | 30 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.data.redis.connection.RedisConnectionFactory; 6 | import org.springframework.data.redis.core.RedisTemplate; 7 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; 8 | import org.springframework.data.redis.serializer.StringRedisSerializer; 9 | 10 | /** 11 | * Created by IntelliJ IDEA. 12 | * 13 | * @Author: ZhangYuGe 14 | * @Email 398698424@qq.com 15 | * @Date: 2024/4/23 上午10:46 16 | * @Descriptions: redis配置 17 | */ 18 | @Configuration 19 | public class RedisConfig { 20 | @Bean 21 | public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { 22 | RedisTemplate template = new RedisTemplate<>(); 23 | template.setConnectionFactory(connectionFactory); 24 | template.setKeySerializer(new StringRedisSerializer()); 25 | template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); 26 | return template; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/templates/api.js.ftl: -------------------------------------------------------------------------------- 1 | import axios, { msgType } from '@/utils/axios' 2 | 3 | const BASE_URL = '${apiPath.parent}' 4 | 5 | /** 6 | * 分页查询数据列表 7 | */ 8 | export function pageApi(params) { 9 | return axios.get(`${r'$'}{BASE_URL}/page`, { params }) 10 | } 11 | 12 | /** 13 | * 查询数据列表 14 | */ 15 | export function listApi(params) { 16 | return axios.get(`${r'$'}{BASE_URL}/list`, { params }) 17 | } 18 | 19 | /** 20 | * 新增数据 21 | */ 22 | export function addDataApi(data){ 23 | return axios.post(`${r'$'}{BASE_URL}/addData`, data, { successMsgType: msgType.msg }) 24 | } 25 | 26 | /** 27 | * 根据主键更新数据 28 | */ 29 | export function updateByPkValApi(data){ 30 | return axios.post(`${r'$'}{BASE_URL}/updateByPkVal`, data, { successMsgType: msgType.msg }) 31 | } 32 | 33 | /** 34 | * 保存数据信息,主键有值则修改,否则新增 35 | */ 36 | export function saveDataApi(data) { 37 | if (data.${pkey.name}) 38 | return updateByPkValApi(data) 39 | else 40 | return addDataApi(data) 41 | } 42 | 43 | /** 44 | * 根据主键删除数据 45 | */ 46 | export function deleteByPkValApi(${pkey.name}) { 47 | return axios.post(`${r'$'}{BASE_URL}/deleteByPkVal/${r'$'}{${pkey.name}}`, null, { successMsgType: msgType.msg }) 48 | } 49 | -------------------------------------------------------------------------------- /newbie-weblog/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.newbie 8 | newbie-boot3 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | newbie-weblog 13 | 14 | 15 | 21 16 | 21 17 | UTF-8 18 | 19 | 20 | 21 | 22 | com.newbie 23 | newbie-system 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-aop 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /newbie-admin/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | ${AnsiColor.BLUE} 2 | ---------------------------------------------------------------------------------------------------------- 3 | | ███╗ ██╗███████╗██╗ ██╗██████╗ ██╗███████╗ ██████╗ ██████╗ ██████╗ ████████╗ | 4 | | ████╗ ██║██╔════╝██║ ██║██╔══██╗██║██╔════╝ ██╔══██╗██╔═══██╗██╔═══██╗╚══██╔══╝ | 5 | | ██╔██╗ ██║█████╗ ██║ █╗ ██║██████╔╝██║█████╗█████╗██████╔╝██║ ██║██║ ██║ ██║ | 6 | | ██║╚██╗██║██╔══╝ ██║███╗██║██╔══██╗██║██╔══╝╚════╝██╔══██╗██║ ██║██║ ██║ ██║ | 7 | | ██║ ╚████║███████╗╚███╔███╔╝██████╔╝██║███████╗ ██████╔╝╚██████╔╝╚██████╔╝ ██║ | 8 | | ╚═╝ ╚═══╝╚══════╝ ╚══╝╚══╝ ╚═════╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ | 9 | ---------------------------------------------------------------------------------------------------------- 10 | ${spring.application.name} version: ${spring.application.version} 11 | spring-boot version: ${spring-boot.version} 12 | ---------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/exception/NewbieException.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.exception; 2 | 3 | import com.newbie.common.util.R; 4 | import lombok.Getter; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * 9 | * @Author: ZhangYuGe 10 | * @Email 398698424@qq.com 11 | * @Date: 2024/4/17 下午11:31 12 | * @Descriptions: 业务异常类 13 | */ 14 | @Getter 15 | public final class NewbieException extends RuntimeException { 16 | 17 | private final Integer code; // 异常编码 18 | private final Boolean isPrintLog; // 是否打印日志 19 | 20 | public NewbieException(String message) { 21 | super(message); 22 | this.code = R.ERROR_CODE; 23 | this.isPrintLog = false; 24 | } 25 | 26 | public NewbieException(String message, boolean isPrintLog) { 27 | super(message); 28 | this.code = R.ERROR_CODE; 29 | this.isPrintLog = isPrintLog; 30 | } 31 | 32 | public NewbieException(int code, String message) { 33 | super(message); 34 | this.code = code; 35 | this.isPrintLog = false; 36 | } 37 | 38 | public NewbieException(int code, String message, boolean isPrintLog) { 39 | super(message); 40 | this.code = code; 41 | this.isPrintLog = isPrintLog; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **欢迎使用NewbieBoot快速开发框架** 2 | 3 | ## 框架开发环境 4 | 5 | + JDK 21 6 | + Maven 3.9.4 7 | + Idea 2024.1.1 8 | 9 | ## 脚本介绍 10 | 11 | 项目脚本存放在bin目录下 12 | 13 | + **shell jar管理脚本** jar.sh 14 | 15 | ```shell 16 | # 服务启动 17 | sh jar.sh start 18 | # 服务停止 19 | sh jar.sh stop 20 | # 服务运行状态查看 21 | sh jar.sh status 22 | # 重启服务 23 | sh jar.sh restart 24 | # 帮助说明,用于提示输入参数信息 25 | sh jar.sh usage 26 | ``` 27 | 28 | 29 | 30 | + **mvn重新打包脚本** reinstall.bat 31 | 32 | + windows平台双击运行 33 | 34 | + **windows平台jar运行脚本** run.bat 35 | 36 | + windows平台双击运行 37 | 38 | ## 数据库脚本介绍 39 | 40 | 数据库脚本存放在bin目录下 41 | 42 | + **Mysql初始化脚本** mysql.sql 43 | + **Oracle初始化脚本** oracle.sql 44 | + **Postgresql初始化脚本** pgsql.sql 45 | 46 | ## 模块介绍 47 | 48 | ### newbie-admin 49 | 50 | 主要定义后台系统的controller层,对外开放接口,处于最顶层模块 51 | 52 | ### newbie-common 53 | 54 | 通用模块/基础模块,处于最底层模块,主要定义通用设施,自定义工具类、自定义注解、基础实体、基础配置、异常处理等等。 55 | 56 | ### newbie-file 57 | 58 | 文件服务模块,属于服务设施,主要提供文件上传下载等功能的服务 59 | 60 | ### newbie-generator 61 | 62 | 代码生成器,可根据数据库表生成对应的前后端代码。 63 | 64 | ### newbie-security 65 | 66 | 安全控制模块,负责接口拦截,检查系统认证及接口鉴权等安全功能。 67 | 68 | ### newbie-system 69 | 70 | 系统管理模块,属于基础服务模块,用户管理、角色管理、菜单权限管理及分配等系统级服务和登录日志、操作日志等功能。 71 | 72 | ### newbie-weblog 73 | 74 | web日志模块,使用aop切面进行接口的访问日志的记录 75 | 76 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysDept.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | * 部门表 9 | * @TableName sys_dept 10 | */ 11 | @EqualsAndHashCode(callSuper = true) 12 | @TableName(value ="sys_dept") 13 | @Data 14 | public class SysDept extends BaseEntity{ 15 | 16 | /** 17 | * 部门名称 18 | */ 19 | private String deptName; 20 | 21 | 22 | /** 23 | * 父级id 24 | */ 25 | private String parentId; 26 | 27 | /** 28 | * 祖级列表 29 | */ 30 | private String ancestors; 31 | 32 | /** 33 | * 显示顺序 34 | */ 35 | private Integer sort; 36 | 37 | /** 38 | * 负责人 39 | */ 40 | private String leader; 41 | 42 | /** 43 | * 联系电话 44 | */ 45 | private String phone; 46 | 47 | /** 48 | * 邮箱 49 | */ 50 | private String email; 51 | 52 | /** 53 | * 状态(1正常 0停用) 54 | */ 55 | private String status; 56 | 57 | /** 58 | * 层级 59 | */ 60 | private Integer tier; 61 | 62 | /** 63 | * 首页路由地址 64 | */ 65 | private String homePath; 66 | 67 | /** 68 | * 备注 69 | */ 70 | private String remark; 71 | 72 | } -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/OSRuntimeInfo.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 系统运行时信息 9 | * 10 | */ 11 | @Data 12 | public class OSRuntimeInfo { 13 | 14 | /** 15 | * 时刻 16 | */ 17 | private String timestamp; 18 | 19 | /** 20 | * cpu使用率 21 | */ 22 | private double cpuUsage; 23 | 24 | /** 25 | * cpu基准速度(GHz) 26 | */ 27 | private String cpuMaxFreq; 28 | 29 | /** 30 | * cpu当前速度(GHz) 31 | */ 32 | private String cpuCurrentFreq; 33 | 34 | /** 35 | * 总内存 36 | */ 37 | private long totalMemory; 38 | 39 | /** 40 | * 使用内存 41 | */ 42 | private long usedMemory; 43 | 44 | /** 45 | * 可用虚拟总内存 46 | */ 47 | private long swapTotalMemory; 48 | 49 | /** 50 | * 已用虚拟内存 51 | */ 52 | private long swapUsedMemory; 53 | 54 | /** 55 | * 磁盘信息 56 | */ 57 | private List disksList; 58 | 59 | /** 60 | * 磁盘读取速率(Kb/s) 61 | */ 62 | private Double diskReadRate; 63 | 64 | /** 65 | * 磁盘写入速率(Kb/s) 66 | */ 67 | private Double diskWriteRate; 68 | 69 | /** 70 | * 网卡信息 71 | */ 72 | private List networkList; 73 | 74 | } 75 | -------------------------------------------------------------------------------- /newbie-weblog/src/main/java/com/newbie/weblog/conditional/AllApiStrategyConditional.java: -------------------------------------------------------------------------------- 1 | package com.newbie.weblog.conditional; 2 | 3 | 4 | import com.newbie.weblog.enums.WebLogStrategyEnum; 5 | import org.springframework.context.annotation.Condition; 6 | import org.springframework.context.annotation.ConditionContext; 7 | import org.springframework.core.env.Environment; 8 | import org.springframework.core.type.AnnotatedTypeMetadata; 9 | import org.springframework.util.StringUtils; 10 | 11 | import java.util.Arrays; 12 | 13 | 14 | public class AllApiStrategyConditional implements Condition { 15 | @Override 16 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 17 | Environment environment = context.getEnvironment(); 18 | String[] activeProfiles = environment.getActiveProfiles(); 19 | Boolean enable = environment.getProperty("newbie.weblog.enable", Boolean.class); 20 | String env = environment.getProperty("newbie.weblog.env"); 21 | WebLogStrategyEnum strategy = environment.getProperty("newbie.weblog.default-strategy", WebLogStrategyEnum.class); 22 | 23 | return Boolean.TRUE.equals(enable) 24 | && WebLogStrategyEnum.ALL_API.equals(strategy) 25 | && (!StringUtils.hasLength(env) || Arrays.asList(activeProfiles).contains(env)); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysUser.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | * 系统用户 9 | * @TableName sys_user 10 | */ 11 | @EqualsAndHashCode(callSuper = true) 12 | @TableName(value ="sys_user") 13 | @Data 14 | public class SysUser extends BaseEntity { 15 | 16 | 17 | /** 18 | * 部门ID 19 | */ 20 | private String deptId; 21 | 22 | /** 23 | * 用户名 24 | */ 25 | private String username; 26 | 27 | /** 28 | * 密码 29 | */ 30 | private String password; 31 | 32 | /** 33 | * 昵称 34 | */ 35 | private String nickName; 36 | 37 | /** 38 | * 头像地址 39 | */ 40 | private String avatar; 41 | 42 | /** 43 | * 首页路由地址 44 | */ 45 | private String homePath; 46 | 47 | /** 48 | * 电话(手机号) 49 | */ 50 | private String phone; 51 | 52 | /** 53 | * 邮箱 54 | */ 55 | private String email; 56 | 57 | /** 58 | * 性别(1男 0女) 59 | */ 60 | private String gender; 61 | 62 | /** 63 | * 账号状态(1正常 0锁定) 64 | */ 65 | private String status; 66 | 67 | /** 68 | * 备注 69 | */ 70 | private String remark; 71 | 72 | /** 73 | * 排序 74 | */ 75 | private Integer sort; 76 | 77 | } -------------------------------------------------------------------------------- /newbie-weblog/src/main/java/com/newbie/weblog/conditional/DefaultStrategyConditional.java: -------------------------------------------------------------------------------- 1 | package com.newbie.weblog.conditional; 2 | 3 | import com.newbie.weblog.enums.WebLogStrategyEnum; 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.core.type.AnnotatedTypeMetadata; 8 | import org.springframework.util.StringUtils; 9 | 10 | import java.util.Arrays; 11 | import java.util.Objects; 12 | 13 | 14 | public class DefaultStrategyConditional implements Condition { 15 | 16 | @Override 17 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 18 | Environment environment = context.getEnvironment(); 19 | String[] activeProfiles = environment.getActiveProfiles(); 20 | Boolean enable = environment.getProperty("newbie.weblog.enable", Boolean.class); 21 | String env = environment.getProperty("newbie.weblog.env"); 22 | WebLogStrategyEnum strategy = environment.getProperty("newbie.weblog.default-strategy", WebLogStrategyEnum.class); 23 | 24 | return Boolean.TRUE.equals(enable) 25 | && (Objects.isNull(strategy) || WebLogStrategyEnum.DEFAULT.equals(strategy)) 26 | && (!StringUtils.hasLength(env) || Arrays.asList(activeProfiles).contains(env)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /newbie-security/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.newbie 8 | newbie-boot3 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | newbie-security 13 | 14 | 15 | 21 16 | 21 17 | UTF-8 18 | 19 | 20 | 21 | com.newbie 22 | newbie-system 23 | 24 | 25 | 26 | cn.dev33 27 | sa-token-redis 28 | 29 | 30 | 31 | cn.dev33 32 | sa-token-jwt 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.IdType; 5 | import com.baomidou.mybatisplus.annotation.TableField; 6 | import com.baomidou.mybatisplus.annotation.TableId; 7 | import lombok.Data; 8 | 9 | import java.io.Serial; 10 | import java.io.Serializable; 11 | import java.util.Date; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * 16 | * @Author: ZhangYuGe 17 | * @Email 398698424@qq.com 18 | * @Date: 2024/4/17 下午5:28 19 | * @Descriptions: 基础实体对象 20 | */ 21 | @Data 22 | public abstract class BaseEntity implements Serializable { 23 | @Serial 24 | private static final long serialVersionUID = 1L; 25 | 26 | /** 27 | * 主键 28 | */ 29 | @TableId(type = IdType.ASSIGN_ID) 30 | private String id; 31 | 32 | /** 33 | * 创建时间 34 | */ 35 | @TableField(fill = FieldFill.INSERT) 36 | private Date createTime; 37 | 38 | /** 39 | * 最后更新时间 40 | */ 41 | @TableField(fill = FieldFill.UPDATE) 42 | private Date updateTime; 43 | 44 | /** 45 | * 创建者,目前使用SysUser的username 46 | */ 47 | @TableField(fill = FieldFill.INSERT) 48 | private String createBy; 49 | /** 50 | * 更新者,目前使用SysUser的username 51 | */ 52 | @TableField(fill = FieldFill.UPDATE) 53 | private String updateBy; 54 | } 55 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/OSInfo.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain; 2 | 3 | import cn.hutool.core.date.DatePattern; 4 | import cn.hutool.core.date.DateTime; 5 | import cn.hutool.core.date.DateUtil; 6 | import cn.hutool.core.util.StrUtil; 7 | import lombok.Data; 8 | 9 | /** 10 | * 系统信息 11 | * 12 | */ 13 | @Data 14 | public class OSInfo { 15 | 16 | /** 17 | * 系统 18 | */ 19 | private String os; 20 | 21 | /** 22 | * 系统架构 23 | */ 24 | private String osArch; 25 | 26 | /** 27 | * java版本 28 | */ 29 | private String javaVersion; 30 | 31 | /** 32 | * 工作目录 33 | */ 34 | private String userDir; 35 | 36 | /** 37 | * cpu核心数 38 | */ 39 | private int cpuCount; 40 | 41 | /** 42 | * 主机host 43 | */ 44 | private String host; 45 | 46 | /** 47 | * 主机名称 48 | */ 49 | private String hostName; 50 | 51 | /** 52 | * 系统启动时间 53 | */ 54 | private String bootTime; 55 | 56 | /** 57 | * 系统正常运行时长 58 | */ 59 | private String runTime; 60 | public String getRunTime(){ 61 | String runTime = ""; 62 | if (StrUtil.isNotEmpty(this.bootTime)) { 63 | DateTime start = DateUtil.parse(this.bootTime, DatePattern.NORM_DATETIME_PATTERN); 64 | runTime = DateUtil.formatBetween(start, DateUtil.date()); 65 | } 66 | return runTime; 67 | } 68 | 69 | } 70 | 71 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/impl/SysDictDataServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.newbie.common.domain.entity.SysDictData; 5 | import com.newbie.system.service.SysDictDataService; 6 | import com.newbie.system.mapper.SysDictDataMapper; 7 | import lombok.RequiredArgsConstructor; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * @author 39869 15 | * @description 针对表【sys_dict_data(系统字典数据)】的数据库操作Service实现 16 | * @createDate 2024-04-16 23:21:27 17 | */ 18 | @Service 19 | @RequiredArgsConstructor 20 | public class SysDictDataServiceImpl extends ServiceImpl 21 | implements SysDictDataService{ 22 | private final SysDictDataMapper sysDictDataMapper; 23 | 24 | @Override 25 | @Transactional 26 | public void updateDictDataAsDefault(String id) { 27 | // 根据id查询 28 | SysDictData dictData = getById(id); 29 | // 取消默认 30 | sysDictDataMapper.clearDefault(dictData.getTypeId()); 31 | // 设置默认 32 | sysDictDataMapper.setDefault(dictData.getId()); 33 | } 34 | 35 | @Override 36 | public List getDictDataListByTypeCode(String typeCode) { 37 | return sysDictDataMapper.getDictDataListByTypeCode(typeCode); 38 | } 39 | } 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/templates/service.java.ftl: -------------------------------------------------------------------------------- 1 | package ${package.service}; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import ${package.entity}.${Entity}Entity; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by NewbieGenerator. 12 | * 13 | * @Author: ${gc.author} 14 | * @Email ${gc.email} 15 | * @Date: ${gc.date} 16 | * @Descriptions: ${comment!} 服务类 17 | */ 18 | public interface I${Entity}Service extends IService<${Entity}Entity> { 19 | 20 | /** 21 | * 分页查询数据列表 22 | * @param page 分页信息 23 | * @param entity 数据实体 24 | * @return IPage<${Entity}Entity> 25 | */ 26 | IPage<${Entity}Entity> getPage(IPage<${Entity}Entity> page, ${Entity}Entity entity); 27 | 28 | /** 29 | * 查询数据列表 30 | * @param entity 数据实体 31 | * @return List<${Entity}Entity> 32 | */ 33 | List<${Entity}Entity> getList(${Entity}Entity entity); 34 | 35 | /** 36 | * 根据主键查询数据详情 37 | * @param pkVal 主键值 38 | * @return ${Entity}Entity 39 | */ 40 | ${Entity}Entity getByPkVal(Serializable pkVal); 41 | 42 | /** 43 | * 新增数据 44 | * @param entity 数据实体 45 | */ 46 | void addData(${Entity}Entity entity); 47 | 48 | /** 49 | * 根据主键修改数据 50 | * @param entity 数据实体 51 | */ 52 | void updateByPkVal(${Entity}Entity entity); 53 | 54 | /** 55 | * 根据主键删除数据 56 | * @param pkVal 主键值 57 | */ 58 | void deleteByPkVal(Serializable pkVal); 59 | } -------------------------------------------------------------------------------- /newbie-weblog/src/main/java/com/newbie/weblog/aspect/WebLogAspectAdvice.java: -------------------------------------------------------------------------------- 1 | package com.newbie.weblog.aspect; 2 | 3 | import com.newbie.system.service.SysLogOperateService; 4 | import com.newbie.weblog.config.WebLogConfigProperties; 5 | import lombok.RequiredArgsConstructor; 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * Created by IntelliJ IDEA. 11 | * 12 | * @Author: ZhangYuGe 13 | * @Email 398698424@qq.com 14 | * @Date: 2024/5/18 下午6:48 15 | * @Descriptions: 日志切面通知 16 | */ 17 | @Component 18 | @RequiredArgsConstructor 19 | public class WebLogAspectAdvice { 20 | private final SysLogOperateService sysLogOperateService; 21 | private final WebLogConfigProperties webLogConfigProperties; 22 | 23 | public Object doAroundAdvice(ProceedingJoinPoint point) throws Throwable{ 24 | long beginTime = System.currentTimeMillis(); 25 | String methodName = point.getSignature().getName(); 26 | String className = point.getTarget().getClass().getName(); 27 | try { 28 | Object proceed = point.proceed(); 29 | if (!webLogConfigProperties.getOnlyError()) { 30 | sysLogOperateService.saveSysLogOperate(className + "." + methodName, beginTime); 31 | } 32 | return proceed; 33 | } catch (Throwable throwable) { 34 | sysLogOperateService.saveSysLogOperate(className + "." + methodName, beginTime, throwable); 35 | throw throwable; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/templates/mapper.java.ftl: -------------------------------------------------------------------------------- 1 | package ${package.mapper}; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import ${package.entity}.${Entity}Entity; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import jakarta.annotation.Nullable; 7 | import org.apache.ibatis.annotations.Mapper; 8 | 9 | import java.io.Serializable; 10 | import java.util.List; 11 | 12 | 13 | /** 14 | * Created by NewbieGenerator. 15 | * 16 | * @Author: ${gc.author} 17 | * @Email ${gc.email} 18 | * @Date: ${gc.date} 19 | * @Descriptions: ${comment!} Mapper 接口 20 | */ 21 | @Mapper 22 | public interface ${Entity}Mapper extends BaseMapper<${Entity}Entity> { 23 | 24 | /** 25 | * 查询数据列表 26 | * @param page 分页信息 27 | * @param entity 数据实体类 28 | * @return List<${Entity}Entity> 29 | */ 30 | List<${Entity}Entity> selectList(@Nullable IPage<${Entity}Entity> page, ${Entity}Entity entity); 31 | 32 | /** 33 | * 根据主键查询数据 34 | * @param pkVal 主键值 35 | * @return ${Entity}Entity 36 | */ 37 | ${Entity}Entity selectByPkVal(Serializable pkVal); 38 | 39 | /** 40 | * 插入数据 41 | * @param entity 数据实体类 42 | * @return 插入条数 43 | */ 44 | int insertData(${Entity}Entity entity); 45 | 46 | /** 47 | * 根据主键更新数据 48 | * @param entity 数据实体类 49 | * @return 更新条数 50 | */ 51 | int updateByPkVal(${Entity}Entity entity); 52 | 53 | /** 54 | * 根据主键删除数据 55 | * @param pkVal 主键值 56 | * @return 删除条数 57 | */ 58 | int deleteByPkVal(Serializable pkVal); 59 | } 60 | -------------------------------------------------------------------------------- /newbie-weblog/src/main/java/com/newbie/weblog/aspect/WebLogAspect.java: -------------------------------------------------------------------------------- 1 | package com.newbie.weblog.aspect; 2 | 3 | import com.newbie.weblog.conditional.DefaultStrategyConditional; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.aspectj.lang.annotation.Around; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.annotation.Pointcut; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 11 | import org.springframework.context.annotation.Conditional; 12 | import org.springframework.stereotype.Component; 13 | 14 | @Aspect 15 | @Component 16 | @ConditionalOnWebApplication 17 | @Conditional(DefaultStrategyConditional.class) 18 | @Slf4j 19 | @RequiredArgsConstructor 20 | public class WebLogAspect { 21 | 22 | private final WebLogAspectAdvice webLogAspectAdvice; 23 | static { 24 | log.info("启用 Web Log 记录日志 ---- 使用 DEFAULT 策略"); 25 | } 26 | 27 | 28 | @Pointcut("@annotation(com.newbie.common.annotation.IgnoreWebLog) || @within(com.newbie.common.annotation.IgnoreWebLog)") 29 | public void ignoreWebLogCut() { 30 | } 31 | @Pointcut("@annotation(com.newbie.common.annotation.WebLog) || @within(com.newbie.common.annotation.WebLog)") 32 | public void WebLogCut() { 33 | } 34 | 35 | @Around(value = "WebLogCut() && !ignoreWebLogCut()") 36 | public Object doAroundAdvice(ProceedingJoinPoint point) throws Throwable { 37 | return webLogAspectAdvice.doAroundAdvice(point); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/service/IGenConfigService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.service; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.newbie.generator.domain.GenConfigEntity; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by NewbieGenerator. 12 | * 13 | * @Author: ZhangYuGe 14 | * @Email 398698424@qq.com 15 | * @Date: 2024-10-04 16 | * @Descriptions: 代码生成器配置 服务类 17 | */ 18 | public interface IGenConfigService extends IService { 19 | 20 | /** 21 | * 分页查询数据列表 22 | * @param page 分页信息 23 | * @param entity 数据实体 24 | * @return IPage 25 | */ 26 | IPage getPage(IPage page, GenConfigEntity entity); 27 | 28 | /** 29 | * 查询数据列表 30 | * @param entity 数据实体 31 | * @return List 32 | */ 33 | List getList(GenConfigEntity entity); 34 | 35 | /** 36 | * 根据主键查询数据详情 37 | * @param pkVal 主键值 38 | * @return GenConfigEntity 39 | */ 40 | GenConfigEntity getByPkVal(Serializable pkVal); 41 | 42 | /** 43 | * 新增数据 44 | * @param entity 数据实体 45 | */ 46 | void addData(GenConfigEntity entity); 47 | 48 | /** 49 | * 根据主键修改数据 50 | * @param entity 数据实体 51 | */ 52 | void updateByPkVal(GenConfigEntity entity); 53 | 54 | /** 55 | * 根据主键删除数据 56 | * @param pkVal 主键值 57 | */ 58 | void deleteByPkVal(Serializable pkVal); 59 | } -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysUserRoleService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.newbie.common.domain.entity.SysUser; 7 | import com.newbie.common.domain.entity.SysUserRole; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author 39869 13 | * @description 针对表【sys_user_role(用户和角色关系表)】的数据库操作Service 14 | * @createDate 2024-04-16 15:30:47 15 | */ 16 | public interface SysUserRoleService extends IService { 17 | 18 | /** 19 | * 根据 用户ID 及 角色ID列表 删除数据 20 | * @param userId 用户ID 21 | * @param roleIds 角色ID列表 22 | */ 23 | void removeByUserIdAndRoleIds(String userId, List roleIds); 24 | 25 | /** 26 | * 根据 角色ID 及 用户ID列表 删除数据 27 | * @param roleId 角色ID 28 | * @param userIds 用户ID列表 29 | */ 30 | void removeByRoleIdAndUserIds(String roleId, List userIds); 31 | 32 | /** 33 | * 根据角色ID查询已分配的用户 34 | * 35 | * @param page 分页参数对象 36 | * @param sysUser 筛选条件对象 37 | * @param roleId 角色ID 38 | * @return 39 | */ 40 | IPage queryUserByRoleId(Page page, SysUser sysUser, String roleId); 41 | 42 | /** 43 | * 根据角色ID查询未分配的用户 44 | * 45 | * @param page 分页参数对象 46 | * @param sysUser 筛选条件对象 47 | * @param roleId 角色ID 48 | * @return 49 | */ 50 | IPage queryUnUserByRoleId(Page page, SysUser sysUser, String roleId); 51 | 52 | } 53 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/controller/GeneratorController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.controller; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.newbie.common.util.R; 6 | import com.newbie.generator.domain.GenerateBody; 7 | import com.newbie.generator.domain.TableInfo; 8 | import com.newbie.generator.service.GeneratorService; 9 | import jakarta.servlet.http.HttpServletResponse; 10 | import lombok.RequiredArgsConstructor; 11 | import org.springframework.util.CollectionUtils; 12 | import org.springframework.util.StringUtils; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | 16 | @RestController 17 | @RequestMapping("/generator") 18 | @RequiredArgsConstructor 19 | public class GeneratorController { 20 | private final GeneratorService generatorService; 21 | @GetMapping("/dbTableList") 22 | public R> dbTableList(Page page, TableInfo tableInfo){ 23 | return R.ok(generatorService.getDbTableList(page, tableInfo)); 24 | } 25 | 26 | 27 | @PostMapping("/generate") 28 | public R generate(@RequestBody GenerateBody generateBody, HttpServletResponse response){ 29 | if (!StringUtils.hasLength(generateBody.getConfigId())) { 30 | return R.error("未选择配置"); 31 | } 32 | if(generateBody.getTableNames() == null || generateBody.getTableNames().length == 0){ 33 | return R.error("未选择目标"); 34 | } 35 | generatorService.generatorCode(generateBody,response); 36 | return R.ok(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /newbie-system/src/main/resources/mapper/SysUserRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | id,user_id,role_id, 19 | create_by,create_time 20 | update_by,update_time 21 | 22 | 23 | delete from sys_user_role 24 | where user_id = #{userId} 25 | and role_id in 26 | 27 | #{item} 28 | 29 | 30 | 31 | delete from sys_user_role 32 | where role_id = #{roleId} 33 | and user_id in 34 | 35 | #{item} 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/SysUserService.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.newbie.common.domain.entity.SysUser; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author 39869 12 | * @description 针对表【sys_user(系统用户)】的数据库操作Service 13 | * @createDate 2024-04-16 15:30:47 14 | */ 15 | public interface SysUserService extends IService { 16 | /** 17 | * 分页查询 18 | * 19 | * @param page 20 | * @param entity 21 | * @return com.baomidou.mybatisplus.core.metadata.IPage 22 | */ 23 | IPage queryPage(Page page, SysUser entity); 24 | 25 | /** 26 | * 添加用户 27 | * 28 | * @param sysUser 29 | */ 30 | void saveUser(SysUser sysUser); 31 | 32 | /** 33 | * 修改用户 34 | * 35 | * @param sysUser 36 | */ 37 | void updateUser(SysUser sysUser); 38 | 39 | /** 40 | * 修改密码 41 | * 42 | * @param userId 用户ID 43 | * @param newPassword 新密码 44 | * @param confirmNewPassword 确认密码 45 | * @param immediatelyKick 修改成功后是否强制下线 46 | * @return 是否成功 47 | */ 48 | boolean updateUserPassword(String userId, String newPassword, String confirmNewPassword,Boolean immediatelyKick); 49 | 50 | /** 51 | * 批量删除 52 | * @param idList ID列表 53 | */ 54 | void deleteBatch(List idList); 55 | 56 | /** 57 | * 修改当前用户基本信息 58 | * @param sysUser 用户对象 59 | */ 60 | void updateByCurr(SysUser sysUser); 61 | } 62 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/config/DbConfig.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.config; 2 | 3 | import com.newbie.generator.mapper.GeneratorMapper; 4 | import com.newbie.generator.mapper.MysqlGeneratorMapper; 5 | import com.newbie.generator.mapper.Postgresql16GeneratorMapper; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.SneakyThrows; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.context.annotation.Primary; 12 | 13 | import javax.sql.DataSource; 14 | import java.sql.Connection; 15 | import java.sql.DatabaseMetaData; 16 | 17 | /** 18 | * 数据库配置 19 | */ 20 | @Configuration 21 | @RequiredArgsConstructor 22 | @Slf4j 23 | public class DbConfig { 24 | private final Postgresql16GeneratorMapper postgresql16GeneratorMapper; 25 | private final MysqlGeneratorMapper mysqlGeneratorMapper; 26 | private final DataSource dataSource; 27 | 28 | @SneakyThrows 29 | @Bean 30 | @Primary 31 | public GeneratorMapper generatorMapper(){ 32 | Connection connection = dataSource.getConnection(); 33 | DatabaseMetaData metaData = connection.getMetaData(); 34 | String databaseProductName = metaData.getDatabaseProductName(); 35 | log.info("========== 代码生成器启动 =========="); 36 | if("PostgreSQL".equals(databaseProductName)){ 37 | return postgresql16GeneratorMapper; 38 | } 39 | if ("MySQL".equals(databaseProductName)) { 40 | return mysqlGeneratorMapper; 41 | } 42 | log.warn("====== 代码生成器:不支持的数据库类型,默认使用 PostgreSQL ======"); 43 | return postgresql16GeneratorMapper; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysLogOperate.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.*; 4 | import lombok.Data; 5 | import org.springframework.util.StringUtils; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | import java.util.Date; 10 | 11 | /** 12 | * 系统操作日志 13 | * 14 | * @TableName sys_log_operate 15 | */ 16 | @TableName(value = "sys_log_operate") 17 | @Data 18 | public class SysLogOperate implements Serializable { 19 | /** 20 | * 主键 21 | */ 22 | @TableId(type = IdType.ASSIGN_ID) 23 | private String id; 24 | 25 | /** 26 | * 用户名 27 | */ 28 | private String username; 29 | 30 | /** 31 | * 状态,1 成功,0 失败 32 | */ 33 | private String status; 34 | 35 | /** 36 | * 失败原因 37 | */ 38 | private String failReason; 39 | 40 | /** 41 | * 客户端IP 42 | */ 43 | private String clientIp; 44 | 45 | /** 46 | * 请求路径 47 | */ 48 | private String targetUri; 49 | 50 | /** 51 | * 执行的类方法 52 | */ 53 | private String targetFun; 54 | 55 | /** 56 | * 请求方式 57 | */ 58 | private String method; 59 | 60 | /** 61 | * 消耗时长,毫秒 62 | */ 63 | private Long costTime; 64 | 65 | /** 66 | * 创建时间 67 | */ 68 | @TableField(fill = FieldFill.INSERT) 69 | private Date createTime; 70 | 71 | public void setFailReason(String msg) { 72 | if (StringUtils.hasLength(msg) && msg.length() > 1000) { 73 | this.failReason = msg.substring(0, 1000); 74 | } else { 75 | this.failReason = msg; 76 | } 77 | } 78 | 79 | 80 | @Serial 81 | @TableField(exist = false) 82 | private static final long serialVersionUID = 1L; 83 | } -------------------------------------------------------------------------------- /newbie-system/src/main/resources/mapper/SysRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | r.id,r.role_name,r.role_code, 23 | r.sort,r.status,r.home_path, 24 | r.remark,r.create_by,r.create_time, 25 | r.update_by,r.update_time 26 | 27 | 35 | 36 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/impl/SysDictTypeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.newbie.common.domain.entity.SysDictData; 6 | import com.newbie.common.domain.entity.SysDictType; 7 | import com.newbie.common.exception.NewbieException; 8 | import com.newbie.system.mapper.SysDictDataMapper; 9 | import com.newbie.system.mapper.SysDictTypeMapper; 10 | import com.newbie.system.service.SysDictTypeService; 11 | import lombok.RequiredArgsConstructor; 12 | import org.springframework.stereotype.Service; 13 | import org.springframework.transaction.annotation.Transactional; 14 | import org.springframework.util.CollectionUtils; 15 | 16 | import java.util.List; 17 | 18 | /** 19 | * @author 39869 20 | * @description 针对表【sys_dict_type(系统字典类型)】的数据库操作Service实现 21 | * @createDate 2024-04-16 23:21:27 22 | */ 23 | @Service 24 | @RequiredArgsConstructor 25 | public class SysDictTypeServiceImpl extends ServiceImpl 26 | implements SysDictTypeService{ 27 | private final SysDictTypeMapper sysDictTypeMapper; 28 | private final SysDictDataMapper sysDictDataMapper; 29 | 30 | @Override 31 | @Transactional 32 | public void deleteBatch(List idList) { 33 | // 查询字典类型下的字典数据 34 | List dictDataList = sysDictDataMapper.selectList(new LambdaQueryWrapper() 35 | .in(SysDictData::getTypeId, idList)); 36 | 37 | if (!CollectionUtils.isEmpty(dictDataList)) { 38 | throw new NewbieException("请先删除数据后再删除类型"); 39 | } 40 | // 删除字典类型 41 | sysDictTypeMapper.deleteBatchIds(idList); 42 | } 43 | } 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysLogLogin.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.*; 4 | import lombok.Data; 5 | import org.springframework.util.StringUtils; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | import java.util.Date; 10 | 11 | /** 12 | * 系统登录日志 13 | * @TableName sys_log_login 14 | */ 15 | @TableName(value ="sys_log_login") 16 | @Data 17 | public class SysLogLogin implements Serializable { 18 | /** 19 | * 主键 20 | */ 21 | @TableId(type = IdType.ASSIGN_ID) 22 | private String id; 23 | 24 | /** 25 | * 状态 1 成功,0 失败 26 | */ 27 | private String status; 28 | 29 | /** 30 | * 登录IP 31 | */ 32 | private String loginIp; 33 | 34 | /** 35 | * 登录方式 36 | */ 37 | private String loginMethod; 38 | 39 | /** 40 | * 失败原因 41 | */ 42 | private String failReason; 43 | 44 | /** 45 | * 操作系统 46 | */ 47 | private String os; 48 | 49 | /** 50 | * 浏览器信息 51 | */ 52 | private String browser; 53 | 54 | /** 55 | * 消耗时长,毫秒 56 | */ 57 | private Long costTime; 58 | 59 | /** 60 | * 1 登入,0 登出 61 | */ 62 | private String loginType; 63 | 64 | /** 65 | * 创建时间 66 | */ 67 | @TableField(fill = FieldFill.INSERT) 68 | private Date createTime; 69 | 70 | /** 71 | * 用户名 72 | */ 73 | private String username; 74 | 75 | public void setFailReason(String msg) { 76 | if (StringUtils.hasLength(msg) && msg.length() > 1000) { 77 | this.failReason = msg.substring(0, 1000); 78 | } else { 79 | this.failReason = msg; 80 | } 81 | } 82 | 83 | @Serial 84 | @TableField(exist = false) 85 | private static final long serialVersionUID = 1L; 86 | } -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/mapper/MysqlGeneratorMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 17 | 18 | 33 | 34 | 35 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/util/R.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.util; 2 | 3 | 4 | import lombok.Data; 5 | import lombok.experimental.Accessors; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | 10 | /** 11 | * Created by IntelliJ IDEA. 12 | * 13 | * @param 响应数据类型 14 | * @Author: ZhangYuGe 15 | * @Date: 2024/4/15 22:07 16 | * @Descriptions: 响应数据封装 17 | */ 18 | @Data 19 | @Accessors(chain = true) 20 | public class R implements Serializable { 21 | @Serial 22 | private static final long serialVersionUID = 1L; 23 | 24 | public static final String SUCCESS_MSG = "成功"; 25 | public static final Integer SUCCESS_CODE = 200; 26 | public static final String ERROR_MSG = "未知异常,请联系管理员"; 27 | public static final Integer ERROR_CODE = 500; 28 | 29 | private Integer code; 30 | private String msg; 31 | private T data; 32 | private Boolean ok; 33 | 34 | public R() { 35 | } 36 | 37 | /** 38 | * 成功(带数据) 39 | * 40 | * @param data 响应数据 41 | */ 42 | public static R ok(T data) { 43 | return new R() 44 | .setCode(SUCCESS_CODE) 45 | .setMsg(SUCCESS_MSG) 46 | .setOk(true) 47 | .setData(data); 48 | } 49 | 50 | /** 51 | * 成功(不带数据) 52 | */ 53 | public static R ok() { 54 | return R.ok(null); 55 | } 56 | 57 | /** 58 | * 失败 59 | * 60 | * @param code 代码 61 | * @param msg 消息 62 | */ 63 | public static R error(int code, String msg) { 64 | return new R() 65 | .setCode(code) 66 | .setMsg(msg) 67 | .setOk(false); 68 | } 69 | 70 | /** 71 | * 失败 72 | * 73 | * @param msg 消息 74 | */ 75 | public static R error(String msg) { 76 | return R.error(ERROR_CODE, msg); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/mapper/SecurityMapper.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.mapper; 2 | 3 | import com.newbie.common.domain.entity.SysDept; 4 | import com.newbie.common.domain.entity.SysMenu; 5 | import com.newbie.common.domain.entity.SysRole; 6 | import com.newbie.common.domain.entity.SysUser; 7 | import org.apache.ibatis.annotations.Mapper; 8 | import org.apache.ibatis.annotations.Param; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Created by IntelliJ IDEA. 14 | * 15 | * @Author: ZhangYuGe 16 | * @Email 398698424@qq.com 17 | * @Date: 2024/4/16 19:44 18 | * @Descriptions: unknown 19 | */ 20 | @Mapper 21 | public interface SecurityMapper { 22 | 23 | /** 24 | * 根据用户名查询用户 25 | * @param username 用户名 26 | * @return 用户 27 | */ 28 | SysUser selectUserByUsername(String username); 29 | 30 | /** 31 | * 根据用户id查询菜单列表 32 | * @param userId 用户ID 33 | * @return 菜单列表 34 | */ 35 | List selectMenuListByUserId(@Param("userId") String userId,@Param("menuType") String menuType); 36 | 37 | /** 38 | * 根据用户ID查询角色列表 39 | * @param userId 用户ID 40 | * @return 角色列表 41 | */ 42 | List selectRoleListByUserId(String userId); 43 | 44 | /** 45 | * 初始化管理员用户 46 | * @param sysUser 用户对象 47 | */ 48 | int insertAdminUser(SysUser sysUser); 49 | 50 | /** 51 | * 查询所有菜单 52 | * @return 菜单列表 53 | */ 54 | List selectMenuAll(); 55 | 56 | /** 57 | * 根据用户ID查询用户 58 | * @param userId 用户ID 59 | * @return 用户 60 | */ 61 | SysUser selectUserByUserId(String userId); 62 | 63 | /** 64 | * 根据用户ID更新用户密码 65 | * @param sysUser 用户对象 66 | */ 67 | int updateUserPasswordByUserId(SysUser sysUser); 68 | 69 | /** 70 | * 根据部门ID获取部门信息 71 | * @param deptId 部门ID 72 | * @return 73 | */ 74 | SysDept selectDeptByDeptId(String deptId); 75 | } 76 | -------------------------------------------------------------------------------- /newbie-admin/src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | # springdoc-openapi项目配置 2 | springdoc: 3 | api-docs: 4 | enabled: false 5 | spring: 6 | # 数据源配置 7 | datasource: 8 | # ==============Mysql============== 9 | driver-class-name: com.mysql.cj.jdbc.Driver 10 | url: jdbc:mysql://localhost:3306/newbie3?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8&allowMultiQueries=true 11 | username: root 12 | password: root 13 | # ==============Pgsql============== 14 | # driver-class-name: org.postgresql.Driver 15 | # url: jdbc:postgresql://localhost:5432/user_JNcKh5 16 | # username: postgresql 17 | # password: postgresql 18 | # ==============Oracle============== 19 | # driverClassName: oracle.jdbc.driver.OracleDriver 20 | # url: jdbc:oracle:thin:@localhost:1521/orcl 21 | # username: newbie 22 | # password: newbie 23 | data: 24 | redis: 25 | host: localhost 26 | password: 27 | port: 6379 28 | timeout: 10s 29 | lettuce: 30 | pool: 31 | max-active: 200 32 | max-wait: -1ms 33 | max-idle: 10 34 | min-idle: 1 35 | newbie: 36 | # 日志 37 | weblog: 38 | enable: false 39 | default-strategy: all_api 40 | only-error: true 41 | # 验证码配置 42 | captcha: 43 | timeout: 60 #超时(单位:秒) 44 | # 文件服务配置 45 | file: 46 | scheme: default 47 | prefix: public 48 | # 本服务器文件保存磁盘地址 49 | file-location: /var/www/files 50 | # minio 51 | minio: 52 | end-point: http://localhost:9000 53 | access-key: upaGr2JF0uGD7dxpLzqM 54 | secret-key: NZvAgDfqr58OvcUrW9G942kmv4MSX40QTIuxTX0f 55 | bucket: files 56 | sa-token: 57 | # 白名单 58 | white-list: /security/login, /security/initAdmin, /security/imageCaptcha, /public/**, /file/download 59 | # jwt秘钥 60 | jwt-secret-key: bsdasdasifhueuiwyurfewbfjsdafjg 61 | # token有效期半小时(单位:秒) 62 | timeout: 1800 63 | is-log: false -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/impl/SysRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.newbie.common.domain.entity.SysRole; 6 | import com.newbie.common.domain.entity.SysRoleMenu; 7 | import com.newbie.common.domain.entity.SysUserRole; 8 | import com.newbie.common.exception.NewbieException; 9 | import com.newbie.system.mapper.SysRoleMapper; 10 | import com.newbie.system.mapper.SysRoleMenuMapper; 11 | import com.newbie.system.mapper.SysUserRoleMapper; 12 | import com.newbie.system.service.SysRoleService; 13 | import lombok.RequiredArgsConstructor; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.transaction.annotation.Transactional; 16 | 17 | import java.util.List; 18 | 19 | /** 20 | * @author 39869 21 | * @description 针对表【sys_role(角色表)】的数据库操作Service实现 22 | * @createDate 2024-04-16 15:30:47 23 | */ 24 | @Service 25 | @RequiredArgsConstructor 26 | public class SysRoleServiceImpl extends ServiceImpl 27 | implements SysRoleService { 28 | 29 | private final SysRoleMapper sysRoleMapper; 30 | private final SysUserRoleMapper sysUserRoleMapper; 31 | private final SysRoleMenuMapper sysRoleMenuMapper; 32 | 33 | @Override 34 | @Transactional 35 | public void deleteBatch(List idList) { 36 | // 查询用户角色关系 37 | if (sysUserRoleMapper.selectCount(new LambdaQueryWrapper() 38 | .in(SysUserRole::getRoleId, idList)) > 0) throw new NewbieException("请先解除用户与角色的关联后再次尝试"); 39 | // 查询角色菜单关系 40 | if (sysRoleMenuMapper.selectCount(new LambdaQueryWrapper() 41 | .in(SysRoleMenu::getRoleId,idList)) > 0) throw new NewbieException("请先解除角色与菜单/按钮的关联后再次尝试"); 42 | 43 | sysRoleMapper.deleteBatchIds(idList); 44 | } 45 | } 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /newbie-admin/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # springdoc-openapi项目配置 2 | springdoc: 3 | api-docs: 4 | enabled: true 5 | spring: 6 | # 数据源配置 7 | datasource: 8 | # ==============Mysql============== 9 | driver-class-name: com.mysql.cj.jdbc.Driver 10 | url: jdbc:mysql://localhost:3306/newbie3?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8&allowMultiQueries=true 11 | username: root 12 | password: root 13 | # ==============Pgsql============== 14 | # driver-class-name: org.postgresql.Driver 15 | # url: jdbc:postgresql://localhost:5432/user_JNcKh5 16 | # username: postgresql 17 | # password: postgresql 18 | # ==============Oracle============== 19 | # driverClassName: oracle.jdbc.driver.OracleDriver 20 | # url: jdbc:oracle:thin:@localhost:1521/orcl 21 | # username: newbie 22 | # password: newbie 23 | data: 24 | redis: 25 | host: localhost 26 | password: 27 | port: 6379 28 | timeout: 10s 29 | lettuce: 30 | pool: 31 | max-active: 200 32 | max-wait: -1ms 33 | max-idle: 10 34 | min-idle: 1 35 | newbie: 36 | # 日志 37 | weblog: 38 | enable: true # 是否开启日志记录 39 | default-strategy: all_api # 默认策略:all_api:记录所有接口,* default: 记录带有 WebLog 注解的接口的日志 40 | only-error: true # 仅记录错误日志 41 | # 验证码配置 42 | captcha: 43 | timeout: 60 #超时(单位:秒) 44 | # 文件服务配置 45 | file: 46 | scheme: default # * default:服务器本地磁盘文件存储,minio:使用minio 47 | prefix: public # 文件访问前缀 48 | # 本服务器文件保存磁盘地址 49 | file-location: D:/project/upload 50 | # minio 51 | minio: 52 | end-point: http://localhost:9000 53 | access-key: upaGr2JF0uGD7dxpLzqM 54 | secret-key: NZvAgDfqr58OvcUrW9G942kmv4MSX40QTIuxTX0f 55 | bucket: files 56 | sa-token: 57 | # 白名单 58 | white-list: /security/login, /security/initAdmin, /security/imageCaptcha, /public/**, /file/download 59 | # token有效期半小时(单位:秒) 60 | timeout: 1800 61 | is-log: false -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/impl/SysUserRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 6 | import com.newbie.common.domain.entity.SysUser; 7 | import com.newbie.common.domain.entity.SysUserRole; 8 | import com.newbie.system.mapper.SysUserMapper; 9 | import com.newbie.system.mapper.SysUserRoleMapper; 10 | import com.newbie.system.service.SysUserRoleService; 11 | import lombok.RequiredArgsConstructor; 12 | import org.springframework.stereotype.Service; 13 | import org.springframework.transaction.annotation.Transactional; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * @author 39869 19 | * @description 针对表【sys_user_role(用户和角色关系表)】的数据库操作Service实现 20 | * @createDate 2024-04-16 15:30:47 21 | */ 22 | @Service 23 | @RequiredArgsConstructor 24 | public class SysUserRoleServiceImpl extends ServiceImpl 25 | implements SysUserRoleService { 26 | private final SysUserRoleMapper sysUserRoleMapper; 27 | private final SysUserMapper sysUserMapper; 28 | 29 | @Transactional 30 | @Override 31 | public void removeByUserIdAndRoleIds(String userId, List roleIds) { 32 | sysUserRoleMapper.removeByUserIdAndRoleIds(userId,roleIds); 33 | } 34 | 35 | @Transactional 36 | @Override 37 | public void removeByRoleIdAndUserIds(String roleId, List userIds) { 38 | sysUserRoleMapper.removeByRoleIdAndUserIds(roleId,userIds); 39 | 40 | } 41 | @Override 42 | public IPage queryUserByRoleId(Page page, SysUser sysUser, String roleId) { 43 | return sysUserMapper.queryUserByRoleId(page, sysUser, roleId); 44 | } 45 | 46 | @Override 47 | public IPage queryUnUserByRoleId(Page page, SysUser sysUser, String roleId) { 48 | return sysUserMapper.queryUnUserByRoleId(page, sysUser, roleId); 49 | } 50 | } 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/templates/menu.sql.ftl: -------------------------------------------------------------------------------- 1 | -- 需要自定义的值:搜索 aaa 替换为父级菜单ID的值。 2 | -- 菜单ID ${menuId} 3 | -- 新增按钮ID ${addButId} 4 | -- 修改按钮ID ${updateButId} 5 | -- 删除按钮ID ${deleteButId} 6 | 7 | 8 | 9 | -- 页面菜单 10 | INSERT INTO sys_menu (id,title, parent_id, sort, status, route_path, route_name, component, remark, create_by, create_time, update_by, update_time, is_keep, type, is_hide, perm, icon, hide_children, iframe_link, is_outer, transition, fixed_tab, ancestors, tier) 11 | VALUES ('${menuId}','${comment}', 'aaa', 1, '1', '/${gc.moduleName}/${entity}', '${gc.ModuleName}${entity}Vue', '${gc.moduleName}/${entity}/index', NULL, 'NewbieGenerator', '${gc.date}', NULL, NULL, '0', '1', '0', '${gc.moduleName}.${entity}.list', '', '0', '', '0', '', '0', 'aaa,${menuId}', 1); 12 | 13 | -- 新增按钮 14 | INSERT INTO sys_menu (id, title, parent_id, sort, status, remark, create_by, create_time, is_keep, type, is_hide, perm, icon, hide_children, iframe_link, is_outer, transition, fixed_tab, ancestors, tier) 15 | VALUES ('${addButId}', '新增', '${menuId}', 1, '1', '新增按钮', 'NewbieGenerator', '${gc.date}', '0', '0', '0', '${gc.moduleName}.${entity}.add', NULL, '0', NULL, '0', NULL, '0', 'aaa,${menuId},${addButId}', 2); 16 | 17 | -- 修改按钮 18 | INSERT INTO sys_menu (id, title, parent_id, sort, status, remark, create_by, create_time, is_keep, type, is_hide, perm, icon, hide_children, iframe_link, is_outer, transition, fixed_tab, ancestors, tier) 19 | VALUES ('${updateButId}', '修改', '${menuId}', 2, '1', '修改按钮', 'NewbieGenerator', '${gc.date}', '0', '0', '0', '${gc.moduleName}.${entity}.update', NULL, '0', NULL, '0', NULL, '0', 'aaa,${menuId},${updateButId}', 2); 20 | 21 | -- 删除按钮 22 | INSERT INTO sys_menu (id, title, parent_id, sort, status, remark, create_by, create_time, is_keep, type, is_hide, perm, icon, hide_children, iframe_link, is_outer, transition, fixed_tab, ancestors, tier) 23 | VALUES ('${deleteButId}', '删除', '${menuId}', 3, '1', '删除按钮', 'NewbieGenerator', '${gc.date}', '0', '0', '0', '${gc.moduleName}.${entity}.delete', NULL, '0', NULL, '0', NULL, '0', 'aaa,${menuId},${deleteButId}', 2); 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /newbie-admin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.newbie 8 | newbie-boot3 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | newbie-admin 13 | jar 14 | 15 | 16 | 21 17 | 21 18 | UTF-8 19 | 20 | 21 | 22 | 23 | com.newbie 24 | newbie-system 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-test 29 | test 30 | 31 | 32 | com.newbie 33 | newbie-file 34 | 35 | 36 | com.newbie 37 | newbie-security 38 | 39 | 40 | com.newbie 41 | newbie-weblog 42 | 43 | 44 | com.newbie 45 | newbie-generator 46 | 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-maven-plugin 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /newbie-weblog/src/main/java/com/newbie/weblog/aspect/AllApiWebLogAspect.java: -------------------------------------------------------------------------------- 1 | package com.newbie.weblog.aspect; 2 | 3 | import com.newbie.weblog.conditional.AllApiStrategyConditional; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.aspectj.lang.annotation.Around; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.annotation.Pointcut; 10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 11 | import org.springframework.context.annotation.Conditional; 12 | import org.springframework.stereotype.Component; 13 | 14 | @Aspect 15 | @Component 16 | @ConditionalOnWebApplication 17 | @Conditional(AllApiStrategyConditional.class) 18 | @Slf4j 19 | @RequiredArgsConstructor 20 | public class AllApiWebLogAspect { 21 | 22 | static { 23 | log.info("启用 Web Log 记录日志 ---- 使用 ALL_API 策略"); 24 | } 25 | 26 | private final WebLogAspectAdvice webLogAspectAdvice; 27 | 28 | @Pointcut( 29 | "@annotation(org.springframework.web.bind.annotation.GetMapping) " + 30 | "|| @annotation(org.springframework.web.bind.annotation.PostMapping) " + 31 | "|| @annotation(org.springframework.web.bind.annotation.PutMapping) " + 32 | "|| @annotation(org.springframework.web.bind.annotation.DeleteMapping)" + 33 | "|| @annotation(org.springframework.web.bind.annotation.PatchMapping)" + 34 | "|| @annotation(org.springframework.web.bind.annotation.RequestMapping)" 35 | 36 | ) 37 | public void requestMappingCut() { 38 | } 39 | 40 | @Pointcut("@annotation(com.newbie.common.annotation.IgnoreWebLog) || @within(com.newbie.common.annotation.IgnoreWebLog)") 41 | public void ignoreWebLogCut() { 42 | } 43 | 44 | @Pointcut("requestMappingCut() && !ignoreWebLogCut()") 45 | public void webLogCut() { 46 | } 47 | 48 | @Around(value = "webLogCut()") 49 | public Object doAroundAdvice(ProceedingJoinPoint point) throws Throwable { 50 | return webLogAspectAdvice.doAroundAdvice(point); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/config/MetaObjectHandlerImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.config; 2 | 3 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 4 | import com.newbie.common.domain.entity.SysUser; 5 | import com.newbie.common.util.SecurityUtils; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.apache.ibatis.reflection.MetaObject; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.Date; 11 | 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * 16 | * @Author: ZhangYuGe 17 | * @Email 398698424@qq.com 18 | * @Date: 2024/4/17 上午9:02 19 | * @Descriptions: 自动填充实现 20 | */ 21 | @Slf4j 22 | @Component 23 | public class MetaObjectHandlerImpl implements MetaObjectHandler { 24 | 25 | /** 26 | * 数据插入自动填充 27 | * 28 | * @param metaObject 元对象 29 | */ 30 | @Override 31 | public void insertFill(MetaObject metaObject) { 32 | // 如果 有createTime 且 为null 则赋值当前时间 33 | if (metaObject.hasSetter("createTime") && metaObject.getValue("createTime") == null) { 34 | metaObject.setValue("createTime", new Date()); 35 | } 36 | 37 | // 如果 有createBy 且 为null 则赋值当前用户名 38 | if (metaObject.hasSetter("createBy") && metaObject.getValue("createBy") == null) { 39 | try { 40 | SysUser currentUser = SecurityUtils.getCurrentLoginUser(); 41 | metaObject.setValue("createBy", currentUser.getUsername()); 42 | }catch (Exception ignored){ 43 | 44 | } 45 | 46 | } 47 | 48 | } 49 | 50 | @Override 51 | public void updateFill(MetaObject metaObject) { 52 | 53 | // 如果 有updateTime 则赋值当前时间 54 | if (metaObject.hasSetter("updateTime")) { 55 | metaObject.setValue("updateTime", new Date()); 56 | } 57 | 58 | // 如果 有updateBy 则赋值当前用户名 59 | if (metaObject.hasSetter("updateBy")) { 60 | try { 61 | SysUser currentUser = SecurityUtils.getCurrentLoginUser(); 62 | metaObject.setValue("updateBy", currentUser.getUsername()); 63 | }catch (Exception ignored){ 64 | 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.config; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 6 | import jakarta.annotation.Resource; 7 | import org.mybatis.spring.annotation.MapperScan; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | 11 | import javax.sql.DataSource; 12 | import java.sql.Connection; 13 | import java.sql.DatabaseMetaData; 14 | import java.sql.SQLException; 15 | 16 | /** 17 | * Created by IntelliJ IDEA. 18 | * 19 | * @Author: ZhangYuGe 20 | * @Email 398698424@qq.com 21 | * @Date: 2024/4/17 下午4:24 22 | * @Descriptions: mybatis-plus配置 23 | */ 24 | @Configuration 25 | @MapperScan("com.newbie.**.mapper") 26 | public class MybatisPlusConfig { 27 | @Resource 28 | private DataSource dataSource; 29 | /** 30 | * 分页插件 31 | * @return 32 | */ 33 | @Bean 34 | MybatisPlusInterceptor mybatisPlusInterceptor(){ 35 | PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); 36 | try { 37 | Connection connection = dataSource.getConnection(); 38 | DatabaseMetaData metaData = connection.getMetaData(); 39 | String url = metaData.getURL(); 40 | if (url.contains("mysql")) { 41 | paginationInnerInterceptor.setDbType(DbType.MYSQL); 42 | }else if (url.contains("oracle")) { 43 | paginationInnerInterceptor.setDbType(DbType.ORACLE); 44 | }else if (url.contains("postgresql")) { 45 | paginationInnerInterceptor.setDbType(DbType.POSTGRE_SQL); 46 | } 47 | MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); 48 | mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor); 49 | return mybatisPlusInterceptor; 50 | } catch (SQLException e) { 51 | throw new RuntimeException(e); 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /newbie-file/src/main/java/com/newbie/file/config/FileServiceConfig.java: -------------------------------------------------------------------------------- 1 | package com.newbie.file.config; 2 | 3 | import com.newbie.file.enums.FileServiceSchemeEnum; 4 | import com.newbie.file.service.FileService; 5 | import com.newbie.file.service.impl.FileServiceImpl; 6 | import com.newbie.file.service.impl.MinioServiceImpl; 7 | import io.minio.MinioClient; 8 | import lombok.Data; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.boot.context.properties.ConfigurationProperties; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | 14 | /** 15 | * Created by IntelliJ IDEA. 16 | * 17 | * @Author: ZhangYuGe 18 | * @Email 398698424@qq.com 19 | * @Date: 2024/4/24 下午4:59 20 | * @Descriptions: 文件服务配置 21 | */ 22 | @Configuration 23 | @Data 24 | @Slf4j 25 | @ConfigurationProperties(prefix = "newbie.file") 26 | public class FileServiceConfig { 27 | private FileServiceSchemeEnum scheme = FileServiceSchemeEnum.DEFAULT; 28 | private String fileLocation; 29 | private String prefix; 30 | private MinioConfigProperties minio; 31 | 32 | @Bean 33 | public FileService fileService() { 34 | log.info("init fileService start"); 35 | FileService fileService = null; 36 | if (FileServiceSchemeEnum.MINIO.equals(this.scheme)) { 37 | fileService = new MinioServiceImpl( 38 | // 创建Minio客户端 39 | MinioClient.builder() 40 | .endpoint(minio.getEndPoint()) 41 | .credentials(minio.getAccessKey(), minio.getSecretKey()) 42 | .build(), 43 | minio.getBucket(), 44 | this.prefix 45 | ); 46 | log.info("FileService scheme is selected MINIO,endPoint={},bucket={}",minio.getEndPoint(),minio.getBucket()); 47 | } else if (FileServiceSchemeEnum.DEFAULT.equals(this.scheme)) { 48 | fileService = new FileServiceImpl(this.fileLocation,this.prefix); 49 | log.info("FileService scheme is selected DEFAULT,fileLocation={}",this.fileLocation); 50 | } 51 | return fileService; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/controller/file/FileController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.controller.file; 2 | 3 | import com.newbie.file.domain.body.FileBody; 4 | import com.newbie.file.domain.vo.FileVO; 5 | import com.newbie.common.exception.NewbieException; 6 | import com.newbie.file.service.FileService; 7 | import com.newbie.common.util.R; 8 | import io.swagger.v3.oas.annotations.Operation; 9 | import io.swagger.v3.oas.annotations.tags.Tag; 10 | import jakarta.servlet.http.HttpServletResponse; 11 | import lombok.RequiredArgsConstructor; 12 | import org.springframework.util.CollectionUtils; 13 | import org.springframework.util.StringUtils; 14 | import org.springframework.web.bind.annotation.*; 15 | import org.springframework.web.multipart.MultipartFile; 16 | 17 | import java.util.List; 18 | 19 | /** 20 | * Created by IntelliJ IDEA. 21 | * 22 | * @Author: ZhangYuGe 23 | * @Email 398698424@qq.com 24 | * @Date: 2024/4/23 下午6:46 25 | * @Descriptions: 文件控制器 26 | */ 27 | @RestController 28 | @RequestMapping("/file") 29 | @RequiredArgsConstructor 30 | @Tag(name = "文件服务") 31 | public class FileController { 32 | private final FileService fileService; 33 | 34 | /** 35 | * 文件上传 36 | * 37 | * @param fileBody 文件对象 38 | * @return 文件路径数组 39 | */ 40 | @Operation(summary ="上传") 41 | @PostMapping("/upload") 42 | public R> upload(FileBody fileBody) { 43 | List files = fileBody.getFile(); 44 | if (CollectionUtils.isEmpty(files)) { 45 | throw new NewbieException("请选择文件"); 46 | } 47 | return R.ok( fileService.upload(files)).setMsg("上传成功"); 48 | } 49 | 50 | /** 51 | * 下载文件 52 | * 53 | * @param filePath 文件的路径 54 | */ 55 | @Operation(summary ="下载") 56 | @GetMapping("/download") 57 | public void download(String filePath, HttpServletResponse response) { 58 | fileService.download(filePath,response); 59 | } 60 | 61 | 62 | @Operation(summary ="删除") 63 | @GetMapping("/remove") 64 | public R remove(String filePath) { 65 | if(!StringUtils.hasLength(filePath)){ 66 | return R.error("文件路径不能为空"); 67 | } 68 | fileService.remove(filePath); 69 | return R.ok().setMsg("文件删除成功"); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/controller/system/SysDeptController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.controller.system; 2 | 3 | import cn.dev33.satoken.annotation.SaCheckPermission; 4 | import com.newbie.common.domain.entity.SysDept; 5 | import com.newbie.common.util.R; 6 | import com.newbie.system.domain.vo.SysDeptVO; 7 | import com.newbie.system.service.SysDeptService; 8 | import io.swagger.v3.oas.annotations.Operation; 9 | import io.swagger.v3.oas.annotations.tags.Tag; 10 | import lombok.RequiredArgsConstructor; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import java.util.Arrays; 14 | import java.util.List; 15 | 16 | @RestController 17 | @RequestMapping("/system/dept") 18 | @RequiredArgsConstructor 19 | @Tag(name = "部门管理") 20 | public class SysDeptController { 21 | 22 | private final SysDeptService sysDeptService; 23 | 24 | @Operation(summary ="获取部门树") 25 | @SaCheckPermission("sys.dept") 26 | @GetMapping("/tree") 27 | public R> getDeptTree(SysDept sysDept) { 28 | return R.ok(sysDeptService.getDeptTree(sysDept)); 29 | } 30 | 31 | @Operation(summary ="新增部门") 32 | @SaCheckPermission("sys.dept.add") 33 | @PostMapping("/add") 34 | public R addDept(@RequestBody SysDept sysDept) { 35 | String deptId = sysDept.getId(); 36 | if (deptId != null) { 37 | return R.error("请检查此数据是否已存在,deptId=" + deptId); 38 | } 39 | return sysDeptService.addDept(sysDept) ? R.ok().setMsg("新增成功") : R.error("新增失败"); 40 | } 41 | 42 | @Operation(summary ="修改部门") 43 | @SaCheckPermission("sys.dept.update") 44 | @PostMapping("/update") 45 | public R updateDept(@RequestBody SysDept sysDept) { 46 | if (sysDept.getId() == null) { 47 | return R.error("部门ID为空"); 48 | } 49 | return sysDeptService.updateDept(sysDept) ? R.ok().setMsg("修改成功") : R.error("修改失败"); 50 | } 51 | 52 | @Operation(summary ="批量删除部门") 53 | @SaCheckPermission("sys.dept.del") 54 | @PostMapping("/deleteBatch") 55 | public R deleteBatch(@RequestBody String[] ids) { 56 | if (ids == null || ids.length == 0) return R.error("部门ID为空"); 57 | sysDeptService.deleteBatch(Arrays.asList(ids)); 58 | return R.ok().setMsg("删除成功"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/domain/entity/SysMenu.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.domain.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.*; 4 | 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | 8 | /** 9 | * 系统菜单表 10 | * @TableName sys_menu 11 | */ 12 | @EqualsAndHashCode(callSuper = true) 13 | @TableName(value ="sys_menu") 14 | @Data 15 | public class SysMenu extends BaseEntity { 16 | 17 | 18 | /** 19 | * 菜单标题 20 | */ 21 | private String title; 22 | 23 | /** 24 | * 父菜单ID 25 | */ 26 | private String parentId; 27 | 28 | /** 29 | * 排序 30 | */ 31 | private Integer sort; 32 | 33 | /** 34 | * 菜单状态(1正常 0停用) 35 | */ 36 | private String status; 37 | 38 | /** 39 | * 路由地址 40 | */ 41 | private String routePath; 42 | 43 | /** 44 | * 路由name 45 | */ 46 | private String routeName; 47 | 48 | /** 49 | * 组件路径 50 | */ 51 | private String component; 52 | 53 | /** 54 | * 备注 55 | */ 56 | private String remark; 57 | 58 | /** 59 | * 是否缓存组件(1缓存 0不缓存) 60 | */ 61 | private String isKeep; 62 | 63 | /** 64 | * 菜单类型(1菜单 0按钮) 65 | */ 66 | private String type; 67 | 68 | /** 69 | * 是否隐藏菜单(1是 0否 ) 70 | */ 71 | private String isHide; 72 | 73 | /** 74 | * 权限标识 75 | */ 76 | private String perm; 77 | 78 | /** 79 | * 菜单图标 80 | */ 81 | private String icon; 82 | 83 | /** 84 | * 是否隐藏子级菜单(1是 0否) 85 | */ 86 | private String hideChildren; 87 | 88 | /** 89 | * 内嵌外链接地址 90 | */ 91 | private String iframeLink; 92 | 93 | /** 94 | * 是否在layout外显示(1是 0否) 95 | */ 96 | private String isOuter; 97 | 98 | /** 99 | * 切换动画 100 | */ 101 | private String transition; 102 | 103 | /** 104 | * 是否固定在tabs(1是 0否) 105 | */ 106 | private String fixedTab; 107 | 108 | /** 109 | * 祖级列表 110 | */ 111 | private String ancestors; 112 | 113 | /** 114 | * 层级 115 | */ 116 | private Integer tier; 117 | 118 | /** 119 | * 重定向 120 | */ 121 | private String routeRedirect; 122 | } -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/controller/system/SysMenuController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.controller.system; 2 | 3 | import cn.dev33.satoken.annotation.SaCheckPermission; 4 | import com.newbie.common.domain.entity.SysMenu; 5 | import com.newbie.common.util.R; 6 | import com.newbie.system.domain.vo.SysMenuVO; 7 | import com.newbie.system.service.SysMenuService; 8 | import io.swagger.v3.oas.annotations.Operation; 9 | import io.swagger.v3.oas.annotations.tags.Tag; 10 | import lombok.RequiredArgsConstructor; 11 | import org.springframework.util.StringUtils; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | @RestController 18 | @RequestMapping("/system/menu") 19 | @RequiredArgsConstructor 20 | @Tag(name = "菜单管理") 21 | public class SysMenuController { 22 | private final SysMenuService sysMenuService; 23 | 24 | @Operation(summary ="查询菜单树") 25 | @SaCheckPermission("sys.menu") 26 | @GetMapping("/tree") 27 | public R> tree(SysMenu sysMenu) { 28 | List ls = sysMenuService.menuTree(sysMenu); 29 | return R.ok(ls); 30 | } 31 | 32 | @Operation(summary ="新增") 33 | @SaCheckPermission("sys.menu.add") 34 | @PostMapping("/add") 35 | public R add(@RequestBody SysMenu sysMenu) { 36 | String menuId = sysMenu.getId(); 37 | if (StringUtils.hasLength(menuId)) 38 | return R.error("请检查此数据是否已存在,menuId=" + menuId); 39 | 40 | return sysMenuService.addData(sysMenu) ? R.ok().setMsg("新增成功") : R.error("新增失败"); 41 | } 42 | 43 | @Operation(summary ="修改") 44 | @SaCheckPermission("sys.menu.update") 45 | @PostMapping("/update") 46 | public R update(@RequestBody SysMenu sysMenu) { 47 | if (sysMenu.getId() == null) { 48 | return R.error("菜单ID为空"); 49 | } 50 | return sysMenuService.updateData(sysMenu) ? R.ok().setMsg("修改成功") : R.error("修改失败"); 51 | } 52 | 53 | @Operation(summary ="批量删除") 54 | @SaCheckPermission("sys.menu.del") 55 | @PostMapping("/deleteBatch") 56 | public R deleteBatch(@RequestBody String[] ids) { 57 | if (ids == null || ids.length == 0) return R.error("菜单ID为空"); 58 | sysMenuService.deleteBatch(Arrays.asList(ids)); 59 | return R.ok().setMsg("删除成功"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/service/impl/GeneratorServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.newbie.generator.domain.ColumnInfo; 5 | import com.newbie.generator.domain.GenConfigEntity; 6 | import com.newbie.generator.domain.GenerateBody; 7 | import com.newbie.generator.domain.TableInfo; 8 | import com.newbie.generator.mapper.GenConfigMapper; 9 | import com.newbie.generator.mapper.GeneratorMapper; 10 | import com.newbie.generator.service.GeneratorService; 11 | import com.newbie.generator.util.GeneratorUtils; 12 | import jakarta.servlet.http.HttpServletResponse; 13 | import lombok.RequiredArgsConstructor; 14 | import lombok.SneakyThrows; 15 | import org.springframework.stereotype.Service; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | @Service 21 | @RequiredArgsConstructor 22 | public class GeneratorServiceImpl implements GeneratorService { 23 | private final GeneratorMapper generatorMapper; 24 | private final GenConfigMapper genConfigMapper; 25 | @SneakyThrows 26 | @Override 27 | public void generatorCode(GenerateBody generateBody, HttpServletResponse response) { 28 | response.reset(); 29 | 30 | // 获取生成器配置 31 | GenConfigEntity genConfig = genConfigMapper.selectById(generateBody.getConfigId()); 32 | 33 | // 获取表信息 34 | List tableInfoList = new ArrayList<>(); 35 | for (String tableName : generateBody.getTableNames()) { 36 | tableInfoList.add(this.getTableInfo(tableName)); 37 | } 38 | 39 | // 生成代码 40 | GeneratorUtils.generate(tableInfoList,genConfig,response.getOutputStream()); 41 | } 42 | 43 | /** 44 | * 获取表信息 45 | * 46 | * @param tableName 表名 47 | * @return TableInfo 48 | */ 49 | private TableInfo getTableInfo(String tableName) { 50 | TableInfo tableInfo = generatorMapper.selectTableByName(tableName); 51 | List columnInfoList = generatorMapper.selectColumnList(tableName); 52 | tableInfo.setColumns(columnInfoList); 53 | return tableInfo; 54 | } 55 | 56 | @Override 57 | public IPage getDbTableList(IPage page, TableInfo tableInfo) { 58 | return page.setRecords(generatorMapper.selectTableList(page,tableInfo)); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/lifecycle/CommandLineRunnerImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.lifecycle; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.autoconfigure.web.ServerProperties; 6 | import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; 7 | import org.springframework.boot.web.server.WebServer; 8 | import org.springframework.core.env.Environment; 9 | import org.springframework.stereotype.Component; 10 | 11 | import java.net.InetAddress; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * 16 | * @Author: ZhangYuGe 17 | * @Email 398698424@qq.com 18 | * @Date: 2024/4/17 下午4:28 19 | * @Descriptions: unknown 20 | */ 21 | @Component 22 | @RequiredArgsConstructor 23 | public class CommandLineRunnerImpl implements CommandLineRunner { 24 | private final Environment environment; 25 | 26 | @Override 27 | public void run(String... args) throws Exception { 28 | 29 | String ip = InetAddress.getLocalHost().getHostAddress(); 30 | String port = environment.getProperty("server.port"); 31 | String property = environment.getProperty("server.servlet.context-path"); 32 | String path = property == null ? "" : property; 33 | 34 | String appName = environment.getProperty("spring.application.name"); 35 | String name = appName == null ? "" : appName; 36 | 37 | String swaggerPath = path.endsWith("/") ? "swagger-ui/index.html" : "/swagger-ui/index.html"; 38 | String knife4jPath = path.endsWith("/") ? "doc.html" : "/doc.html"; 39 | 40 | System.out.printf("\n\t\t\t\t\t\t\u001B[%d;%dm%s\u001B[0m%n", 32, 2, "欢迎使用 NewbieBoot"); 41 | String content1 = """ 42 | ---------------------------------------------------------------------- 43 | Application %s is running! Access URLs: 44 | Local: http://localhost:%s%s 45 | External: http://%s:%s%s 46 | Swagger: http://localhost:%s%s%s 47 | Knife4j: http://localhost:%s%s%s 48 | ---------------------------------------------------------------------- 49 | """; 50 | System.out.printf("\u001B[%d;%dm%s\u001B[0m%n", 32, 2, String.format(content1, name, port, path, ip, port, path, port, path, swaggerPath, port, path, knife4jPath)); 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/config/SaTokenConfigure.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.config; 2 | 3 | import cn.dev33.satoken.config.SaTokenConfig; 4 | import cn.dev33.satoken.interceptor.SaInterceptor; 5 | import cn.dev33.satoken.jwt.StpLogicJwtForSimple; 6 | import cn.dev33.satoken.stp.StpLogic; 7 | import cn.dev33.satoken.stp.StpUtil; 8 | import lombok.Data; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.context.properties.ConfigurationProperties; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 14 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 15 | 16 | /** 17 | * Created by IntelliJ IDEA. 18 | * 19 | * @Author: ZhangYuGe 20 | * @Email 398698424@qq.com 21 | * @Date: 2024/4/16 10:29 22 | * @Descriptions: SaToken配置 23 | */ 24 | @Configuration 25 | @Data 26 | @ConfigurationProperties(prefix = "sa-token") 27 | public class SaTokenConfigure implements WebMvcConfigurer { 28 | public static final String[] STATIC_LIST = {"/**/error", "/**/favicon.ico","/**/*.html","/**/*.css","/**/*.js"}; 29 | 30 | // 白名单 31 | private String[] whiteList = { 32 | "/security/login", 33 | "/security/initAdmin", 34 | "/security/imageCaptcha", 35 | "/public/**", 36 | "/file/download" 37 | }; 38 | 39 | private static final String[] API_DOC = {"/v3/api-docs/**","/swagger-ui/**"}; 40 | 41 | /** 42 | * 注册拦截器 43 | * 44 | * @param registry 注册器 45 | */ 46 | @Override 47 | public void addInterceptors(InterceptorRegistry registry) { 48 | // 注册 Sa-Token 拦截器 49 | registry.addInterceptor(new SaInterceptor(handler -> StpUtil.checkLogin())) 50 | .addPathPatterns("/**") 51 | .excludePathPatterns(STATIC_LIST) 52 | .excludePathPatterns(this.whiteList) 53 | .excludePathPatterns(API_DOC); 54 | } 55 | 56 | // Sa-Token 整合 jwt 57 | @Bean 58 | public StpLogic getStpLogicJwt() { 59 | return new StpLogicJwtForSimple(); // Simple 简单模式 60 | } 61 | 62 | @Autowired 63 | public void configSaToken(SaTokenConfig config) { 64 | // jwt秘钥 65 | config.setJwtSecretKey("bsdasdasifhueuiwyurfewbfjsdafjg"); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/controller/GenConfigController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.controller; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.newbie.generator.service.IGenConfigService; 6 | import com.newbie.generator.domain.GenConfigEntity; 7 | import com.newbie.common.util.R; 8 | import lombok.RequiredArgsConstructor; 9 | import io.swagger.v3.oas.annotations.Operation; 10 | import cn.dev33.satoken.annotation.SaCheckPermission; 11 | import org.springframework.web.bind.annotation.*; 12 | import java.io.Serializable; 13 | import java.util.List; 14 | 15 | /** 16 | * Created by NewbieGenerator. 17 | * 18 | * @Author: ZhangYuGe 19 | * @Email 398698424@qq.com 20 | * @Date: 2024-10-04 21 | * @Descriptions: 代码生成器配置 Api 接口 22 | */ 23 | @RestController 24 | @RequestMapping("/generator/genConfig") 25 | @RequiredArgsConstructor 26 | public class GenConfigController { 27 | 28 | private final IGenConfigService iGenConfigService; 29 | 30 | @Operation(summary ="分页查询数据列表") 31 | @SaCheckPermission("generator.genConfig.list") 32 | @GetMapping("/page") 33 | public R> page(Page page, GenConfigEntity entity) { 34 | return R.ok(iGenConfigService.getPage(page,entity)); 35 | } 36 | 37 | @Operation(summary ="查询数据列表") 38 | @SaCheckPermission("generator.genConfig.list") 39 | @GetMapping("/list") 40 | public R> list(GenConfigEntity entity) { 41 | return R.ok(iGenConfigService.getList(entity)); 42 | } 43 | 44 | @Operation(summary ="新增数据") 45 | @SaCheckPermission("generator.genConfig.add") 46 | @PostMapping("/addData") 47 | public R addData(@RequestBody GenConfigEntity entity) { 48 | iGenConfigService.addData(entity); 49 | return R.ok(); 50 | } 51 | 52 | @Operation(summary ="根据主键更新数据") 53 | @SaCheckPermission("generator.genConfig.update") 54 | @PostMapping("/updateByPkVal") 55 | public R updateByPkVal(@RequestBody GenConfigEntity entity) { 56 | iGenConfigService.updateById(entity); 57 | return R.ok(); 58 | } 59 | @Operation(summary ="根据主键删除数据") 60 | @SaCheckPermission("generator.genConfig.delete") 61 | @PostMapping("/deleteByPkVal/{id}") 62 | public R deleteByPkVal(@PathVariable Serializable id) { 63 | iGenConfigService.deleteByPkVal(id); 64 | return R.ok(); 65 | } 66 | } -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/util/CamelCaseConverter.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.util; 2 | 3 | /** 4 | * 驼峰式变换器 5 | */ 6 | public class CamelCaseConverter { 7 | 8 | /** 9 | * 将下划线命名转换为小驼峰命名。 10 | * 11 | * @param underscoreStr 下划线命名的字符串 12 | * @return 小驼峰命名的字符串 13 | */ 14 | public static String toLowerCaseCamel(String underscoreStr) { 15 | StringBuilder result = new StringBuilder(); 16 | boolean nextUpperCase = false; 17 | for (char c : underscoreStr.toCharArray()) { 18 | if (c == '_') { 19 | nextUpperCase = true; 20 | } else { 21 | if (nextUpperCase) { 22 | result.append(Character.toUpperCase(c)); 23 | nextUpperCase = false; 24 | } else { 25 | result.append(c); 26 | } 27 | } 28 | } 29 | return result.toString(); 30 | } 31 | 32 | /** 33 | * 将下划线命名转换为大驼峰命名。 34 | * 35 | * @param underscoreStr 下划线命名的字符串 36 | * @return 大驼峰命名的字符串 37 | */ 38 | public static String toUpperCaseCamel(String underscoreStr) { 39 | StringBuilder result = new StringBuilder(); 40 | boolean nextUpperCase = true; 41 | for (char c : underscoreStr.toCharArray()) { 42 | if (c == '_') { 43 | nextUpperCase = true; 44 | } else { 45 | if (nextUpperCase) { 46 | result.append(Character.toUpperCase(c)); 47 | nextUpperCase = false; 48 | } else { 49 | result.append(c); 50 | } 51 | } 52 | } 53 | return result.toString(); 54 | } 55 | 56 | /** 57 | * 将驼峰命名转换为下划线命名。 58 | * 59 | * @param camelStr 驼峰命名的字符串 60 | * @return 下划线命名的字符串 61 | */ 62 | public static String toUnderscore(String camelStr) { 63 | StringBuilder result = new StringBuilder(); 64 | for (char c : camelStr.toCharArray()) { 65 | if (Character.isUpperCase(c)) { 66 | result.append('_'); 67 | result.append(Character.toLowerCase(c)); 68 | } else { 69 | result.append(c); 70 | } 71 | } 72 | return result.toString().toUpperCase().startsWith("_") ? result.toString().substring(1) : result.toString(); 73 | } 74 | 75 | 76 | public static void main(String[] args) { 77 | String text = "sys_dict_data"; 78 | System.out.println(toUpperCaseCamel(text)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /newbie-system/src/main/resources/mapper/SysDictDataMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | t.id,t.label,t.value, 26 | t.type_id,t.ele_type,t.ele_class, 27 | t.status,t.def,t.sort, 28 | t.remark,t.create_by,t.create_time, 29 | t.update_by,t.update_time 30 | 31 | 32 | 33 | UPDATE sys_dict_data 34 | SET def = 'N' 35 | WHERE type_id = #{typeId} 36 | AND def = 'Y' 37 | 38 | 39 | 40 | UPDATE sys_dict_data 41 | SET def = 'Y' 42 | WHERE id = #{id} 43 | 44 | 45 | 54 | 55 | -------------------------------------------------------------------------------- /newbie-security/src/main/java/com/newbie/security/service/impl/ImageCaptchaServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.security.service.impl; 2 | 3 | import cn.hutool.captcha.CaptchaUtil; 4 | import cn.hutool.captcha.LineCaptcha; 5 | import cn.hutool.captcha.generator.CodeGenerator; 6 | import cn.hutool.captcha.generator.MathGenerator; 7 | import com.newbie.common.exception.NewbieException; 8 | import com.newbie.security.domain.vo.Captcha; 9 | import com.newbie.security.domain.vo.ImageCaptcha; 10 | import com.newbie.security.service.CaptchaService; 11 | import lombok.RequiredArgsConstructor; 12 | import org.springframework.beans.factory.annotation.Value; 13 | import org.springframework.data.redis.core.RedisTemplate; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.util.StringUtils; 16 | 17 | import java.util.concurrent.TimeUnit; 18 | 19 | /** 20 | * Created by IntelliJ IDEA. 21 | * 22 | * @Author: ZhangYuGe 23 | * @Email 398698424@qq.com 24 | * @Date: 2024/4/23 上午11:17 25 | * @Descriptions: 图片验证码实现 26 | */ 27 | @Service 28 | @RequiredArgsConstructor 29 | public class ImageCaptchaServiceImpl implements CaptchaService { 30 | private final RedisTemplate redisTemplate; 31 | private final CodeGenerator codeGenerator = new MathGenerator(1); 32 | @Value("${newbie.captcha.timeout}") 33 | private Long timeout; 34 | 35 | @Override 36 | public Captcha create(String key) { 37 | LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100, this.codeGenerator, 0); 38 | String code = captcha.getCode(); 39 | ImageCaptcha imageCaptcha = new ImageCaptcha(); 40 | imageCaptcha.setCheckCodeKey(key); 41 | imageCaptcha.setImageBase64(captcha.getImageBase64Data()); 42 | 43 | // 缓存key和code 44 | redisTemplate.opsForValue().set(key, code, timeout, TimeUnit.SECONDS); 45 | 46 | return imageCaptcha; 47 | } 48 | 49 | @Override 50 | public boolean verify(String key,String userInputCode) { 51 | if(!StringUtils.hasLength(key)) throw new NewbieException("验证码key不能为空"); 52 | if(!StringUtils.hasLength(userInputCode)) throw new NewbieException("验证码不能为空"); 53 | Object o = redisTemplate.opsForValue().get(key); 54 | if(o == null){ 55 | throw new NewbieException("验证码已失效"); 56 | } 57 | String code = (String)o; 58 | boolean verify =this.codeGenerator.verify(code, userInputCode); 59 | if(verify){ 60 | redisTemplate.delete(key); 61 | return true; 62 | }else{ 63 | return false; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/util/SecurityUtils.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.util; 2 | 3 | 4 | import cn.dev33.satoken.stp.SaLoginModel; 5 | import cn.dev33.satoken.stp.SaTokenInfo; 6 | import cn.dev33.satoken.stp.StpUtil; 7 | import cn.hutool.crypto.digest.BCrypt; 8 | import cn.hutool.json.JSONObject; 9 | import cn.hutool.json.JSONUtil; 10 | import com.newbie.common.constant.SecurityConstant; 11 | import com.newbie.common.domain.LoginUser; 12 | 13 | 14 | /** 15 | * Created by IntelliJ IDEA. 16 | * 17 | * @Author: ZhangYuGe 18 | * @Email 398698424@qq.com 19 | * @Date: 2024/4/18 下午1:12 20 | * @Descriptions: 安全控制工具类 21 | */ 22 | public final class SecurityUtils { 23 | private SecurityUtils() {} 24 | 25 | /** 26 | * 密码加密 27 | * @param plaintext 密码明文 28 | * @return 密码密文 29 | */ 30 | public static String encodePassword(String plaintext) { 31 | return BCrypt.hashpw(plaintext); 32 | } 33 | 34 | /** 35 | * 密码校验 36 | * @param plaintext 密码明文 37 | * @param encoded 密码密文 38 | * @return 是否匹配 39 | */ 40 | public static boolean checkPassword(String plaintext, String encoded) { 41 | return BCrypt.checkpw(plaintext, encoded); 42 | } 43 | 44 | /** 45 | * 获取当前登录用户 46 | * @return 当前登录用户 47 | */ 48 | public static LoginUser getCurrentLoginUser(){ 49 | JSONObject jsonObject = (JSONObject) StpUtil.getExtra(SecurityConstant.SYS_USER_KEY); 50 | return JSONUtil.toBean(jsonObject, LoginUser.class); 51 | } 52 | 53 | /** 54 | * 判断当前登录用户是否为admin用户 55 | */ 56 | public static boolean isAdmin(){ 57 | return getCurrentLoginUser().isAdmin(); 58 | } 59 | 60 | /** 61 | * 登录 62 | * @param loginUser 登录用户对象 63 | * @param tokenTimeout token超时 64 | * @return SaTokenInfo 65 | */ 66 | public static SaTokenInfo login(LoginUser loginUser,Long tokenTimeout){ 67 | SaLoginModel loginModel = SaLoginModel 68 | .create() 69 | .setExtra(SecurityConstant.SYS_USER_KEY, loginUser) 70 | .build(); 71 | 72 | // token有效期 73 | if (tokenTimeout != null) { 74 | loginModel.setTimeout(tokenTimeout); 75 | } 76 | // 登录 77 | StpUtil.login(loginUser.getId(), loginModel); 78 | return StpUtil.getTokenInfo(); 79 | } 80 | 81 | /** 82 | * 登录 83 | * @param loginUser 登录用户对象 84 | * @return SaTokenInfo 85 | */ 86 | public static SaTokenInfo login(LoginUser loginUser){ 87 | return SecurityUtils.login(loginUser,null); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/controller/system/SysRoleMenuController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.controller.system; 2 | 3 | import cn.dev33.satoken.annotation.SaCheckPermission; 4 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; 5 | import com.newbie.common.domain.entity.SysRoleMenu; 6 | import com.newbie.common.util.R; 7 | import com.newbie.system.domain.body.SysRoleMenuBody; 8 | import com.newbie.system.service.SysRoleMenuService; 9 | import io.swagger.v3.oas.annotations.Operation; 10 | import io.swagger.v3.oas.annotations.tags.Tag; 11 | import lombok.RequiredArgsConstructor; 12 | import org.springframework.transaction.annotation.Transactional; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | @RestController 19 | @RequestMapping("/system/role_menu") 20 | @RequiredArgsConstructor 21 | @Tag(name = "角色菜单关系") 22 | public class SysRoleMenuController { 23 | private final SysRoleMenuService sysRoleMenuService; 24 | 25 | @Operation(summary ="根据角色id删除角色与权限关系并重新保存") 26 | @SaCheckPermission("sys.role.perm") 27 | @PostMapping("/removeAndSaveByRoleId") 28 | @Transactional 29 | public R removeAndSaveByRoleId(@RequestBody SysRoleMenuBody sysRoleMenuBody) { 30 | String roleId = sysRoleMenuBody.getRoleId(); 31 | List menuIds = sysRoleMenuBody.getMenuIds(); 32 | if (roleId == null || menuIds == null) return R.error("角色ID或菜单ID列表为空"); 33 | 34 | // 根据 roleId 删除已有的权限信息 35 | sysRoleMenuService.remove(Wrappers.lambdaQuery().eq(SysRoleMenu::getRoleId, sysRoleMenuBody.getRoleId())); 36 | 37 | // 保存角色权限信息 38 | List sysRoleMenuList = new ArrayList<>(); 39 | menuIds.forEach(menuId -> { 40 | SysRoleMenu sysRoleMenu = new SysRoleMenu(); 41 | sysRoleMenu.setMenuId(menuId); 42 | sysRoleMenu.setRoleId(roleId); 43 | sysRoleMenuList.add(sysRoleMenu); 44 | }); 45 | sysRoleMenuService.saveBatch(sysRoleMenuList); 46 | 47 | return R.ok().setMsg("保存成功"); 48 | } 49 | 50 | 51 | /** 52 | * 根据角色ID获取权限关系列表 53 | * 54 | * @param roleId 角色ID 55 | * @return 角色权限关系列表 56 | */ 57 | @Operation(summary ="根据角色ID获取权限关系列表") 58 | @SaCheckPermission("sys.role.perm") 59 | @GetMapping("/listByRoleId") 60 | public R> menuIdsByRoleId(String roleId) { 61 | List list = sysRoleMenuService 62 | .lambdaQuery() 63 | .eq(SysRoleMenu::getRoleId, roleId) 64 | .list(); 65 | return R.ok(list); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/impl/SysLogLoginServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service.impl; 2 | 3 | import cn.hutool.core.thread.ThreadUtil; 4 | import cn.hutool.http.Header; 5 | import cn.hutool.http.useragent.UserAgent; 6 | import cn.hutool.http.useragent.UserAgentUtil; 7 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 8 | import com.newbie.common.domain.entity.SysLogLogin; 9 | import com.newbie.common.util.IpUtils; 10 | import com.newbie.system.mapper.SysLogLoginMapper; 11 | import com.newbie.system.service.SysLogLoginService; 12 | import jakarta.servlet.http.HttpServletRequest; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.web.context.request.RequestContextHolder; 15 | import org.springframework.web.context.request.ServletRequestAttributes; 16 | 17 | import java.util.Objects; 18 | 19 | /** 20 | * @author 39869 21 | * @description 针对表【sys_log_login(系统登录日志)】的数据库操作Service实现 22 | * @createDate 2024-05-20 16:09:37 23 | */ 24 | @Service 25 | public class SysLogLoginServiceImpl extends ServiceImpl 26 | implements SysLogLoginService { 27 | 28 | @Override 29 | public void saveLoginLog(String username, long startTimeMillis,String type,String loginMethod) { 30 | this.saveLoginLog(username, startTimeMillis,type, loginMethod,null); 31 | } 32 | 33 | @Override 34 | public void saveLoginLog(String username, long startTimeMillis,String type,String loginMethod, Throwable e) { 35 | // 获取Request对象 36 | HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); 37 | // 创建登录日志对象 38 | SysLogLogin sysLogLogin = new SysLogLogin(); 39 | 40 | sysLogLogin.setUsername(username); 41 | sysLogLogin.setStatus(e == null ? "1" : "0"); 42 | sysLogLogin.setFailReason(e == null ? null : e.getMessage()); 43 | sysLogLogin.setLoginIp(IpUtils.getIpAddr(request)); 44 | sysLogLogin.setLoginMethod(loginMethod); 45 | UserAgent ua = UserAgentUtil.parse(request.getHeader(Header.USER_AGENT.toString())); 46 | String osInfo = ua.getOs().getName() + "(" + ua.getOsVersion() + ")"; 47 | String browserInfo = ua.getBrowser().getName() + "(" + ua.getVersion() + ")"; 48 | sysLogLogin.setOs(osInfo); 49 | sysLogLogin.setBrowser(browserInfo); 50 | sysLogLogin.setLoginType(type); 51 | sysLogLogin.setCostTime(System.currentTimeMillis() - startTimeMillis); 52 | // 保存 53 | ThreadUtil.execute(() -> { 54 | this.save(sysLogLogin); 55 | }); 56 | } 57 | } 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/templates/serviceImpl.java.ftl: -------------------------------------------------------------------------------- 1 | package ${package.serviceImpl}; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import ${package.entity}.${Entity}Entity; 5 | import ${package.mapper}.${Entity}Mapper; 6 | import ${package.service}.I${Entity}Service; 7 | 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 9 | import lombok.RequiredArgsConstructor; 10 | import org.springframework.stereotype.Service; 11 | import java.io.Serializable; 12 | import java.util.List; 13 | import java.util.UUID; 14 | 15 | /** 16 | * Created by NewbieGenerator. 17 | * 18 | * @Author: ${gc.author} 19 | * @Email ${gc.email} 20 | * @Date: ${gc.date} 21 | * @Descriptions: ${comment!} 服务实现类 22 | */ 23 | @Service 24 | @RequiredArgsConstructor 25 | public class ${Entity}ServiceImpl extends ServiceImpl<${Entity}Mapper, ${Entity}Entity> implements I${Entity}Service { 26 | private final ${Entity}Mapper ${entity}Mapper; 27 | 28 | @Override 29 | public IPage<${Entity}Entity> getPage(IPage<${Entity}Entity> page, ${Entity}Entity entity) { 30 | // Wrapper<${Entity}Entity> wrapper = new LambdaQueryWrapper<${Entity}Entity>() 31 | <#list fields as field> 32 | // .like(StringUtils.hasLength(${field.name}.${field.getMethodName}()), ${Entity}Entity::${field.getMethodName}, ${field.name}.${field.getMethodName}()) 33 | 34 | // ; 35 | // return genConfigMapper.selectPage(page,wrapper); 36 | 37 | return page.setRecords(${entity}Mapper.selectList(page,entity)); 38 | } 39 | 40 | @Override 41 | public List<${Entity}Entity> getList(${Entity}Entity entity) { 42 | // Wrapper<${Entity}Entity> wrapper = new LambdaQueryWrapper<${Entity}Entity>() 43 | <#list fields as field> 44 | // .like(StringUtils.hasLength(${field.name}.${field.getMethodName}()), ${Entity}Entity::${field.getMethodName}, ${field.name}.${field.getMethodName}()) 45 | 46 | // ; 47 | // return genConfigMapper.selectList(wrapper); 48 | 49 | return ${entity}Mapper.selectList(null,entity); 50 | } 51 | 52 | @Override 53 | public ${Entity}Entity getByPkVal(Serializable pkVal) { 54 | return ${entity}Mapper.selectByPkVal(pkVal); 55 | } 56 | 57 | @Override 58 | public void addData(${Entity}Entity entity) { 59 | ${entity}Mapper.insert(entity); 60 | } 61 | 62 | @Override 63 | public void updateByPkVal(${Entity}Entity entity) { 64 | ${entity}Mapper.updateById(entity); 65 | } 66 | 67 | @Override 68 | public void deleteByPkVal(Serializable pkVal) { 69 | ${entity}Mapper.deleteById(pkVal); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /newbie-generator/src/main/java/com/newbie/generator/service/impl/GenConfigServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.generator.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 6 | import com.baomidou.mybatisplus.core.metadata.IPage; 7 | import com.newbie.generator.domain.GenConfigEntity; 8 | import com.newbie.generator.mapper.GenConfigMapper; 9 | import com.newbie.generator.service.IGenConfigService; 10 | 11 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 12 | import lombok.RequiredArgsConstructor; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.util.StringUtils; 15 | 16 | import java.io.Serializable; 17 | import java.util.List; 18 | import java.util.UUID; 19 | 20 | /** 21 | * Created by NewbieGenerator. 22 | * 23 | * @Author: ZhangYuGe 24 | * @Email 398698424@qq.com 25 | * @Date: 2024-10-04 26 | * @Descriptions: 代码生成器配置 服务实现类 27 | */ 28 | @Service 29 | @RequiredArgsConstructor 30 | public class GenConfigServiceImpl extends ServiceImpl implements IGenConfigService { 31 | private final GenConfigMapper genConfigMapper; 32 | 33 | @Override 34 | public IPage getPage(IPage page, GenConfigEntity entity) { 35 | Wrapper wrapper = new LambdaQueryWrapper() 36 | .like(StringUtils.hasLength(entity.getConfigName()), GenConfigEntity::getConfigName, entity.getConfigName()) 37 | .like(StringUtils.hasLength(entity.getAuthor()),GenConfigEntity::getAuthor,entity.getAuthor()); 38 | return genConfigMapper.selectPage(page,wrapper); 39 | } 40 | 41 | @Override 42 | public List getList(GenConfigEntity entity) { 43 | Wrapper wrapper = new LambdaQueryWrapper() 44 | .like(StringUtils.hasLength(entity.getConfigName()), GenConfigEntity::getConfigName, entity.getConfigName()) 45 | .like(StringUtils.hasLength(entity.getAuthor()),GenConfigEntity::getAuthor,entity.getAuthor()); 46 | return genConfigMapper.selectList(wrapper); 47 | } 48 | 49 | @Override 50 | public GenConfigEntity getByPkVal(Serializable pkVal) { 51 | return genConfigMapper.selectById(pkVal); 52 | } 53 | 54 | @Override 55 | public void addData(GenConfigEntity entity) { 56 | genConfigMapper.insert(entity); 57 | } 58 | 59 | @Override 60 | public void updateByPkVal(GenConfigEntity entity) { 61 | genConfigMapper.updateById(entity); 62 | } 63 | 64 | @Override 65 | public void deleteByPkVal(Serializable pkVal) { 66 | genConfigMapper.deleteById(pkVal); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/templates/dataForm.vue.ftl: -------------------------------------------------------------------------------- 1 | 38 | 39 | 91 | 92 | -------------------------------------------------------------------------------- /newbie-system/src/main/java/com/newbie/system/service/impl/SysLogOperateServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.newbie.system.service.impl; 2 | 3 | 4 | import cn.hutool.core.thread.ThreadUtil; 5 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 6 | import com.newbie.common.domain.LoginUser; 7 | import com.newbie.common.domain.entity.SysLogOperate; 8 | import com.newbie.common.util.IpUtils; 9 | import com.newbie.common.util.SecurityUtils; 10 | import com.newbie.system.mapper.SysLogOperateMapper; 11 | import com.newbie.system.service.SysLogOperateService; 12 | import jakarta.servlet.http.HttpServletRequest; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.web.context.request.RequestContextHolder; 15 | import org.springframework.web.context.request.ServletRequestAttributes; 16 | 17 | import java.util.Objects; 18 | 19 | /** 20 | * @author 39869 21 | * @description 针对表【sys_log_operat(系统操作日志)】的数据库操作Service实现 22 | * @createDate 2024-05-18 18:03:34 23 | */ 24 | @Service 25 | public class SysLogOperateServiceImpl extends ServiceImpl 26 | implements SysLogOperateService { 27 | 28 | 29 | @Override 30 | public void saveSysLogOperate(String targetFun,long startTimeMillis,Throwable throwable) { 31 | // 获取Request对象 32 | HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); 33 | // 创建操作日志对象 34 | SysLogOperate sysLogOperate = new SysLogOperate(); 35 | // 获取当前用户 36 | try { 37 | LoginUser currentLoginUser = SecurityUtils.getCurrentLoginUser(); 38 | if (Objects.nonNull(currentLoginUser)) { 39 | // 操作者用户名 40 | sysLogOperate.setUsername(currentLoginUser.getUsername()); 41 | } 42 | }catch (Exception e){ 43 | sysLogOperate.setUsername("#"); 44 | } 45 | 46 | // 客户端地址 47 | sysLogOperate.setClientIp(IpUtils.getIpAddr(request)); 48 | // 接口路径 49 | sysLogOperate.setTargetUri(request.getRequestURI()); 50 | // 目标方法 51 | sysLogOperate.setTargetFun(targetFun); 52 | // 请求方式 53 | sysLogOperate.setMethod(request.getMethod()); 54 | 55 | 56 | if (Objects.nonNull(throwable)) { 57 | // 日志类型,1 正常,0 异常 58 | sysLogOperate.setStatus("0"); 59 | // 异常消息 60 | sysLogOperate.setFailReason(throwable.getMessage()); 61 | }else{ 62 | sysLogOperate.setStatus("1"); 63 | } 64 | // 消耗时长,毫秒 65 | sysLogOperate.setCostTime(System.currentTimeMillis() - startTimeMillis); 66 | // 保存日志 67 | ThreadUtil.execute(()-> this.save(sysLogOperate)); 68 | 69 | 70 | } 71 | 72 | @Override 73 | public void saveSysLogOperate(String targetFun, long startTimeMillis) { 74 | this.saveSysLogOperate(targetFun,startTimeMillis,null); 75 | } 76 | } 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/templates/controller.java.ftl: -------------------------------------------------------------------------------- 1 | package ${package.controller}; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import ${package.service}.I${Entity}Service; 6 | import ${package.entity}.${Entity}Entity; 7 | import com.newbie.common.util.R; 8 | import lombok.RequiredArgsConstructor; 9 | <#if gc.springDoc> 10 | import io.swagger.v3.oas.annotations.Operation; 11 | 12 | <#if gc.apiAuth> 13 | import cn.dev33.satoken.annotation.SaCheckPermission; 14 | 15 | import org.springframework.web.bind.annotation.*; 16 | import java.io.Serializable; 17 | import java.util.List; 18 | 19 | /** 20 | * Created by NewbieGenerator. 21 | * 22 | * @Author: ${gc.author} 23 | * @Email ${gc.email} 24 | * @Date: ${gc.date} 25 | * @Descriptions: ${comment!} Api 接口 26 | */ 27 | @RestController 28 | @RequestMapping("${apiPath.parent}") 29 | @RequiredArgsConstructor 30 | <#if gc.springDoc> 31 | @Tag(name = "${comment!}") 32 | 33 | public class ${Entity}Controller { 34 | 35 | private final I${Entity}Service i${Entity}Service; 36 | 37 | <#if gc.springDoc> 38 | @Operation(summary ="分页查询数据列表") 39 | 40 | <#if gc.apiAuth> 41 | @SaCheckPermission("${gc.moduleName}.${entity}.list") 42 | 43 | @GetMapping("/page") 44 | public R> page(Page<${Entity}Entity> page, ${Entity}Entity entity) { 45 | return R.ok(i${Entity}Service.getPage(page,entity)); 46 | } 47 | 48 | <#if gc.springDoc> 49 | @Operation(summary ="查询数据列表") 50 | 51 | <#if gc.apiAuth> 52 | @SaCheckPermission("${gc.moduleName}.${entity}.list") 53 | 54 | @GetMapping("/list") 55 | public R> list(${Entity}Entity entity) { 56 | return R.ok(i${Entity}Service.getList(entity)); 57 | } 58 | 59 | <#if gc.springDoc> 60 | @Operation(summary ="新增数据") 61 | 62 | <#if gc.apiAuth> 63 | @SaCheckPermission("${gc.moduleName}.${entity}.add") 64 | 65 | @PostMapping("/addData") 66 | public R addData(@RequestBody ${Entity}Entity entity) { 67 | i${Entity}Service.addData(entity); 68 | return R.ok(); 69 | } 70 | 71 | <#if gc.springDoc> 72 | @Operation(summary ="根据主键更新数据") 73 | 74 | <#if gc.apiAuth> 75 | @SaCheckPermission("${gc.moduleName}.${entity}.update") 76 | 77 | @PostMapping("/updateByPkVal") 78 | public R updateByPkVal(@RequestBody ${Entity}Entity entity) { 79 | i${Entity}Service.updateById(entity); 80 | return R.ok(); 81 | } 82 | <#if gc.springDoc> 83 | @Operation(summary ="根据主键删除数据") 84 | 85 | <#if gc.apiAuth> 86 | @SaCheckPermission("${gc.moduleName}.${entity}.delete") 87 | 88 | @PostMapping("/deleteByPkVal/{${pkey.name}}") 89 | public R deleteByPkVal(@PathVariable Serializable ${pkey.name}) { 90 | i${Entity}Service.deleteByPkVal(${pkey.name}); 91 | return R.ok(); 92 | } 93 | } -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/templates/mapper.xml.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 26 | 27 | 28 | 39 | 40 | 41 | 42 | 43 | <#list fields as field> 44 | <#if field.type="String"> 45 | ${field.colName}, 46 | <#else> 47 | ${field.colName}, 48 | 49 | 50 | 51 | 52 | <#list fields as field> 53 | <#if field.type="String"> 54 | ${r'#'}{${field.name}}, 55 | <#else> 56 | ${r'#'}{${field.name}}, 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | UPDATE ${tableName} 65 | 66 | <#list fields as field> 67 | <#if !field.pk> 68 | ${field.colName} = ${r'#'}{${field.name}}, 69 | 70 | 71 | 72 | WHERE ${pkey.colName}=${r'#'}{${pkey.name}} 73 | 74 | 75 | 76 | 77 | DELETE FROM ${tableName} WHERE ${pkey.colName}=${r'#'}{${pkey.name}} 78 | 79 | 80 | -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/controller/system/SysUserController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.controller.system; 2 | 3 | import cn.dev33.satoken.annotation.SaCheckPermission; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 6 | import com.newbie.common.domain.entity.SysUser; 7 | import com.newbie.common.util.R; 8 | import com.newbie.security.domain.body.PasswordBody; 9 | import com.newbie.system.service.SysUserService; 10 | import io.swagger.v3.oas.annotations.Operation; 11 | import io.swagger.v3.oas.annotations.tags.Tag; 12 | import lombok.RequiredArgsConstructor; 13 | import org.springframework.util.StringUtils; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import java.util.Arrays; 17 | 18 | 19 | @RestController 20 | @RequestMapping("/system/user") 21 | @RequiredArgsConstructor 22 | @Tag(name = "用户管理") 23 | public class SysUserController { 24 | private final SysUserService sysUserService; 25 | 26 | @Operation(summary ="查询分页数据") 27 | @SaCheckPermission("sys.user") 28 | @GetMapping("/paging") 29 | public R> paging(Page page, SysUser sysUser) { 30 | IPage iPage = sysUserService.queryPage(page, sysUser); 31 | return R.ok(iPage); 32 | } 33 | 34 | @Operation(summary ="新增") 35 | @SaCheckPermission("sys.user.add") 36 | @PostMapping("/add") 37 | public R add(@RequestBody SysUser sysUser) { 38 | String userId = sysUser.getId(); 39 | if (StringUtils.hasLength(userId)) return R.error("请检查此数据是否已存在,userId=" + userId); 40 | sysUserService.saveUser(sysUser); 41 | return R.ok().setMsg("添加成功"); 42 | } 43 | 44 | @Operation(summary ="修改") 45 | @SaCheckPermission("sys.user.update") 46 | @PostMapping("/update") 47 | public R update(@RequestBody SysUser sysUser) { 48 | if (sysUser.getId() == null) return R.error("用户ID为空"); 49 | sysUserService.updateUser(sysUser); 50 | return R.ok().setMsg("修改成功"); 51 | } 52 | 53 | @Operation(summary ="批量删除") 54 | @SaCheckPermission("sys.user.del") 55 | @PostMapping("/deleteBatch") 56 | public R deleteBatch(@RequestBody String[] ids) { 57 | if(ids==null || ids.length==0) return R.error("用户ID为空"); 58 | sysUserService.deleteBatch(Arrays.asList(ids)); 59 | return R.ok().setMsg("删除成功"); 60 | } 61 | 62 | @Operation(summary ="修改用户密码") 63 | @SaCheckPermission("sys.user.update.password") 64 | @PostMapping("/updateUserPassword") 65 | public R updateUserPassword(@RequestBody PasswordBody passwordBody){ 66 | boolean b = sysUserService.updateUserPassword(passwordBody.getUserId(),passwordBody.getNtext(),passwordBody.getCtext(),passwordBody.getImmediatelyKick()); 67 | return b?R.ok().setMsg("修改成功"):R.error("修改密码失败"); 68 | } 69 | 70 | /** 71 | * 当前用户修改自己的基本用户信息 72 | * @param sysUser 用户对象 73 | * @return 74 | */ 75 | @Operation(summary ="当前用户修改自己的基本用户信息") 76 | @PostMapping("/updateByCurr") 77 | public R updateByCurr(@RequestBody SysUser sysUser){ 78 | sysUserService.updateByCurr(sysUser); 79 | return R.ok(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/controller/monitor/SysLogOperateController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.controller.monitor; 2 | 3 | import cn.dev33.satoken.annotation.SaCheckPermission; 4 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 7 | import com.newbie.common.domain.entity.SysLogOperate; 8 | import com.newbie.common.util.R; 9 | import com.newbie.system.service.SysLogOperateService; 10 | import io.swagger.v3.oas.annotations.Operation; 11 | import io.swagger.v3.oas.annotations.tags.Tag; 12 | import lombok.RequiredArgsConstructor; 13 | import org.springframework.util.StringUtils; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import java.util.Arrays; 17 | import java.util.Date; 18 | 19 | /** 20 | * Created by IntelliJ IDEA. 21 | * 22 | * @Author: ZhangYuGe 23 | * @Email 398698424@qq.com 24 | * @Date: 2024/5/18 下午10:29 25 | * @Descriptions: 系统操作日志 26 | */ 27 | @RestController 28 | @RequestMapping("/monitor/log/operate") 29 | @RequiredArgsConstructor 30 | @Tag(name = "操作日志") 31 | public class SysLogOperateController { 32 | 33 | private final SysLogOperateService sysLogOperateService; 34 | 35 | @Operation(summary ="查询分页数据") 36 | @SaCheckPermission("sys.log.operate") 37 | @GetMapping("/paging") 38 | public R> paging(Page page, SysLogOperate sysLogOperate) { 39 | String clientIp = sysLogOperate.getClientIp(); 40 | String status = sysLogOperate.getStatus(); 41 | String method = sysLogOperate.getMethod(); 42 | String targetUri = sysLogOperate.getTargetUri(); 43 | Page pageData = sysLogOperateService.lambdaQuery() 44 | .like(StringUtils.hasLength(clientIp),SysLogOperate::getClientIp,clientIp) 45 | .eq(StringUtils.hasLength(status),SysLogOperate::getStatus,status) 46 | .eq(StringUtils.hasLength(method),SysLogOperate::getMethod,method) 47 | .like(StringUtils.hasLength(targetUri),SysLogOperate::getTargetUri,targetUri) 48 | .orderByDesc(SysLogOperate::getCreateTime) 49 | .page(page); 50 | return R.ok(pageData); 51 | } 52 | 53 | @Operation(summary ="批量删除") 54 | @SaCheckPermission("sys.log.operate.del") 55 | @PostMapping("/deleteBatch") 56 | public R deleteBatch(@RequestBody String[] ids) { 57 | if (ids == null || ids.length == 0) return R.error("日志ID为空"); 58 | sysLogOperateService.removeBatchByIds(Arrays.asList(ids)); 59 | return R.ok().setMsg("删除成功"); 60 | } 61 | 62 | @Operation(summary ="删除i天前数据") 63 | @SaCheckPermission("sys.log.operate.del") 64 | @GetMapping("/deleteBeforeData") 65 | public R deleteBeforeData(Integer i) { 66 | 67 | long l = System.currentTimeMillis(); 68 | long j = 1000L * 60 * 60 * 24 * i; 69 | 70 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper() 71 | .lt(SysLogOperate::getCreateTime, new Date(l-j)); 72 | sysLogOperateService.remove(wrapper); 73 | return R.ok().setMsg("清除成功"); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/controller/system/SysRoleController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.controller.system; 2 | 3 | import cn.dev33.satoken.annotation.SaCheckPermission; 4 | import com.baomidou.mybatisplus.core.metadata.IPage; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 6 | import com.newbie.common.domain.entity.SysRole; 7 | import com.newbie.common.util.R; 8 | import com.newbie.system.service.SysRoleService; 9 | import io.swagger.v3.oas.annotations.Operation; 10 | import io.swagger.v3.oas.annotations.tags.Tag; 11 | import lombok.RequiredArgsConstructor; 12 | import org.springframework.util.StringUtils; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import java.util.Arrays; 16 | 17 | @RestController 18 | @RequestMapping("/system/role") 19 | @RequiredArgsConstructor 20 | @Tag(name = "角色管理") 21 | public class SysRoleController { 22 | private final SysRoleService sysRoleService; 23 | 24 | @Operation(summary ="查询分页数据") 25 | @SaCheckPermission("sys.role") 26 | @GetMapping("/paging") 27 | public R> paging(Page page, SysRole sysRole) { 28 | String roleName = sysRole.getRoleName(); 29 | String roleCode = sysRole.getRoleCode(); 30 | String status = sysRole.getStatus(); 31 | 32 | Page pageInfo = sysRoleService 33 | .lambdaQuery() 34 | .like(StringUtils.hasLength(roleName), SysRole::getRoleName, roleName) 35 | .like(StringUtils.hasLength(roleCode), SysRole::getRoleCode, roleCode) 36 | .eq(StringUtils.hasLength(status), SysRole::getStatus, status) 37 | .orderBy(true, true, SysRole::getSort) 38 | .page(page); 39 | return R.ok(pageInfo); 40 | } 41 | 42 | @Operation(summary ="新增") 43 | @SaCheckPermission("sys.role.add") 44 | @PostMapping("/add") 45 | public R add(@RequestBody SysRole sysRole) { 46 | String roleId = sysRole.getId(); 47 | if (StringUtils.hasLength(roleId)) return R.error("添加失败,请检查此数据是否已存在,roleId=" + roleId); 48 | // 查询角色编码唯一 49 | if (sysRoleService.lambdaQuery().eq(SysRole::getRoleCode, sysRole.getRoleCode()).count() > 0) 50 | return R.error("角色编码已存在"); 51 | 52 | // 保存角色信息 53 | sysRoleService.save(sysRole); 54 | return R.ok().setMsg("添加成功"); 55 | } 56 | 57 | @Operation(summary ="修改") 58 | @SaCheckPermission("sys.role.update") 59 | @PostMapping("/update") 60 | public R update(@RequestBody SysRole sysRole) { 61 | if (sysRole.getId() == null) { 62 | return R.error("角色ID为空"); 63 | } 64 | // 判断角色编码是否重复 65 | if (sysRoleService.lambdaQuery() 66 | .eq(SysRole::getRoleCode, sysRole.getRoleCode()) 67 | .ne(SysRole::getId, sysRole.getId()).count() > 0) 68 | return R.error("角色编码已存在"); 69 | 70 | 71 | // 修改角色信息 72 | sysRoleService.updateById(sysRole); 73 | return R.ok().setMsg("修改成功"); 74 | } 75 | 76 | @Operation(summary ="批量删除") 77 | @SaCheckPermission("sys.role.del") 78 | @PostMapping("/deleteBatch") 79 | public R deleteBatch(@RequestBody String[] ids) { 80 | if (ids == null || ids.length == 0) return R.error("角色ID为空"); 81 | sysRoleService.deleteBatch(Arrays.asList(ids)); 82 | return R.ok().setMsg("删除成功"); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /newbie-security/src/main/resources/mapper/SecurityMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | m.id,m.title,m.parent_id, 8 | m.sort,m.status,m.route_path, 9 | m.route_name,m.component,m.remark, 10 | m.create_by,m.create_time,m.update_by, 11 | m.update_time,m.is_keep,m.type, 12 | m.is_hide,m.perm,m.icon, 13 | m.hide_children,m.iframe_link,m.is_outer, 14 | m.transition,m.fixed_tab,m.ancestors,m.tier,m.route_redirect 15 | 16 | 17 | r.id,r.role_name,r.role_code, 18 | r.sort,r.status,r.home_path, 19 | r.remark,r.create_by,r.create_time, 20 | r.update_by,r.update_time 21 | 22 | 23 | u.id,u.dept_id,u.username, 24 | u.password,u.nick_name,u.avatar, 25 | u.home_path,u.phone,u.email, 26 | u.gender,u.status,u.remark, 27 | u.sort,u.create_by,u.create_time, 28 | u.update_by,u.update_time 29 | 30 | 31 | insert into sys_user 32 | (username, password, nick_name, status, create_time) 33 | values (#{username}, #{password}, #{nickName}, '1', #{createTime}) 34 | 35 | 36 | update sys_user 37 | set password = #{password} 38 | where id = #{id} 39 | 40 | 46 | 55 | 63 | 77 | 83 | 87 | 88 | -------------------------------------------------------------------------------- /bin/jar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 该脚本为Linux下启动java程序的脚本 4 | # 5 | # author: luandy 6 | # date: 2021/1/15 7 | # Newbieboot感谢作者 8 | # 9 | # 特别注意: 10 | # 该脚本使用系统kill命令来强制终止指定的java程序进程。 11 | # 所以在杀死进程前,可能会造成数据丢失或数据不完整。如果必须要考虑到这类情况,则需要改写此脚本, 12 | # 13 | # 14 | # 根据实际情况来修改以下配置信息 ################################## 15 | 16 | # JAVA应用程序的名称 17 | APP_NAME=newbie-boot 18 | # JAVA应用程序端口号 19 | SERVER_PORT=8080 20 | # jar包存放路径 21 | JAR_PATH='/var/www/jar' 22 | # jar包名称 23 | JAR_NAME=newbie-admin-0.0.1-SNAPSHOT.jar 24 | # PID 代表是PID文件 25 | JAR_PID=$JAR_NAME\.pid 26 | # 日志输出文件 27 | LOG_FILE=logs 28 | 29 | # java虚拟机启动参数 30 | JAVA_OPTS="-Xms512m -Xmx512m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024m -Dfile.encoding=utf-8" 31 | 32 | # 根据实际情况来修改以上配置信息 ################################## 33 | 34 | 35 | # 检查程序是否处于运行状态 36 | is_exist() { 37 | # 查询出应用服务的进程id,grep -v 是反向查询的意思,查找除了grep操作的run.jar的进程之外的所有进程 38 | pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' ` 39 | 40 | # [ ]表示条件测试。注意这里的空格很重要。要注意在'['后面和']'前面都必须要有空格 41 | # [ -z STRING ] 如果STRING的长度为零则返回为真,即空是真 42 | # 如果不存在返回0,存在返回1 43 | if [ -z "${pid}" ]; then 44 | return 0 45 | else 46 | return 1 47 | fi 48 | } 49 | 50 | # ######### Shell脚本中$0、$?、$!、$$、$*、$#、$@等的说明 ######### 51 | 52 | # $$ Shell本身的PID(ProcessID,即脚本运行的当前 进程ID号) 53 | # $! Shell最后运行的后台Process的PID(后台运行的最后一个进程的 进程ID号) 54 | # $? 最后运行的命令的结束代码(返回值)即执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误) 55 | # $- 显示shell使用的当前选项,与set命令功能相同 56 | # $* 所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数,此选项参数可超过9个。 57 | # $@ 所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 58 | # $# 添加到Shell的参数个数 59 | # $0 Shell本身的文件名 60 | # $1~$n 添加到Shell的各参数值。$1是第1参数、$2是第2参数…。 61 | 62 | # 服务启动方法 63 | start() { 64 | is_exist 65 | if [ $? -eq "1" ]; then 66 | echo "$APP_NAME is already running pid is ${pid}" 67 | else 68 | # jar服务启动脚本 69 | nohup java $JAVA_OPTS -Xloggc:$LOG_FILE/gc/gclog.log -XX:HeapDumpPath=$LOG_FILE/gc/HeapDump.hprof -jar $JAR_PATH/$JAR_NAME -Dserver.port=$SERVER_PORT >./$LOG_FILE/run.log 2>&1 & 70 | echo $! > $JAR_PID 71 | echo "start $APP_NAME successed pid is $! " 72 | tail -1000f $LOG_FILE/run.log 73 | fi 74 | } 75 | 76 | # 服务停止方法 77 | stop() { 78 | # is_exist 79 | pidf=$(cat $JAR_PID) 80 | # echo "$pidf" 81 | echo "pid = $pidf begin kill $pidf" 82 | kill $pidf 83 | rm -rf $JAR_PID 84 | sleep 2 85 | # 判断服务进程是否存在 86 | is_exist 87 | if [ $? -eq "1" ]; then 88 | echo "pid = $pid begin kill -9 $pid" 89 | kill -9 $pid 90 | sleep 2 91 | echo "$APP_NAME process stopped!" 92 | else 93 | echo "$APP_NAME is not running!" 94 | fi 95 | } 96 | 97 | # 服务运行状态查看方法 98 | status() { 99 | is_exist 100 | if [ $? -eq "1" ]; then 101 | echo "$APP_NAME is running,pid is ${pid}" 102 | else 103 | echo "$APP_NAME is not running!" 104 | fi 105 | } 106 | 107 | # 重启服务方法 108 | restart() { 109 | # 调用服务停止命令 110 | stop 111 | # 调用服务启动命令 112 | start 113 | } 114 | 115 | # 帮助说明,用于提示输入参数信息 116 | usage() { 117 | echo "Usage: sh run-service.sh [ start | stop | restart | status ]" 118 | exit 1 119 | } 120 | 121 | ################################### 122 | # 读取脚本的第一个参数($1),进行判断 123 | # 参数取值范围:{ start | stop | restart | status } 124 | # 如参数不在指定范围之内,则打印帮助信息 125 | ################################### 126 | #根据输入参数,选择执行对应方法,不输入则执行使用说明 127 | case "$1" in 128 | 'start') 129 | start 130 | ;; 131 | 'stop') 132 | stop 133 | ;; 134 | 'restart') 135 | restart 136 | ;; 137 | 'status') 138 | status 139 | ;; 140 | *) 141 | usage 142 | ;; 143 | esac 144 | exit 0 -------------------------------------------------------------------------------- /newbie-admin/src/main/java/com/newbie/controller/monitor/SysLogLoginController.java: -------------------------------------------------------------------------------- 1 | package com.newbie.controller.monitor; 2 | 3 | import cn.dev33.satoken.annotation.SaCheckPermission; 4 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 7 | import com.newbie.common.domain.entity.SysLogLogin; 8 | import com.newbie.common.util.R; 9 | import com.newbie.common.util.SecurityUtils; 10 | import com.newbie.system.service.SysLogLoginService; 11 | import io.swagger.v3.oas.annotations.Operation; 12 | import io.swagger.v3.oas.annotations.tags.Tag; 13 | import lombok.RequiredArgsConstructor; 14 | import org.springframework.util.StringUtils; 15 | import org.springframework.web.bind.annotation.*; 16 | 17 | import java.util.Arrays; 18 | import java.util.Date; 19 | 20 | /** 21 | * Created by IntelliJ IDEA. 22 | * 23 | * @Author: ZhangYuGe 24 | * @Email 398698424@qq.com 25 | * @Date: 2024/5/24 上午10:36 26 | * @Descriptions: 登录日志控制器 27 | */ 28 | @RestController 29 | @RequiredArgsConstructor 30 | @RequestMapping("/monitor/log/login") 31 | @Tag(name = "登录日志") 32 | public class SysLogLoginController { 33 | private final SysLogLoginService sysLogLoginService; 34 | 35 | @Operation(summary ="查询分页数据") 36 | @SaCheckPermission("sys.log.login") 37 | @GetMapping("/paging") 38 | public R> paging(Page page, SysLogLogin sysLogLogin) { 39 | String username = sysLogLogin.getUsername(); 40 | String status = sysLogLogin.getStatus(); 41 | Page pageData = sysLogLoginService.lambdaQuery() 42 | .like(StringUtils.hasLength(username),SysLogLogin::getUsername,username) 43 | .eq(StringUtils.hasLength(status),SysLogLogin::getStatus,status) 44 | .orderByDesc(SysLogLogin::getCreateTime) 45 | .page(page); 46 | return R.ok(pageData); 47 | } 48 | 49 | @Operation(summary ="查询当前用户的登录日志分页数据") 50 | @GetMapping("/pagingByCurrUser") 51 | public R> pagingByCurrUser(Page page, SysLogLogin sysLogLogin) { 52 | String username = SecurityUtils.getCurrentLoginUser().getUsername(); 53 | String status = sysLogLogin.getStatus(); 54 | Page pageData = sysLogLoginService.lambdaQuery() 55 | .eq(StringUtils.hasLength(username),SysLogLogin::getUsername,username) 56 | .eq(StringUtils.hasLength(status),SysLogLogin::getStatus,status) 57 | .orderByDesc(SysLogLogin::getCreateTime) 58 | .page(page); 59 | return R.ok(pageData); 60 | } 61 | 62 | 63 | @Operation(summary ="批量删除") 64 | @SaCheckPermission("sys.log.login.del") 65 | @PostMapping("/deleteBatch") 66 | public R deleteBatch(@RequestBody String[] ids) { 67 | if (ids == null || ids.length == 0) return R.error("日志ID为空"); 68 | sysLogLoginService.removeBatchByIds(Arrays.asList(ids)); 69 | return R.ok().setMsg("删除成功"); 70 | } 71 | 72 | @Operation(summary ="删除i天前数据") 73 | @SaCheckPermission("sys.log.login.del") 74 | @GetMapping("/deleteBeforeData") 75 | public R deleteBeforeData(Integer i) { 76 | 77 | long l = System.currentTimeMillis(); 78 | long j = 1000L * 60 * 60 * 24 * i; 79 | 80 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper() 81 | .lt(SysLogLogin::getCreateTime, new Date(l-j)); 82 | sysLogLoginService.remove(wrapper); 83 | return R.ok().setMsg("清除成功"); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /newbie-common/src/main/java/com/newbie/common/handle/GlobalExceptionHandle.java: -------------------------------------------------------------------------------- 1 | package com.newbie.common.handle; 2 | 3 | import cn.dev33.satoken.exception.NotLoginException; 4 | import cn.dev33.satoken.exception.NotPermissionException; 5 | import cn.dev33.satoken.exception.NotRoleException; 6 | import cn.dev33.satoken.exception.NotSafeException; 7 | import com.newbie.common.exception.NewbieException; 8 | import com.newbie.common.util.R; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.web.bind.annotation.ExceptionHandler; 11 | import org.springframework.web.bind.annotation.RestControllerAdvice; 12 | 13 | import java.util.Optional; 14 | 15 | /** 16 | * Created by IntelliJ IDEA. 17 | * 18 | * @Author: ZhangYuGe 19 | * @Email 398698424@qq.com 20 | * @Date: 2024/4/16 11:22 21 | * @Descriptions: 全局异常处理 22 | */ 23 | @RestControllerAdvice 24 | @Slf4j 25 | public class GlobalExceptionHandle { 26 | 27 | @ExceptionHandler(NotLoginException.class) 28 | public R handlerNotLoginException(NotLoginException nle) { 29 | // 判断场景值,定制化异常信息 30 | String message = ""; 31 | if(nle.getType().equals(NotLoginException.NOT_TOKEN)) { 32 | message = "未能读取到有效 token"; 33 | } 34 | else if(nle.getType().equals(NotLoginException.INVALID_TOKEN)) { 35 | message = "token 无效"; 36 | } 37 | else if(nle.getType().equals(NotLoginException.TOKEN_TIMEOUT)) { 38 | message = "token 已过期"; 39 | } 40 | else if(nle.getType().equals(NotLoginException.BE_REPLACED)) { 41 | message = "token 已被顶下线"; 42 | } 43 | else if(nle.getType().equals(NotLoginException.KICK_OUT)) { 44 | message = "token 已被踢下线"; 45 | } 46 | else if(nle.getType().equals(NotLoginException.TOKEN_FREEZE)) { 47 | message = "token 已被冻结"; 48 | } 49 | else if(nle.getType().equals(NotLoginException.NO_PREFIX)) { 50 | message = "未按照指定前缀提交 token"; 51 | } 52 | else { 53 | message = "当前会话未登录"; 54 | } 55 | 56 | // 返回给前端 57 | return R.error(401, message); 58 | } 59 | 60 | @ExceptionHandler 61 | public R handlerNotRoleException(NotRoleException e) { 62 | return R.error(403, "无此角色:" + e.getRole()); 63 | } 64 | 65 | @ExceptionHandler 66 | public R handlerNotPermissionException(NotPermissionException e) { 67 | return R.error(403, "无此权限:" + e.getPermission()); 68 | } 69 | 70 | @ExceptionHandler 71 | public R handlerNotSafeException(NotSafeException e) { 72 | return R.error(401, "二级认证异常:" + e.getMessage()); 73 | } 74 | 75 | /** 76 | * 业务异常 77 | * 78 | * @param e 异常对象 79 | * @return 返回结果 80 | */ 81 | @ExceptionHandler(NewbieException.class) 82 | public R NewbieExceptionHandler(NewbieException e) { 83 | int code = Optional.ofNullable(e.getCode()).orElse(R.ERROR_CODE); 84 | String message = Optional.ofNullable(e.getMessage()).orElse(R.ERROR_MSG); 85 | if (e.getIsPrintLog()) { 86 | log.error(message, e); 87 | } 88 | return R.error(code,message); 89 | } 90 | 91 | /** 92 | * 运行时异常 93 | * 94 | * @param e 异常对象 95 | * @return 返回结果 96 | */ 97 | @ExceptionHandler(RuntimeException.class) 98 | public R RuntimeExceptionHandler(RuntimeException e) { 99 | String message = Optional.ofNullable(e.getMessage()).orElse(R.ERROR_MSG); 100 | log.error(message, e); 101 | return R.error(message); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /newbie-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.newbie 8 | newbie-boot3 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | newbie-common 13 | 14 | 15 | 21 16 | 21 17 | UTF-8 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | 32 | org.projectlombok 33 | lombok 34 | 35 | 36 | 37 | cn.hutool 38 | hutool-all 39 | 40 | 41 | 42 | 43 | com.baomidou 44 | mybatis-plus-spring-boot3-starter 45 | 46 | 47 | 48 | com.mysql 49 | mysql-connector-j 50 | 51 | 52 | 53 | org.postgresql 54 | postgresql 55 | 56 | 57 | 58 | com.oracle.database.jdbc 59 | ojdbc6 60 | 11.2.0.4 61 | 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-starter-data-redis 66 | 67 | 68 | 69 | org.apache.commons 70 | commons-pool2 71 | 72 | 73 | 74 | cn.dev33 75 | sa-token-spring-boot3-starter 76 | 77 | 78 | cn.hutool 79 | hutool-all 80 | 81 | 82 | 83 | 84 | 85 | 86 | com.github.xiaoymin 87 | knife4j-openapi3-jakarta-spring-boot-starter 88 | 89 | 90 | 91 | 92 | com.github.oshi 93 | oshi-core 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /newbie-generator/src/main/resources/mapper/Postgresql16GeneratorMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 16 | 17 | 31 | 32 | 33 | SELECT 34 | c.table_name, 35 | c.constraint_name, 36 | a.column_name, 37 | c.constraint_type 38 | FROM 39 | information_schema.table_constraints AS c 40 | JOIN 41 | information_schema.key_column_usage AS k 42 | ON c.constraint_name = k.constraint_name 43 | JOIN 44 | information_schema.tables AS t 45 | ON t.table_schema = c.table_schema 46 | AND t.table_name = c.table_name 47 | JOIN 48 | information_schema.columns AS a 49 | ON a.table_schema = k.table_schema 50 | AND a.table_name = k.table_name 51 | AND a.column_name = k.column_name 52 | WHERE 53 | c.constraint_type = 'PRIMARY KEY' 54 | AND 55 | c.table_schema = 'public' 56 | AND 57 | c.table_name = #{tableName} 58 | 59 | 60 | 61 | SELECT col.attname AS column_name, 62 | pgd.description AS comment 63 | FROM pg_attribute col 64 | LEFT JOIN 65 | pg_description pgd ON (col.attrelid = pgd.objoid AND col.attnum = pgd.objsubid) 66 | WHERE col.attrelid = 'public.${tableName}'::regclass -- 替换为你的表名 67 | AND 68 | col.attnum > 0 69 | AND 70 | NOT col.attisdropped 71 | ORDER BY 72 | col.attnum 73 | 74 | 75 | 76 | 96 | 97 | 98 | --------------------------------------------------------------------------------