# my-base-admin **Repository Path**: catberus/my-base-admin ## Basic Information - **Project Name**: my-base-admin - **Description**: 基于ruoyi-vue-admin的精简版脚手架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-06 - **Last Updated**: 2026-05-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Base-Admin 精简版后台管理脚手架 基于 RuoYi-Vue-Plus 精简的后台管理脚手架,移除了多租户、OSS、SMS、社交登录等复杂功能,保留核心架构。 ## 技术栈 | 技术 | 版本 | 说明 | |------|------|------| | Spring Boot | 3.5.9 | 基础框架 | | Sa-Token | 1.44.0 | 权限认证 | | MyBatis Plus | 3.5.16 | ORM框架 | | Redisson | 3.52.0 | Redis客户端 | | Hutool | 5.8.43 | 工具类库 | | Mapstruct Plus | 1.5.0 | 对象转换 | | Lock4j | 2.2.7 | 分布式锁 | ## 项目结构 ``` my-base-admin/ ├── pom.xml # 根 pom(版本管理) ├── base-admin/ # 启动模块 │ ├── pom.xml │ └── src/main/ │ ├── java/org/dromara/ │ │ ├── BaseAdminApplication.java │ │ └── controller/ │ └── resources/ │ ├── application.yml │ ├── application-dev.yml │ └── logback-plus.xml ├── base-common/ # 通用模块聚合 │ ├── pom.xml │ ├── base-common-bom/ # 版本管理(仅 common 模块) │ ├── base-common-core/ # 核心工具 │ ├── base-common-json/ # JSON 序列化 │ ├── base-common-redis/ # Redis 缓存 │ ├── base-common-mybatis/ # 数据库 │ ├── base-common-satoken/ # 认证 │ ├── base-common-security/ # 安全 │ ├── base-common-web/ # Web │ └── base-common-log/ # 日志 ├── base-modules/ # 业务模块聚合 │ ├── pom.xml │ └── base-demo/ # 示例模块 │ ├── pom.xml │ └── src/main/java/org/dromara/demo/ │ ├── controller/ │ ├── domain/ │ │ ├── Entity.java │ │ ├── bo/ # 业务对象 │ │ └── vo/ # 视图对象 │ ├── mapper/ │ ├── service/ │ │ ├── IService.java │ │ └── impl/ │ └── resources/mapper/ └── script/sql/ # 数据库脚本 ``` --- ## 一、基础设置 ### 1.1 环境要求 - JDK 17+ - Maven 3.6+ - MySQL 8.0+ - Redis 6.0+ ### 1.2 核心配置文件 **application.yml 主要配置:** ```yaml server: port: 8090 # Sa-Token 认证配置 sa-token: token-name: Authorization jwt-secret-key: your-secret-key # MyBatis Plus 配置 mybatis-plus: mapperPackage: org.dromara.**.mapper mapperLocations: classpath*:mapper/**/*Mapper.xml global-config: dbConfig: idType: ASSIGN_ID # 雪花ID # 安全排除路径 security: excludes: - /*.html - /**/*.css - /**/*.js - /error ``` **application-dev.yml 数据源配置:** ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/base_admin username: root password: password data: redis: host: localhost port: 6379 ``` ### 1.3 启动命令 ```bash # 开发环境 mvn spring-boot:run -pl base-admin # 生产环境 mvn clean package -Pprod java -jar base-admin/target/base-admin.jar ``` --- ## 二、Common 模块功能 ### 2.1 base-common-core **核心工具类:** | 类名 | 功能 | |------|------| | `R` | 统一响应封装 | | `ServiceException` | 业务异常 | | `MapstructUtils` | 对象转换工具 | | `StringUtils` | 字符串工具 | | `ServletUtils` | 请求响应工具 | | `SpringUtils` | Spring上下文工具 | | `DateUtils` | 日期工具 | **统一响应格式:** ```java // 成功 R.ok(data) R.ok() // 失败 R.fail("错误消息") R.fail(HttpStatus.FAIL, "错误消息") // Controller 返回 return R.ok(testDemoService.queryById(id)); ``` **验证分组:** ```java // AddGroup - 新增时校验 // EditGroup - 编辑时校验 // QueryGroup - 查询时校验 @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody TestDemoBo bo) { return toAjax(testDemoService.insertByBo(bo)); } ``` ### 2.2 base-common-mybatis **BaseMapperPlus 接口:** ```java // Mapper 继承 BaseMapperPlus,自动获得 Vo 转换能力 public interface TestDemoMapper extends BaseMapperPlus { } // 使用示例 TestDemoVo vo = baseMapper.selectVoById(id); // 单个 List list = baseMapper.selectVoList(lqw); // 列表 Page page = baseMapper.selectVoPage(pageQuery.build(), lqw); // 分页 ``` **BaseEntity 基类:** ```java public class BaseEntity { private Long createBy; // 创建人 private Date createTime; // 创建时间 private Long updateBy; // 更新人 private Date updateTime; // 更新时间 private Map params; // 扩展参数(用于时间范围查询) } ``` **分页查询:** ```java @GetMapping("/list") public R> list(TestDemoBo bo, PageQuery pageQuery) { return R.ok(testDemoService.queryPageList(bo, pageQuery)); } // Service 实现 public TableDataInfo queryPageList(TestDemoBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); } ``` ### 2.3 base-common-redis **Redis 缓存常量:** ```java // CacheNames - 缓存名称定义 public interface CacheNames { String SYS_CONFIG = "sys_config"; String SYS_DICT = "sys_dict"; } // CacheConstants - 缓存键常量 public interface CacheConstants { String LOGIN_TOKEN_KEY = "login_tokens:"; } ``` ### 2.4 base-common-satoken **登录辅助类 LoginHelper:** ```java // 获取当前登录用户 LoginUser loginUser = LoginHelper.getLoginUser(); Long userId = LoginHelper.getUserId(); String username = LoginHelper.getUsername(); // 登录/登出 LoginHelper.loginByDevice(loginBody, DeviceType.PC); SaHolder.getStorage().delete(LoginHelper.TOKEN_KEY); ``` ### 2.5 base-common-web **全局异常处理 GlobalExceptionHandler:** - 处理 ServiceException、参数校验异常、权限异常等 **BaseController:** ```java // 返回操作结果 protected R toAjax(int rows) { return rows > 0 ? R.ok() : R.fail(); } ``` ### 2.6 base-common-log **操作日志注解 @Log:** ```java @Log(title = "测试单表", businessType = BusinessType.INSERT) @PostMapping() public R add(@RequestBody TestDemoBo bo) { return toAjax(testDemoService.insertByBo(bo)); } // BusinessType 枚举 INSERT, UPDATE, DELETE, GRANT, EXPORT, IMPORT, FORCE, CLEAN ``` --- ## 三、如何扩展 Modules ### 3.1 模块目录结构规范 每个业务模块遵循统一结构: ``` base-{module}/ ├── pom.xml └── src/main/ ├── java/org/dromara/{module}/ │ ├── controller/ # 控制器 │ │ └── XxxController.java │ ├── domain/ # 实体类 │ │ ├── Xxx.java # 数据库实体 │ │ ├── bo/ # 业务对象(接收参数) │ │ │ └── XxxBo.java │ │ └── vo/ # 视图对象(返回数据) │ │ │ └── XxxVo.java │ ├── mapper/ # Mapper接口 │ │ └── XxxMapper.java │ └── service/ # 服务层 │ │ ├── IXxxService.java │ │ └── impl/ │ │ │ └── XxxServiceImpl.java └── resources/mapper/{module}/ └── XxxMapper.xml ``` ### 3.2 创建新模块步骤 **Step 1: 在 base-modules 下创建模块目录** ```bash base-modules/base-{module}/ ``` **Step 2: 创建 pom.xml** ```xml org.dromara base-modules ${revision} 4.0.0 base-{module} {module}模块 org.dromara base-common-core org.dromara base-common-mybatis org.dromara base-common-log org.dromara base-common-web org.dromara base-common-security ``` **Step 3: 在 base-modules/pom.xml 添加模块** ```xml base-demo base-{module} ``` **Step 4: 在根 pom.xml 添加版本管理** ```xml org.dromara base-{module} ${revision} ``` **Step 5: 在 base-admin/pom.xml 添加依赖** ```xml org.dromara base-{module} ``` ### 3.3 代码模板 **Entity 实体类:** ```java package org.dromara.{module}.domain; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; import org.dromara.common.mybatis.core.domain.BaseEntity; @Data @EqualsAndHashCode(callSuper = true) @TableName("表名") public class Xxx extends BaseEntity { @TableId(value = "id") private Long id; // 其他字段... @Version private Long version; @TableLogic private Long delFlag; } ``` **Bo 业务对象:** ```java package org.dromara.{module}.domain.bo; import io.github.linpeilie.annotations.AutoMapper; import jakarta.validation.constraints.*; import lombok.Data; import lombok.EqualsAndHashCode; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.{module}.domain.Xxx; @Data @EqualsAndHashCode(callSuper = true) @AutoMapper(target = Xxx.class, reverseConvertGenerate = false) public class XxxBo extends BaseEntity { @NotNull(message = "主键不能为空", groups = {EditGroup.class}) private Long id; @NotBlank(message = "名称不能为空", groups = {AddGroup.class, EditGroup.class}) private String name; // 其他字段... } ``` **Vo 视图对象:** ```java package org.dromara.{module}.domain.vo; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import org.dromara.{module}.domain.Xxx; import java.io.Serial; import java.io.Serializable; @Data @AutoMapper(target = Xxx.class) public class XxxVo implements Serializable { @Serial private static final long serialVersionUID = 1L; private Long id; private String name; // 其他字段... } ``` **Mapper 接口:** ```java package org.dromara.{module}.mapper; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.{module}.domain.Xxx; import org.dromara.{module}.domain.vo.XxxVo; public interface XxxMapper extends BaseMapperPlus { } ``` **Service 接口:** ```java package org.dromara.{module}.service; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.{module}.domain.bo.XxxBo; import org.dromara.{module}.domain.vo.XxxVo; import java.util.Collection; import java.util.List; public interface IXxxService { XxxVo queryById(Long id); TableDataInfo queryPageList(XxxBo bo, PageQuery pageQuery); List queryList(XxxBo bo); Boolean insertByBo(XxxBo bo); Boolean updateByBo(XxxBo bo); Boolean deleteWithValidByIds(Collection ids, Boolean isValid); } ``` **Service 实现:** ```java package org.dromara.{module}.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.{module}.domain.Xxx; import org.dromara.{module}.domain.bo.XxxBo; import org.dromara.{module}.domain.vo.XxxVo; import org.dromara.{module}.mapper.XxxMapper; import org.dromara.{module}.service.IXxxService; import org.springframework.stereotype.Service; import java.util.Collection; import java.util.List; import java.util.Map; @RequiredArgsConstructor @Service public class XxxServiceImpl implements IXxxService { private final XxxMapper baseMapper; @Override public XxxVo queryById(Long id) { return baseMapper.selectVoById(id); } @Override public TableDataInfo queryPageList(XxxBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); } @Override public List queryList(XxxBo bo) { return baseMapper.selectVoList(buildQueryWrapper(bo)); } private LambdaQueryWrapper buildQueryWrapper(XxxBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); // 构建查询条件 lqw.like(StringUtils.isNotBlank(bo.getName()), Xxx::getName, bo.getName()); lqw.orderByAsc(Xxx::getId); return lqw; } @Override public Boolean insertByBo(XxxBo bo) { Xxx add = MapstructUtils.convert(bo, Xxx.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); } return flag; } @Override public Boolean updateByBo(XxxBo bo) { Xxx update = MapstructUtils.convert(bo, Xxx.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } private void validEntityBeforeSave(Xxx entity) { // 数据校验 } @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { if (isValid) { // 业务校验 } return baseMapper.deleteByIds(ids) > 0; } } ``` **Controller:** ```java package org.dromara.{module}.controller; import cn.dev33.satoken.annotation.SaCheckPermission; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; import org.dromara.common.core.validate.QueryGroup; import org.dromara.common.web.core.BaseController; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.{module}.domain.bo.XxxBo; import org.dromara.{module}.domain.vo.XxxVo; import org.dromara.{module}.service.IXxxService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import java.util.Arrays; @Validated @RequiredArgsConstructor @RestController @RequestMapping("/{module}/{entity}") public class XxxController extends BaseController { private final IXxxService xxxService; @SaCheckPermission("{module}:{entity}:list") @GetMapping("/list") public R> list(@Validated(QueryGroup.class) XxxBo bo, PageQuery pageQuery) { return R.ok(xxxService.queryPageList(bo, pageQuery)); } @SaCheckPermission("{module}:{entity}:query") @GetMapping("/{id}") public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { return R.ok(xxxService.queryById(id)); } @SaCheckPermission("{module}:{entity}:add") @Log(title = "Xxx", businessType = BusinessType.INSERT) @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody XxxBo bo) { return toAjax(xxxService.insertByBo(bo)); } @SaCheckPermission("{module}:{entity}:edit") @Log(title = "Xxx", businessType = BusinessType.UPDATE) @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody XxxBo bo) { return toAjax(xxxService.updateByBo(bo)); } @SaCheckPermission("{module}:{entity}:remove") @Log(title = "Xxx", businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { return toAjax(xxxService.deleteWithValidByIds(Arrays.asList(ids), true)); } } ``` **Mapper XML:** ```xml ``` ### 3.4 数据库脚本 ```sql CREATE TABLE xxx ( id BIGINT NOT NULL COMMENT '主键', name VARCHAR(100) DEFAULT NULL COMMENT '名称', version BIGINT DEFAULT 0 COMMENT '版本', del_flag BIGINT DEFAULT 0 COMMENT '删除标志', create_by BIGINT DEFAULT NULL COMMENT '创建人', create_time DATETIME DEFAULT NULL COMMENT '创建时间', update_by BIGINT DEFAULT NULL COMMENT '更新人', update_time DATETIME DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (id) ) ENGINE=InnoDB COMMENT='Xxx表'; ``` --- ## 四、命名规范 | 类型 | 规范 | 示例 | |------|------|------| | 模块名 | base-{module} | base-demo, base-system | | 包名 | org.dromara.{module} | org.dromara.demo | | 实体类 | Xxx | TestDemo | | 业务对象 | XxxBo | TestDemoBo | | 视图对象 | XxxVo | TestDemoVo | | Mapper | XxxMapper | TestDemoMapper | | Service接口 | IXxxService | ITestDemoService | | Service实现 | XxxServiceImpl | TestDemoServiceImpl | | Controller | XxxController | TestDemoController | | 请求路径 | /{module}/{entity} | /demo/demo | | 权限标识 | {module}:{entity}:{action} | demo:demo:add | --- ## 五、依赖关系 ``` base-admin (启动模块) ├── base-demo (业务模块) ├── base-common-web ├── base-common-mybatis ├── base-common-security └── base-common-log base-demo (业务模块) ├── base-common-core ├── base-common-mybatis ├── base-common-redis ├── base-common-log ├── base-common-web └── base-common-security base-common-* (通用模块) └── 无业务模块依赖(只依赖第三方库) ``` **重要原则:** - **common 模块不依赖业务模块** - **业务模块依赖 common 模块** - **启动模块依赖所有业务模块** --- ## License MIT