Sz-Admin | SpringBoot3 JDK21 Vue3开源后台RBAC管理系统 | Sz-Admin代码规范推荐

简介

image.png
image.png

Sz Admin ,一个基于 Spring Boot 3、JDK21、Vue 3 和 Element-Plus 的开源后台管理框架,致力于为您提供一个流畅、直观且功能强大的开发框架。它不仅融合了最新的技术趋势,而且通过精心设计,确保了系统的简洁性和高效,让使用者可以专注业务。

在线体验


规范

规范就像软件开发的地图和指南,帮助团队成员在项目旅程中找到正确的方向。它们为代码的组织、命名和风格设立了框架,使得整个团队能够以更加一致的方式合作。通过规范,我们可以避免陷入混乱和混乱的境地,并确保我们的代码库保持清晰、易于理解和可维护。


<font color=blue>不要担心!</font> 以下规范看起来有可能比较多,但是我们代码生成器基本都帮助我们实现了。

后端

1. 项目结构

我们以表teacher_statistics为例,其业务代码结构如下:

以后新业务与<u>teacher_statics</u>同理,在com.sz.admin目录下创建业务相关包名,并同时遵循下述结构。

虽然看起来目录结构比较多,但我们不用担心代码生成器很容易帮我们创建它们,并且可以根据自己的实际需求灵活生成所需文件。

sz-boot-parent/sz-service/sz-service-admin/
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── sz
│   │   │           ├── admin
│   │   │           │   ├── system                                          # rbac系统相关代码等都存放到此包下
│   │   │           │   │   │  ...
│   │   │           │   └── teacher                                         # teacher_statstics 表抽取包名,存放所有和teacher相关的业务
│   │   │           │       ├── controller                                  # controller层
│   │   │           │       │   └── TeacherStatisticsController.java                
│   │   │           │       ├── mapper
│   │   │           │       │   └── TeacherStatisticsMapper.java            # mybatis mapper
│   │   │           │       ├── pojo                                        # pojo层
│   │   │           │       │   ├── dto
│   │   │           │       │   │   ├── TeacherStatisticsCreateDTO.java     # DTO add
│   │   │           │       │   │   ├── TeacherStatisticsImportDTO.java     # DTO 导入
│   │   │           │       │   │   ├── TeacherStatisticsListDTO.java       # DTO 列表查询条件
│   │   │           │       │   │   └── TeacherStatisticsUpdateDTO.java     # DTO update
│   │   │           │       │   ├── po
│   │   │           │       │   │   └── TeacherStatistics.java              # PO 数据库实体映射
│   │   │           │       │   └── vo
│   │   │           │       │       └── TeacherStatisticsVO.java
│   │   │           │       └── service                                     # service层
│   │   │           │           ├── impl
│   │   │           │           │   └── TeacherStatisticsServiceImpl.java
│   │   │           │           └── TeacherStatisticsService.java
│   │   └── resources
│   │       ├── ...
│   │       ├── mapper
│   │       │   ├── system
│   │       │   ├── ...
│   │       │   └── teacher                                                 # mybatis mapperXml
│   │       │       └── TeacherStatisticsMapper.xml

2. 分层

在sz-admin框架中,我们采用DTO、VO和PO来组织POJO类,以优化数据管理和传输:

  • DTO(数据传输对象):(Data Transfer Object)专为服务层与控制器间的数据交换设计,仅包含数据属性,不涉及业务逻辑。
  • VO(视图对象):定制化数据结构,用于向用户界面传递信息。VO可以基于DTO进行扩展,包含简化或特定格式的数据,并可能集成少量业务逻辑以满足展示需求。
  • PO(持久化对象):代表数据库中的持久化数据模型,与数据库表结构直接对应,属性映射数据库字段。

3. 时间格式

在创建数据表时,除非有特定需求,我们通常将时间字段设置为datetime类型,这在Java中对应于LocalDateTimeLocalDate类型。

无需担心时间格式的解析问题,因为我们的框架已经在sz-common模块中的JacksonConfiguration.java[1]类中提供了相应的处理。


4. 主键自增ID、关联ID

框架规定,所有主键自增ID(int)、关联ID(int) 在java中都以 Long 类型进行映射。


5. Web API

我们的Web API严格遵循RESTful API设计原则,以确保高效和一致的资源管理。以下是API路由和操作的概览:

如:

Method Router CRUD 描述
POST /teacher-statics 新增 用于创建新的教师统计数据
PUT /teacher-statics 修改 用于更新教师统计数据。
DELETE /teacher-statics 删除 用于删除教师统计数据。
GET /teacher-statics 查询、分页查询 用于检索教师统计数据列表,支持分页查询。
GET /teacher-statics/{id} 详情 用于获取指定ID的教师统计数据详情。
POST /teacher-statics/import 导入 用于执行教师统计数据的批量导入。
POST /teacher-statics/export 导出 用于执行教师统计数据的批量导出。

6. Service 接口命名规范

teacher_staticstics表的业务逻辑中,我们遵循以下接口方法命名规则,以确保代码的清晰和一致性:

public interface TeacherStatisticsService extends IService<TeacherStatistics> {

    // 新增
    void create(TeacherStatisticsCreateDTO dto);

    // 修改
    void update(TeacherStatisticsUpdateDTO dto);

    // 分页
    PageResult<TeacherStatisticsVO> page(TeacherStatisticsListDTO dto);

    // 列表(不分页)
    List<TeacherStatisticsVO> list(TeacherStatisticsListDTO dto);

    // 删除
    void remove(SelectIdsDTO dto);

    // 详情
    TeacherStatisticsVO detail(Object id);

    // 导入
    void importExcel(MultipartFile file);

    // 导出
    void exportExcel(TeacherStatisticsListDTO dto, HttpServletResponse response);
}

7. Swagger注解

我们的框架遵循Swagger 3和OpenAPI Specification (OAS) 3.0标准,要求在Controller方法和POJO类上适当使用注解,以确保API的自文档化和规范性。

例如,您可以这样使用注解:

// controller.java
@Tag(name =  "教师统计总览表")
public class TeacherStatisticsController  {
    
    @Operation(summary = "新增")
    public ApiResult create(@RequestBody TeacherStatisticsCreateDTO dto) {
        teacherStatisticsService.create(dto);
        return ApiResult.success();
    }
    
    // 二进制文件上传特殊样式
    @Operation(summary = "导入")
    @Parameters({
      @Parameter(name = "file", description = "上传文件", schema = @Schema(type = "string", format = "binary"), required = true),
    })
    public void importExcel(MultipartFile file) {
        teacherStatisticsService.importExcel(file);
    }
    
    // ...
}
// DTO.java、PO.java、VO.java
@Data
@Schema(description = "TeacherStatistics添加DTO")
public class TeacherStatisticsCreateDTO {

   @Schema(description =  "统计年限")
   private String year;

   @Schema(description =  "统计月份")
   private String month;

   @Schema(description =  "统计年月")
   private String duringTime;

   @Schema(description =  "教师id")
   private String teacherId;

   @Schema(description =  "讲师区分类型")
   private Integer teacherCommonType;

   @Schema(description =  "授课总数")
   private Integer totalTeaching;

   @Schema(description =  "服务班次数")
   private Integer totalClassCount;

   @Schema(description =  "课时总数")
   private BigDecimal totalHours;

   @Schema(description =  "核对状态")
   private Integer checkStatus;

   @Schema(description =  "核对时间")
   @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
   private LocalDateTime checkTime;

   @Schema(description =  "最近一次同步时间")
   @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
   private LocalDateTime lastSyncTime;

   @Schema(description =  "备注")
   private String remark;

}
生成API文档 UI 如下
image.png

8. @Autowired 注解

框架中如无特殊情况禁止使用@Autowired注解!!如需引入bean可使用如下两种方式:

  1. 使用 @RequiredArgsConstructor:在类的构造函数中声明 final 类型的依赖,Lombok 会自动生成构造函数,并自动注入对应的 bean。例如:
 @RequiredArgsConstructor
public class TeacherStatisticsController {
    private final TeacherStatisticsService teacherStatisticsService;
}
  1. 使用 @Resource 注解:通过 @Resource 注解直接注入对应的 bean。例如:
public class TeacherStatisticsController {
    @Resource
    private TeacherStatisticsService teacherStatisticsService;
}

9. 接口鉴权

在我们的框架中,Controller 接口方法应明确其权限要求,除非存在特定的业务需求。这有助于确保安全性和合规性。

以下是使用 @SaCheckPermission 注解来指定接口方法权限范围的示例代码:

public class SysRoleController {
    
    // 有sys.role.create_btn 权限标识的用户或 角色是超级管理员可以访问。
    @Operation(summary = "角色新增")
    @SaCheckPermission(value = "sys.role.create_btn", orRole = GlobalConstant.SUPER_ROLE)
    public ApiResult create(@Valid @RequestBody SysRoleAddDTO dto) {
        sysRoleService.create(dto);
        return ApiResult.success();
    }

    ...
    // 同时具有sys.role.setting_btn、sys.role.update_btn权限标识的用户或角色是超级管理员可以访问。
    @Operation(summary = "角色菜单信息查询")    
    @SaCheckPermission(value = {"sys.role.setting_btn", "sys.role.update_btn"}, mode = SaMode.AND, orRole = GlobalConstant.SUPER_ROLE)
    @GetMapping("/menu")
    public ApiResult findRoleMenuByRoleId(@NotZero @RequestParam Integer roleId) {
        return ApiPageResult.success(sysRoleMenuService.queryRoleMenu(roleId));
    }

}

前端

1. 项目结构

同样,我们以表teacher_statistics为例,其业务代码结构如下:

sz-admin/
├── api
│   ├── ...
│   ├── interface                                           # ts对象结构,类似于 Java 实体对象
│   │   ├── system                                          
│   │   │   ├── ...
│   │   ├── teacher                                         # teacher_statstics 表抽取包名,存放所有和teacher相关的业务         
│   │   │   └── teacherStatistics.ts                        # 对象实体
│   │   └── ...
│   └── modules
│       ├── system
│       │   ├── ...
│       ├── teacher                                         # teacher_statstics 表抽取包名,存放所有和teacher相关的业务
│       │   └── teacherStatistics.ts                        # API路由
│   │   └── ...
├── ...
└── views                                                   # 项目所有页面
    ├── system
    │   ├── ...
    ├── teacher                                             # teacher_statstics 表抽取包名,存放所有和teacher相关的业务
    │   └── teacherStatistics
    │       ├── components                                  # 页面组件包
    │       │   └── TeacherStatisticsForm.vue               # Form组件(新增、编辑)
    │       └── index.vue                                   # 主页面
    └── ...

2. 按钮鉴权

在我们的开发框架中,对于按钮控件,除非有特定的业务需求,否则必须明确定义它们的权限级别。

例如,以下是使用v-auth指令来指定权限的代码示例:

[!TIP]

v-auth 指令有三种使用方式:

  • 单一权限:

    具有指定字符串内的权限

    v-auth="'sys.menu.create_btn'" 
    
  • 多条件AND:

    必须同时具有conditions数组包含的权限

    v-auth="[{ type: 'and', conditions: ['sys.role.setting_btn', 'sys.role.update_btn'] }]" 
    
  • 多条件OR:

    具有conditions数组内的任一权限

    v-auth="[{ type: 'or',  conditions: ['sys.user.unlock_btn','sys.user.role_set_btn','sys.user.delete_btn' ] }]" 
    
<template>
  <div class="table-box"> 
      
    <ProTable
      ref="proTableRef"
      title="教师统计"
      :indent="20"
      :columns="columns"
      :search-columns="searchColumns"
      :request-api="getTableList"
      row-key="id"
    >
      <!-- 表格 header 按钮 -->
      <template #tableHeader="scope">
        <el-button
          type="primary"
          v-auth="'teacher.statistics.create'" 
          :icon="CirclePlus"
          @click="openAddEdit('新增教师统计')"
        >
          新增
        </el-button>
        ...
        <el-button
          v-auth="'teacher.statistics.remove'"
          type="primary"
          link
          :icon="Delete"
          @click="deleteInfo(row)"
        >
          删除
        </el-button>
      </template>
    </ProTable>
  </div>
</template>
...

3. 代码提交前检查

为了确保项目的长期可持续性和可维护性,我们制定了以下代码提交前的检查流程。请遵循以下步骤,以确保您的代码符合项目标准:

  • 类型检查 (type-check)

    在提交代码前,请运行 TypeScript 类型检查,以确保代码的类型安全。避免使用 any 类型(“any script编程”),因为这会削弱类型系统的优势。如果在构建阶段发现类型错误,构建过程将失败。

    pnpm run type-check
    
  • 代码风格检查 (lint)

    使用 ESLint 进行代码风格检查,确保代码符合项目的风格规范。这有助于保持代码的一致性和可读性。

    pnpm run lint
    
  • 代码格式化 (format)

    在提交之前,对代码进行格式化,以确保其整洁和一致。这有助于减少因格式问题引起的代码审查。

    pnpm run format
    

我们推荐使用集成开发环境(IDE)来自动化上述流程。大多数现代编辑器都支持快捷方式或插件来执行这些操作。以下是在 WebStorm 中执行这些操作的示例:

image.png

打开package.json 分别运行划线部分左侧头部的运行图标即可。


  1. 位于/sz-common/sz-common-core模块下,包com.sz.core.common.configuration

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容