# taskmanager
**Repository Path**: baihu/taskmanager
## Basic Information
- **Project Name**: taskmanager
- **Description**: 管理个人任务
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2019-09-17
- **Last Updated**: 2026-10-23
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 个人任务管理(taskmanager)
一个轻量级的个人任务管理应用,基于 **Spring Boot + 原生 JavaScript 单页**,无需引入任何前端框架即可运行。
## 功能特性
- 用户注册 / 登录(JWT 令牌认证,密码 BCrypt 加密)
- 多用户数据隔离:每个用户只能看到、操作自己的任务
- 任务的增删改查
- 完成状态切换(进行中 / 已完成)
- 优先级(高 / 中 / 低)
- 截止日期,逾期任务红色高亮
- 分类(如工作 / 生活,可自由输入并带历史联想)
- 关键词搜索(匹配标题与描述)
- 按状态、分类筛选,按创建时间 / 截止日期 / 优先级 / 标题排序
- 分页
## 技术栈
| 类别 | 技术 |
|------|------|
| 后端框架 | Spring Boot 3.5.16 |
| 安全认证 | Spring Security + JWT(jjwt 0.12.6)+ BCrypt |
| 数据持久化 | Spring Data JPA + Hibernate |
| 数据库 | H2(文件模式,内嵌,无需单独安装) |
| 前端 | 原生 HTML / CSS / JavaScript(单页,无框架) |
| 构建工具 | Maven |
| 运行环境 | JDK 17+ |
## 软件架构
采用经典分层架构,请求自上而下流转:
```
浏览器 → static/index.html(fetch 调用 REST 接口,携带 Bearer Token)
→ JwtAuthFilter(解析令牌,写入 SecurityContext)
→ TaskController / AuthController(接口层)
→ TaskServiceImpl / UserServiceImpl(业务层)
→ ITaskRepository / IUserRepository(数据访问层)
→ H2 数据库
```
- **security**:`JwtUtil`(令牌生成 / 解析)、`JwtAuthFilter`(认证过滤器)、`SecurityConfig`(无状态安全配置与 401 响应)
- **controller**:`/api/auth` 认证接口、`/api/tasks` 任务接口;任务接口按当前登录用户隔离数据
- **service**:业务逻辑层;列表查询使用 JPA `Specification` 实现搜索 / 筛选 / 排序 / 分页的动态组合
- **repository**:数据访问层,继承 `JpaRepository` 与 `JpaSpecificationExecutor`
- **entity**:`User`(表 `app_user`)、`Task`;状态与优先级使用枚举
- **dto**:`TaskRequest`、`TaskQuery`、`AuthRequest`、`AuthResponse`
- **exception**:`@RestControllerAdvice` 全局异常处理(404 资源不存在、400 参数错误、401 未认证)
## 安装教程
1. 环境要求:JDK 17 及以上、Maven 3.x(H2 内嵌,无需额外安装数据库)
2. 克隆仓库并进入目录:
```bash
git clone https://gitee.com/baihu/taskmanager.git
cd taskmanager
```
3. 启动应用:
```bash
mvn spring-boot:run
```
4. 打开浏览器访问:,首次使用请先注册账号
运行单元测试:
```bash
mvn test
```
## 使用说明
- 打开页面先「注册」或「登录」;登录状态保存在浏览器 localStorage,刷新不会丢失
- 点击右上角「+ 新建任务」,填写标题(必填)、描述、优先级、截止日期、分类后保存
- 列表左侧复选框可一键切换完成状态
- 顶部工具栏支持:关键词搜索、按状态筛选、按分类筛选、按不同字段排序
- 每条任务右侧可「编辑」「删除」
- 右上角显示当前用户,点击「退出」清除令牌并回到登录页
- 数据持久化在运行目录下的 `./.h2/datadb` 文件中;删除 `.h2` 目录并重启即可重置全部数据
## 接口文档
### 认证接口(无需登录)
前缀:`/api/auth`
| 方法 | 路径 | 说明 |
|------|------|------|
| `POST` | `/api/auth/register` | 注册,成功直接返回令牌 |
| `POST` | `/api/auth/login` | 登录,返回令牌 |
| `GET` | `/api/auth/me` | 获取当前登录用户(需携带令牌) |
请求体:
```json
{ "username": "alice", "password": "secret123" }
```
响应体:
```json
{ "token": "eyJhbGciOiJIUzI1NiJ9...", "username": "alice" }
```
校验规则:用户名 3-20 位字母 / 数字 / 下划线且唯一;密码 6-64 位。
### 任务接口(需登录)
统一前缀:`/api/tasks`,请求头必须携带:
```
Authorization: Bearer
```
未携带、令牌无效或过期时返回 `401` 与 `{"message":"未登录或登录已过期"}`。
| 方法 | 路径 | 说明 |
|------|------|------|
| `GET` | `/api/tasks` | 分页查询(支持搜索 / 筛选 / 排序) |
| `POST` | `/api/tasks` | 新建任务 |
| `GET` | `/api/tasks/{id}` | 查询单个任务 |
| `PUT` | `/api/tasks/{id}` | 更新任务 |
| `PATCH` | `/api/tasks/{id}/complete` | 切换完成状态 |
| `DELETE` | `/api/tasks/{id}` | 删除任务 |
| `GET` | `/api/tasks/categories` | 获取分类列表 |
> 所有任务接口只操作当前登录用户自己的数据,访问他人任务返回 404。
**列表查询参数**(`GET /api/tasks`)
| 参数 | 说明 | 示例 |
|------|------|------|
| keyword | 关键词,匹配标题 / 描述 | 设计 |
| status | 状态:`TODO` / `DONE` | TODO |
| priority | 优先级:`LOW` / `MEDIUM` / `HIGH` | HIGH |
| category | 分类 | 工作 |
| sort | 排序,格式 `字段,方向`;可选字段:createTime、updateTime、dueTime、priority、title | createTime,desc |
| page | 页码,从 0 开始 | 0 |
| size | 每页条数 | 10 |
**新建 / 更新请求体**(`POST` / `PUT`)
```json
{
"title": "完成项目设计",
"description": "画原型图",
"priority": "HIGH",
"dueTime": "2026-10-25",
"category": "工作"
}
```
> `title` 必填;`dueTime` 格式为 `yyyy-MM-dd`,不填则视为无截止日期。
**单任务响应示例**
```json
{
"id": 1,
"title": "完成项目设计",
"description": "画原型图",
"status": "TODO",
"priority": "HIGH",
"dueTime": "2026-10-25",
"category": "工作",
"createTime": "2026-10-21 18:25:59",
"updateTime": "2026-10-21 18:25:59",
"user": "admin"
}
```
**列表响应示例**(Spring Data 分页对象)
```json
{
"content": [ { "id": 1, "title": "完成项目设计" } ],
"totalElements": 1,
"totalPages": 1,
"number": 0,
"size": 10
}
```
## 项目结构
```
taskmanager
├── pom.xml
├── src/main/java/com/zs/
│ ├── TaskmanagerApplication.java # 启动类
│ └── taskmanager/
│ ├── controller/
│ │ ├── AuthController.java # 注册 / 登录 / 当前用户
│ │ └── TaskController.java # 任务接口(按登录用户隔离)
│ ├── security/
│ │ ├── JwtUtil.java # 令牌生成与解析
│ │ ├── JwtAuthFilter.java # Bearer Token 认证过滤器
│ │ └── SecurityConfig.java # 无状态安全配置
│ ├── service/
│ │ ├── ITaskService.java
│ │ ├── IUserService.java
│ │ └── impl/
│ │ ├── TaskServiceImpl.java # 业务逻辑 + 动态查询
│ │ └── UserServiceImpl.java # 注册 / 登录 / BCrypt 校验
│ ├── repository/
│ │ ├── ITaskRepository.java # 数据访问层
│ │ └── IUserRepository.java
│ ├── entity/
│ │ ├── User.java # 表 app_user
│ │ ├── Task.java
│ │ ├── TaskStatus.java # TODO / DONE
│ │ └── TaskPriority.java # LOW / MEDIUM / HIGH
│ ├── dto/
│ │ ├── TaskRequest.java # 新建 / 更新请求体
│ │ ├── TaskQuery.java # 列表查询参数
│ │ ├── AuthRequest.java # 注册 / 登录请求体
│ │ └── AuthResponse.java # token + username
│ └── exception/
│ ├── TaskNotFoundException.java
│ ├── UnauthorizedException.java
│ └── GlobalExceptionHandler.java
├── src/main/resources/
│ ├── application.yml # 数据源 / JPA / JWT 配置
│ └── static/index.html # 前端单页(含登录注册)
└── src/test/java/com/zs/TaskmanagerApplicationTests.java
```
## 配置说明(application.yml)
```yaml
spring:
# 数据源
datasource:
url: jdbc:h2:file:./.h2/datadb
username: sa
password: sa
driver-class-name: org.h2.Driver
# JPA:自动建表 / 更新
jpa:
show-sql: true
generate-ddl: true
hibernate:
ddl-auto: update
app:
jwt:
secret: taskmanager-jwt-secret-... # HS256 签名密钥,至少 32 字节
expiration-ms: 86400000 # 令牌有效期,默认 24 小时
```
> **安全提示**:`app.jwt.secret` 仅用于本地演示,部署到公网前请替换为随机密钥,并通过环境变量注入,不要硬编码在仓库中。
## 常见问题
- **端口被占用**:默认端口 8080,可在 `application.yml` 中通过 `server.port` 修改。
- **重置数据**:删除运行目录下的 `.h2` 文件夹后重启即可(会同时清空已注册用户)。
- **H2 保留字**:实体字段 `user` 映射到数据库列 `user_name`(H2 2.x 中 `USER` 为保留字,故做映射);用户表命名为 `app_user` 同理。
- **接口返回 401**:令牌缺失、无效或已过期,重新登录即可;前端会自动清除本地令牌并回到登录页。
- **前端列表报「No static resource api/tasks」**:Spring Boot 3 默认不匹配带尾斜杠的路径,应使用 `/api/tasks?...` 而非 `/api/tasks/?...`(前端已修正)。
## 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
## 码云特技
1. 使用 Readme_XXX.md 来支持不同的语言,例如 Readme_en.md, Readme_zh.md
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)