# 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/)