|
@@ -0,0 +1,169 @@
|
|
|
|
|
+# serve_template
|
|
|
|
|
+
|
|
|
|
|
+在线评测系统(OJ)后端服务模板,基于 Spring Boot 构建,提供统一的认证鉴权、用户管理与通用响应封装,可直接作为后续功能(题目、评测、比赛等)的开发底座。
|
|
|
|
|
+
|
|
|
|
|
+## 技术栈
|
|
|
|
|
+
|
|
|
|
|
+| 分类 | 选型 | 版本 |
|
|
|
|
|
+| --- | --- | --- |
|
|
|
|
|
+| 语言 | Java | 17 |
|
|
|
|
|
+| 框架 | Spring Boot | 3.5.13 |
|
|
|
|
|
+| 构建工具 | Gradle (Wrapper) | 8.14.4 |
|
|
|
|
|
+| 安全 | Spring Security + JWT | - |
|
|
|
|
|
+| ORM | MyBatis-Plus | 3.5.15 |
|
|
|
|
|
+| 数据库 | PostgreSQL + Druid 连接池 | - |
|
|
|
|
|
+| 接口文档 | springdoc-openapi (Swagger UI) | 2.8.16 |
|
|
|
|
|
+
|
|
|
|
|
+## 已实现功能
|
|
|
|
|
+
|
|
|
|
|
+- **用户认证**:注册、登录,密码 BCrypt 加密,登录后签发 JWT(有效期 24 小时)
|
|
|
|
|
+- **接口鉴权**:基于角色的方法级鉴权(`user` / `coach` / `admin`),未认证、无权限统一 JSON 返回
|
|
|
|
|
+- **用户管理**:分页查询、详情查询、新增、编辑、批量删除,以及状态 / 头像 / 密码更新
|
|
|
|
|
+- **统一响应**:`Response<T>` 通用响应体 + 全局异常处理(参数校验、业务异常)
|
|
|
|
|
+- **请求日志**:基于 `CommonsRequestLoggingFilter` 记录请求入参
|
|
|
|
|
+- **接口文档**:Swagger UI 在线调试
|
|
|
|
|
+
|
|
|
|
|
+## 项目结构
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+serve_template
|
|
|
|
|
+├── sql/postgersql.sql # 数据库初始化脚本(表结构、索引与触发器)
|
|
|
|
|
+├── src/main/java/space/anyi/serve
|
|
|
|
|
+│ ├── ServeApplication.java # 启动类
|
|
|
|
|
+│ ├── config # SecurityConfig / WebConfig(CORS/日志) / OpenApiConfig
|
|
|
|
|
+│ ├── controller # AuthController(登录注册) / UserController(用户管理)
|
|
|
|
|
+│ ├── entity # Response(响应体) / PageVo(分页) / auth / user(DTO、VO、实体)
|
|
|
|
|
+│ ├── filter # JwtAuthenticationFilter(JWT 解析过滤器)
|
|
|
|
|
+│ ├── handler # GlobalExceptionHandler + security(JWT 工具、异常入口)
|
|
|
|
|
+│ ├── mapper # MyBatis-Plus Mapper
|
|
|
|
|
+│ └── service # UserService 接口 + impl 实现
|
|
|
|
|
+└── src/main/resources
|
|
|
|
|
+ ├── application.yaml # 应用配置
|
|
|
|
|
+ └── mapper/UserMapper.xml # Mapper XML
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## 快速开始
|
|
|
|
|
+
|
|
|
|
|
+### 1. 环境要求
|
|
|
|
|
+
|
|
|
|
|
+- JDK 17+
|
|
|
|
|
+- PostgreSQL(本地或远程均可)
|
|
|
|
|
+
|
|
|
|
|
+### 2. 初始化数据库
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+psql -U <postgres用户> -f sql/postgersql.sql
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+脚本会创建 `oj` 数据库、`dev` schema,以及用户、题目、评测用例、提交记录、分类、比赛等表(含注释与索引)。
|
|
|
|
|
+
|
|
|
|
|
+### 3. 配置环境变量
|
|
|
|
|
+
|
|
|
|
|
+`application.yaml` 中数据库连接通过环境变量注入:
|
|
|
|
|
+
|
|
|
|
|
+| 环境变量 | 说明 | 默认值 |
|
|
|
|
|
+| --- | --- | --- |
|
|
|
|
|
+| `databaseHost` | 数据库地址 | - |
|
|
|
|
|
+| `databaseUsername` | 数据库用户名 | - |
|
|
|
|
|
+| `databasePassword` | 数据库密码 | - |
|
|
|
|
|
+
|
|
|
|
|
+### 4. 启动
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+./gradlew bootRun
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+服务默认运行在 `http://localhost:8080`。
|
|
|
|
|
+
|
|
|
|
|
+## 接口文档
|
|
|
|
|
+
|
|
|
|
|
+启动后访问 Swagger UI:
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+http://localhost:8080/swagger-ui/index.html
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+> `auth/login`、`auth/register` 及 Swagger 相关路径无需认证,其余接口需在请求头携带 `Authorization: Bearer <token>`。
|
|
|
|
|
+
|
|
|
|
|
+## 数据库设计
|
|
|
|
|
+
|
|
|
|
|
+表均位于 `dev` schema 下:
|
|
|
|
|
+
|
|
|
|
|
+- `user`:用户(账号、密码、用户名、角色、头像、启用状态、逻辑删除标记)
|
|
|
|
|
+- `problem`:题目(标题、描述、时间/内存限制、提交与通过次数、公开状态、难度)
|
|
|
|
|
+- `problem_case`:题目样例(展示给用户)
|
|
|
|
|
+- `problem_test`:评测用例(后台判题,可隐藏)
|
|
|
|
|
+- `submission`:提交记录(代码、语言、判题状态、耗时/内存、得分、用例统计)
|
|
|
|
|
+- `category` / `problem_category_rel`:题目类别及多对多关联
|
|
|
|
|
+- `contest` / `contest_problem` / `contest_registration`:比赛、比赛题目、比赛报名
|
|
|
|
|
+
|
|
|
|
|
+各表之间使用逻辑外键(仅记录 ID),便于水平扩展。
|
|
|
|
|
+
|
|
|
|
|
+### 时间戳自动维护
|
|
|
|
|
+
|
|
|
|
|
+- **创建时间**:所有表的 `created_at` 由数据库列默认值 `DEFAULT NOW()` 在插入时自动填充。
|
|
|
|
|
+- **更新时间**:所有表的 `updated_at` 由 `BEFORE UPDATE` 触发器自动刷新。触发器函数 `set_updated_at()` 将每行更新前的 `updated_at` 置为当前时间,各表对应触发器如下(均在 `sql/postgersql.sql` 中定义):
|
|
|
|
|
+
|
|
|
|
|
+| 表 | 触发器 |
|
|
|
|
|
+| --- | --- |
|
|
|
|
|
+| `user` | `trg_user_updated_at` |
|
|
|
|
|
+| `problem` | `trg_problem_updated_at` |
|
|
|
|
|
+| `problem_case` | `trg_problem_case_updated_at` |
|
|
|
|
|
+| `problem_test` | `trg_problem_test_updated_at` |
|
|
|
|
|
+| `submission` | `trg_submission_updated_at` |
|
|
|
|
|
+| `category` | `trg_category_updated_at` |
|
|
|
|
|
+| `problem_category_rel` | `trg_problem_category_rel_updated_at` |
|
|
|
|
|
+| `contest` | `trg_contest_updated_at` |
|
|
|
|
|
+| `contest_problem` | `trg_contest_problem_updated_at` |
|
|
|
|
|
+| `contest_registration` | `trg_contest_registration_updated_at` |
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+-- 触发器函数(定义一次,所有表共用)
|
|
|
|
|
+CREATE OR REPLACE FUNCTION set_updated_at()
|
|
|
|
|
+RETURNS TRIGGER AS $$
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ NEW.updated_at = NOW();
|
|
|
|
|
+ RETURN NEW;
|
|
|
|
|
+END;
|
|
|
|
|
+$$ LANGUAGE plpgsql;
|
|
|
|
|
+
|
|
|
|
|
+-- 每个表单独建触发器,例如:
|
|
|
|
|
+CREATE TRIGGER trg_user_updated_at
|
|
|
|
|
+BEFORE UPDATE ON dev.user
|
|
|
|
|
+FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+应用层(MyBatis-Plus 实体)无需维护 `created_at` / `updated_at`,插入与更新均由数据库自动处理。
|
|
|
|
|
+
|
|
|
|
|
+### E-R 图
|
|
|
|
|
+
|
|
|
|
|
+```mermaid
|
|
|
|
|
+erDiagram
|
|
|
|
|
+ user ||--o{ problem : "创建(created_by)"
|
|
|
|
|
+ user ||--o{ contest : "创建(created_by)"
|
|
|
|
|
+ user ||--o{ submission : "提交(user_id)"
|
|
|
|
|
+ user ||--o{ contest_registration : "报名(user_id)"
|
|
|
|
|
+ problem ||--o{ problem_case : "样例(problem_id)"
|
|
|
|
|
+ problem ||--o{ problem_test : "评测用例(problem_id)"
|
|
|
|
|
+ problem ||--o{ submission : "提交记录(problem_id)"
|
|
|
|
|
+ problem ||--o{ problem_category_rel : "关联(problem_id)"
|
|
|
|
|
+ category ||--o{ problem_category_rel : "关联(category_id)"
|
|
|
|
|
+ contest ||--o{ submission : "包含(contest_id)"
|
|
|
|
|
+ contest ||--o{ contest_problem : "题目(contest_id)"
|
|
|
|
|
+ problem ||--o{ contest_problem : "被纳入(problem_id)"
|
|
|
|
|
+ contest ||--o{ contest_registration : "报名(contest_id)"
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## 主要依赖
|
|
|
|
|
+
|
|
|
|
|
+| 依赖 | 用途 |
|
|
|
|
|
+| --- | --- |
|
|
|
|
|
+| spring-boot-starter-web | Web MVC |
|
|
|
|
|
+| spring-boot-starter-security | 认证与鉴权 |
|
|
|
|
|
+| spring-boot-starter-validation | 参数校验 |
|
|
|
|
|
+| mybatis-plus-spring-boot3-starter | ORM |
|
|
|
|
|
+| druid-spring-boot-3-starter | 数据库连接池 |
|
|
|
|
|
+| postgresql | PostgreSQL 驱动 |
|
|
|
|
|
+| jjwt | JWT 生成与解析 |
|
|
|
|
|
+| springdoc-openapi-starter-webmvc-ui | Swagger 接口文档 |
|
|
|
|
|
+| spring-boot-starter-actuator | 健康检查与监控(端点全量暴露) |
|