返回作品集
💻 代码项目

任务管理系统 · 层级任务与积分追踪

基于「任务树 + 分值权重」的层级任务管理系统的全栈实现,主任务 100 分向下拆解、叶子完成分值沿父链冒泡。

2026年9月15日

查看链接
Java 21Spring BootVue 3MyBatis-PlusH2JWTPiniaElement Plus

定位

核心业务模型不是普通待办清单,而是「任务树 + 分值权重体系」:每个主任务固定 100 总分,向下逐层按占比瓜分,叶子任务完成后分值沿父链向上累加,把大目标量化成可视化进度与积分。

功能预览

任务主页 —— 任务树总览,支持 JSON 一键导入 / 导出
任务主页 —— 任务树总览,支持 JSON 一键导入 / 导出
任务详情 —— 多层级子任务拆解,同级占比强校验合计 100%
任务详情 —— 多层级子任务拆解,同级占比强校验合计 100%
思维导图 —— jsMind 渲染任务结构,节点按优先级着色
思维导图 —— jsMind 渲染任务结构,节点按优先级着色
任务笔记 —— 可挂载任意层级的富文本笔记,子树聚合检索
任务笔记 —— 可挂载任意层级的富文本笔记,子树聚合检索

架构决策

  • 单体 jar 部署:前端构建产物打进后端 resources/static,产出约 37 MB 自包含 jar,服务器只需一个 JDK;WebConfig 区分 /api/**(REST)与其余路径(SPA history 回退,刻意排除 api 前缀避免 404 被吞成 HTML)。
  • 数据模型混合表达树:t_task_node 同时用 parent_id(定位直接子节点)与物化路径 path(/0/1/5/,LIKE 'prefix%' 一次捞整棵子树,避免递归 SQL),配 idx_task_path 等四个索引。
  • 双令牌无状态:JWT STATELESS、关 CSRF,Access 1 小时 / Refresh 7 天;前端响应拦截器用 isRefreshing + failedQueue 防并发重复刷新。

踩过的坑与权衡

  • 分值重算需双向遍历:recalcSubtreeActualScore() 按浅到深重算后代实际分值,再按深到浅重算完成分值;实际分值 = 父实际分值 × 占比 / 100,用 BigDecimal + HALF_UP 保留两位小数。
  • 占比强校验:同级子任务占比合计必须等于 100%(容差 0.01),否则抛 TASK_PERCENTAGE_SUM_ERROR;已满 100% 时允许新任务以 1% 临时创建再引导调整。
  • 父任务状态同步:进度 = Σ 子完成分值 / 父实际分值,不可手改;满 100% 自动完成、回落自动回退,但不覆盖人工「已暂停」。
  • 跨域 403 根因:Nginx 终止 TLS 后须配 server.forward-headers-strategy: framework 信任 X-Forwarded-*,否则 Spring 认为请求是 http、与浏览器 https Origin 不符判为跨域,导致 JS/CSS 全部 403。
  • 静默局部刷新:前端用递增请求序号丢弃过期响应,解决快速连点进度加减时旧数据覆盖新数据。

技术栈

Java 21、Spring Boot 3.2.5、Spring Security、JJWT、MyBatis-Plus、H2(MODE=MySQL)、Jakarta Validation、Hutool、Lombok;Vue 3、TypeScript、Vite、Element Plus、Pinia、Vue Router、Axios、jsMind。