commit a4aa749cc61863551bb7d1ef08ff88242a032f6a Author: Vicky <10212746+haifeng-jiang@user.noreply.gitee.com> Date: Wed Oct 14 18:02:47 2026 +0800 feat: 初始化短剧服务端(管理后台 API + 客户端 API) Spring Boot 3.2 / MyBatis-Plus / PostgreSQL,7 个 Maven 模块;含认证鉴权、内容与媒资管理、操作日志,以及客户端 /app/** 接口。 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..77cf8a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# 构建产物 +target/ + +# IDE / 编辑器 +.idea/ +*.iml +.vscode/ + +# 系统文件 +.DS_Store + +# 日志 +*.log +logs/ + +# 运行期上传的媒资(图片、视频,几百 MB)不入库,只保留目录 +data/uploads/* +!data/uploads/.gitkeep diff --git a/README.md b/README.md new file mode 100644 index 0000000..aca883d --- /dev/null +++ b/README.md @@ -0,0 +1,320 @@ +# ReelShort 短剧服务(后端) + +短剧服务的服务端,Spring Boot + PostgreSQL,目前实现管理后台接口(`/admin/**`)。 +完整架构设计与迭代计划见 [docs/architecture-design.md](docs/architecture-design.md)。 + +| 项 | 版本 | +| --- | --- | +| 运行时 | JDK 21(LTS),编译目标 Java 17 | +| 框架 | Spring Boot 3.2.5、Spring Security 6、MyBatis-Plus 3.5.7 | +| 数据库 | PostgreSQL 18 | +| 构建 | Maven 3.10 多模块 | + +## 目录结构 + +``` +java/ +├── reelshort-common/ 统一响应、分页、错误码、业务异常 +├── reelshort-framework/ JWT 鉴权、权限校验、全局异常、MyBatis-Plus、CORS +├── reelshort-module-system/ 管理员、角色、权限、菜单、角色分类、配置、操作日志 +├── reelshort-module-content/ 短剧、剧集、题材、审核发布 +├── reelshort-admin-api/ 启动模块与 /admin/** 控制器 +├── sql/ schema.sql 建表、data.sql 初始化数据 +└── docs/ 架构设计文档 +``` + +## 开发环境 + +本机环境由 Homebrew 统一管理(版本以本机实际安装为准): + +| 组件 | 版本 | 说明 | +| --- | --- | --- | +| Homebrew | 7.0.9 | 远端指向清华镜像,见文末常见问题 | +| JDK | OpenJDK 21.0.12.1 | `brew install openjdk@21`,`JAVA_HOME` 已写入 `~/.zshrc` | +| Maven | 3.10.0 | `brew install maven`,命令为 `/opt/homebrew/bin/mvn` | +| PostgreSQL | 18.6 | `brew install postgresql@18`,`brew services start postgresql@18` 启动 | + +> `postgresql@18` 是 keg-only,命令行工具在 `/opt/homebrew/opt/postgresql@18/bin`, +> 用之前把它加到 PATH:`export PATH="/opt/homebrew/opt/postgresql@18/bin:$PATH"`。 + +```sh +java -version # openjdk 21.0.12.1 +mvn -v # Maven 3.10.0 / Java 21.0.12.1 +``` + +说明: + +- 工程编译目标为 Java 17(`maven.compiler.release=17`),在 JDK 21 上构建与运行。 +- 父 POM 显式声明了注解处理器(`full` + `annotationProcessorPaths`): + JDK 23 起不再默认扫描 classpath 上的处理器,缺这段配置 Lombok 会失效。 +- 旧的 JDK 18 仍留在 `/Library/Java/JavaVirtualMachines/jdk-18.0.2.jdk`,删除需要 sudo, + 不影响使用(`java_home` 与 `JAVA_HOME` 都已指向 21)。 + +## 快速开始 + +服务有两个入口,可以只启动其中一个: + +| 服务 | 模块 | 端口 | 面向 | +| --- | --- | --- | --- | +| 管理端 | `reelshort-admin-api` | 8080 | Vue 后台 | +| 客户端 | `reelshort-app-api` | 8081 | Flutter 客户端 | + +### 1. 初始化数据库 + +```sh +export PATH="/opt/homebrew/opt/postgresql@18/bin:$PATH" +cd /Users/jianghaifeng/Desktop/ReelShort/FruitServer +psql -h 127.0.0.1 -U reelshort -d reelshort -f sql/schema.sql +psql -h 127.0.0.1 -U reelshort -d reelshort -f sql/data.sql +``` + +数据库名 `reelshort`,角色 `reelshort`(密码 `reelshort`),两个脚本都可重复执行。 +首次搭建环境时先建角色与库: + +```sh +psql -d postgres -c "CREATE ROLE reelshort LOGIN PASSWORD 'reelshort';" +psql -d postgres -c "CREATE DATABASE reelshort OWNER reelshort ENCODING 'UTF8';" +``` + +连接信息在 +`reelshort-admin-api/src/main/resources/application.yml`,可用环境变量 +`DB_USER` / `DB_PASSWORD` / `JWT_ADMIN_SECRET` 覆盖。 + +### 关于 PostgreSQL 的两点说明 + +- 自增列用 `GENERATED BY DEFAULT AS IDENTITY`;`sql/data.sql` 里用了显式 ID, + 脚本末尾会把序列 `setval` 到当前最大值,新增数据不会主键冲突。 +- PostgreSQL 没有 `ON UPDATE CURRENT_TIMESTAMP`,`updated_at` 由 `set_updated_at()` + 触发器统一维护(见 `sql/schema.sql` 末尾),实体侧仍不参与更新该字段。 +- 轮播图的展示位置列名叫 `slot`(`position` 在 PostgreSQL 里是关键字), + 实体用 `@TableField("slot")` 映射,对外接口字段仍是 `position`,前端无需改动。 + +### 2. 构建 + +```sh +cd /Users/jianghaifeng/Desktop/ReelShort/FruitServer +mvn -DskipTests package +``` + +### 3. 启动 + +```sh +cd /Users/jianghaifeng/Desktop/ReelShort/FruitServer +java -jar reelshort-admin-api/target/reelshort-admin-api-1.0.0-SNAPSHOT.jar +java -jar reelshort-app-api/target/reelshort-app-api-1.0.0-SNAPSHOT.jar +``` + +启动后:服务地址 `http://localhost:8080`,接口文档 `http://localhost:8080/doc.html`。 + +## 默认账号 + +密码均为 `admin123`。 + +| 账号 | 角色 | 权限范围 | +| --- | --- | --- | +| admin | 超级管理员 | 全部 14 项权限 | +| content.editor01 | 内容运营 | 短剧、剧集的增删改与封面上传 | +| content.reviewer01 | 审核专员 | 查看内容、审核发布、数据报表 | +| data.analyst01 | 数据分析师 | 查看短剧列表与数据报表 | + +## 接口一览 + +### 认证 `/admin/auth` + +| 方法 | 路径 | 说明 | +| --- | --- | --- | +| POST | `/login` | 登录,返回 token 与权限码 | +| GET | `/menus` | 当前用户菜单路由树(前端动态路由) | +| GET | `/profile` | 当前登录人信息 | +| POST | `/logout` | 登出(JWT 无状态,前端清除 token 即可) | +| POST | `/password` | 修改自己的密码 | + +### 后台管理 + +| 模块 | 接口 | +| --- | --- | +| 管理员 | `GET /admin/admin-users/page`、`POST /admin/admin-users`、`PUT\|DELETE /admin/admin-users/{id}`、`PUT /{id}/status`、`PUT /{id}/password` | +| 角色 | `GET /admin/roles/page`、`GET /admin/roles/list`、`POST /admin/roles`、`PUT\|DELETE /admin/roles/{id}`、`GET\|PUT /admin/roles/{id}/permissions` | +| 角色分类 | `GET\|POST /admin/role-categories`、`PUT\|DELETE /admin/role-categories/{id}` | +| 权限点 | `GET /admin/permissions`(按分组返回,供权限配置页使用) | +| 菜单 | `GET /admin/menus/tree`、`POST /admin/menus`、`PUT\|DELETE /admin/menus/{id}` | +| 系统配置 | `GET\|PUT /admin/configs` | +| 操作日志 | `GET /admin/operation-logs/page`(按操作人、模块、动作、结果、时间范围筛选)、`GET /admin/operation-logs/{id}` | +| 字典 | `GET /admin/dicts/drama-category`、`GET /admin/dicts/content-status` | + +### 内容管理 + +| 模块 | 接口 | +| --- | --- | +| 短剧 | `GET /admin/dramas/page`、`GET /admin/dramas/{id}`、`POST /admin/dramas`、`PUT\|DELETE /admin/dramas/{id}` | +| 审核发布 | `POST /admin/dramas/{id}/submit`、`/approve`、`/reject`、`/publish`、`/offline` | +| 审核记录 | `GET /admin/dramas/{id}/review-records` | +| 剧集 | `GET /admin/episodes?dramaId=`、`POST /admin/episodes`、`PUT\|DELETE /admin/episodes/{id}`、`PUT /admin/episodes/sort` | +| 轮播图 | `GET /admin/banners/page`、`POST /admin/banners`、`PUT\|DELETE /admin/banners/{id}`、`PUT /admin/banners/{id}/status`、`PUT /admin/banners/sort` | +| 短剧类型 | `GET\|POST /admin/drama-categories`、`PUT\|DELETE /admin/drama-categories/{id}`(权限沿用 `drama:*`) | + +### 媒资 `/admin/media` + +| 方法 | 路径 | 说明 | +| --- | --- | --- | +| POST | `/upload/init` | 建立分片会话,返回 `uploadId`、`chunkSize`、`totalChunks` | +| POST | `/upload/chunk` | 上传单个分片(multipart:`uploadId`、`index`、`file`) | +| POST | `/upload/complete` | 合并分片,返回媒资(含可访问的 `url`) | +| GET | `/{id}` | 查询媒资 | + +## 媒资存储(本地) + +当前没有对象存储,文件直接落在本机磁盘: + +| 项 | 默认值 | 说明 | +| --- | --- | --- | +| 存储目录 | `./data/uploads` | 配置项 `reelshort.media.root-dir`,按 `业务类型/年月/uuid.ext` 分目录 | +| 访问前缀 | `/files/**` | 配置项 `reelshort.media.public-prefix`,映射为静态资源 | +| 分片大小 | 5MB | `reelshort.media.chunk-size`,单文件上限 2GB | +| 请求上限 | 20MB | `spring.servlet.multipart`,只需容纳一个分片 | + +要点: + +- `/files/**` 在 `SecurityConfig` 里是公开路径,因为 `` / `