# 后台管理系统 ## 环境 * Ubuntu 22.04 + JDK 19.0.2 + Maven 3.8.1 * Docker 25.0.4 + Docker-Compose 2.6.1 + Gogs + Drone * MySQL 8.0.31 + Redis 5.0.14.1 * Springboot 3.1.1 ## 部署 ### 打包应用 使用 maven 打包应用程序 .jar ```bash # 默认 local mvn clean package mvn clean package -P dev ``` 注意:外部JAR包目录在 `libs/*`,但目前是需要上传到阿里云私有库进行使用,比如 `ziniao-sdk-java` * 需要配置 maven 的 settings.xml (.m2/ 和 conf/ 都要配置) > https://packages.aliyun.com/repo/config/file/downloadWithPersonalCredential?settingsType=maven ### 启动应用 #### 1.普通启动 ```bash # 安装 nodup (Ubuntu-22.04 虚拟机可能需要安装) sudo apt install perforate -y # 后台执行 nohup java -jar /home/www/project/BackendSys/target/backendsys-1.0.0.jar > backendsys.log& # 监视日志 tail -f nohup.out # 查看已执行的 ps aux | grep java # 关闭进程 kill 158644 ``` #### 2.Docker 启动 根据本地启动配置文件 `Dockerfile` 与 `docker-compose.yml` 注意构建本地应用 `mvn clean package -P local-docker` ```bash # 创建镜像 docker build -t backendsys . # 启动镜像 docker-compose up -d # 查看镜像 docker ps # 监听日志 docker logs [container-id] ``` #### 3.Drone 启动 (线上) 配置 gogs 与 drone 联动,提交分支后立即重启 docker 应用,要注意以下几点: ```bash 1. 修改应用 yml配置文件 的内网IP (数据库/Redis):ip addr show dev eth0 # 一般 eth0: 192.168.3.30 2. 修改内置数据库 mysql库 -> user表 -> root用户的 Host 改为 % (默认有就不用改) 3. 修改内置 Redis conf:bind 192.168.3.30 (重启) ``` ## 项目开发指南 ### 主要目录说明 * (database/) 存放数据库.sql文件的目录 * (config/Security/SecurityConfig/) Security放行白名单/跨域资源配置 * (config/SwaggerConfig/) Swagger文档配置 * (filter/JwtAuthenticationFilter/) JWT放行白名单配置 * (exception/GlobalExceptionHandler/) 全局异常处理类 ### 更改项目名称 - cmd + Shift + F 将 com.xxx 名称进行全局替换; - 将 src/main/java/com/xxx 名称进行修改 ## 约束与规范 ### 1.变量 1) 所有返回值的输出字段,使用 `蛇形命名法` (单词之间使用下划线 _ 分隔,所有字母一般都小写) 2表字段的初始值及赋值,尽量不为 0,以及不从 0 开始 ### 2.常用 #### 1) 实体类 创建实体类时,创建 id 的同时必须要创建多一个 类id,比如 (article_id), 在 {编辑} 与 {删除} 操作时,传参和返回值 必须使用该 类id #### 2) 分页 页码从1开始,分页使用 PageHelper 插件, Service 写法参考: com.backendsys.service.System.SysUserServiceImpl.queryUser ```spring public Map queryUser(Integer pageNum, Integer pageSize, SysUserDTO sysUserDTO) { // 分页查询 if (pageNum != null && pageSize != null) { PageHelper.startPage(pageNum, pageSize); } // 分页输出 (自定义) List> list = sysUserMapper.queryUserList(sysUserDTO); PageInfoResult pageInfoResult = new PageInfoResult(list); return pageInfoResult.toMap(); } ``` #### 3) `增删改` 操作必须要加 `redisson` 分布式锁,锁的命名为小驼峰格式 (aA) #### 4) 提示文字 ```"message": "该用户不存在 (flag)"``` 提示出现 flag 字眼的代表是 逻辑删除,字段 del_flag #### 5) GetMapper 不要在 Controller class 上面写路由,要在每个方法上面写上完整路径 (方便检索) #### 6) Token 如果想在 token 加字段,在 JwtUtil.createSystemToken 中增加 ### 3.数据库 / Mybatis #### 1) 外键 建表,禁止使用外键 #### 2) 字段 2.1) Mybatis.xml 在 `非必填`,`空值` 的情况下,要在查询语句加入空值转义: ``` COALESCE(uf.nickname, '') nickname, ``` 2.2) SQL时间字段创建统一按照以下 ``` `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', ``` 2.3) COUNT 返回值默认是 Long 类型 ``` COUNT(us.id) AS user_count .. Long user_count = (Long) sysUserRole.get("user_count"); ``` 2.4) Mapper/Service - 查,列表、详情,定义变量不使用实体类,统一使用: `List>` 或 `Map` - 增/删/改时,接收参数使用实体类;返回值使用Long类型或Map类型; 2.5) Mapper/Service/Entity/Controller 统一使用目标的`单数`命名 #### 3) 关联查询 / 嵌套查询 使用 集合类型 时: ``` // 列表使用 LinkedHashMap 类型,详情使用实体类 .. ``` #### 4) 更新操作 更新操作之前,需要手动判断该次更新的记录是否存在,并返回相关错误提示 ``` public Result updateUserRole(@Validated(SysUserRoleDTO.Update.class) @RequestBody SysUserRoleDTO sysUserRoleDTO) { // 判断是否存在 Map sysUser = sysUserMapper.queryUserByIdOrName(sysUserDTO.getUser_id(), null); if (sysUser == null) { return Result.error(ResultEnum.DATABASE_OPERATION_FAILED.getCode(), "用户不存在"); } // ``` ### 4.文档 #### 1) 名词解释 * `获得` 前缀表示从数据库获取数据; * `查询` 前缀表示从远程第三方直接获取数据;