任务周期记录系统计划书

17 阅读12分钟

序言


🐒:
   起因是我有很多想法、任务、视频等事情要弄,但磨磨唧唧就忘记干啥了,记了备忘录也磨磨唧唧的,然后不了了之了,有的好不容易弄完了。也不记得什么时候开始的,总感觉用了很长时间,总之,乱七八糟的。


1. 项目愿景与设计哲学


1.1 项目愿景

打造一个个人时间感知工具,帮助用户量化任务拖延程度、复盘完成效率,让 “时间去哪了” 变得可视化、可管理。系统不仅记录任务的开始与结束,更通过情绪化标签和多元化视图,唤醒用户对时间流逝的觉知。


1.2 设计哲学(贯穿全文的三大原则)

原则含义本项目体现
反脆弱系统能容忍下游故障,出问题可自愈软删除恢复、定期备份、导出快照、操作解耦
依赖隔离核心业务不依赖外部框架,升级无忧分层架构(Handler → Service → Repository),Service 层无任何框架导入
设计前置在动手前想清楚边界和异常明确字段流转、统一时间标准、预留扩展字段

2. 核心功能需求


2.1 任务生命周期管理

功能说明
新增任务录入名称、开始时间(默认当前)、任务类型(短期/长期)
完成任务记录完成时间(精确到秒),自动计算总耗时(finish_time - start_time
放弃任务不记录完成时间,需选择放弃原因(如 “三分钟热度”“计划变更”
重新激活“已完成”“已放弃” 的任务重置为 “进行中”(清空完成时间)
软删除删除任务进入回收站,可恢复或彻底清空
编辑任务仅允许修改 名称 和开始时间

2.2 任务类型细分

类型标识特性周期
短期任务short默认类型。若创建后超过 24 * 7 小时未完成且未放弃,前端展示 “🔥 热度冷却” 提示。
拖延标签沿用通用规则。
1 ~ 3 月
长期任务long支持关联子任务(里程碑)。主任务进度条由子任务完成比例自动计算。
最终总耗时仍从主任务 start_time 到 finish_time 计算。
一年以上

2.3 拖延标签系统(通用规则)

针对所有进行中的任务,根据开始时间距当前时间的自然日数动态生成标签(阈值可配置):

天数范围标签
< 7(无)
7 ~ 2 * 7你是在偷懒么?
2 * 7 ~ 4 * 7别拖延了!行动起来!
4 * 7 ~ 8 * 7拖延症犯了吧!!
8 * 7 ~ 12 * 7你是不是在口嗨?!
12 * 7 ~ 16 * 7再这样下去这任务你就烂尾了!
16 * 7 ~ 24 * 7你又画了一个饼...
≥ 24 * 7你果然在放屁!!!

2.4 子任务管理(仅长期任务)

  • 支持增删改子任务,标记完成/未完成,标记完成时自动记录完成时间。
  • 主任务进度 = (已完成子任务数 / 总子任务数) * 100%
  • 当所有子任务完成时,系统提醒用户完成主任务(不强制自动完成)。

2.5 四种前端视图

视图适用场景操作支持
表格/卡片默认视图,适合快速编辑、筛选、批量操作全功能(增删改、完成、放弃)
甘特图直观查看任务时间跨度,暴露 “长期拖延”点击条查看详情,不支持拖拽改期
看板(泳道)按状态(进行中/已完成/已放弃)拖拽管理支持拖拽卡片改变状态,拖至 “完成/放弃” 列触发对应接口
垂直时间轴按开始时间倒序展示,类 “编年体” 叙事展示标签与耗时,侧重阅读,操作按钮折叠至悬停显示

2.6 统计看板

  • 统计近三个月(从当前月往前推 3 个月)的任务数据。
  • 展示指标:总任务数、完成数/率、放弃数/率、进行中数/率
  • 按月分组展示完成率趋势(柱状图/折线图),按任务类型(短期/长期)分别统计完成率。

3. 数据库设计


3.1 主任务表 tasks

字段名类型约束说明
idINTEGERPRIMARY KEY自增主键
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP创建时间
updated_atDATETIMEDEFAULT CURRENT_TIMESTAMP ON UPDATE更新时间
deleted_atDATETIMENULL软删除时间
GORM 软删除支持)
nameVARCHAR(255)NOT NULL任务名称
typeVARCHAR(20)NOT NULL DEFAULT 'short'short / long
start_timeDATETIMENOT NULL开始时间
finish_timeDATETIMENULL完成时间
(仅 status = completed 时有值)
statusVARCHAR(20)NOT NULL DEFAULT 'active'active / completed / abandoned
progressINTDEFAULT 00 ~1 00,仅长期任务有意义,由子任务自动计算
abandon_reasonVARCHAR(50)NULL放弃原因
(如 “三分钟热度” 、“计划变更”

索引statusstart_timedeleted_at


3.2 子任务表 subtasks

字段名类型约束说明
idINTEGERPRIMARY KEY自增主键
created_atDATETIMEDEFAULT CURRENT_TIMESTAMP创建时间
updated_atDATETIMEDEFAULT CURRENT_TIMESTAMP ON UPDATE更新时间
task_idINTEGERNOT NULL, FOREIGN KEY关联 tasks(id),级联删除
nameVARCHAR(255)NOT NULL子任务名称
doneBOOLEANDEFAULT FALSE是否完成
done_timeDATETIMENULL完成时间
(标记完成时自动写入)
orderINTDEFAULT 0排序序号

索引task_idorder


4. 后端架构设计(Go + Gin + GORM)


4.1 分层架构与依赖隔离

┌─────────────────────────────────────────────────────────┐
│  外部依赖(Gin / GORM / 第三方库)                      │
└─────────────────────────────────────────────────────────┘
                            ⬇
┌─────────────────────────────────────────────────────────┐
│  Handler 层(internal/handler)                        │
│  - 唯一导入 Gin 的地方                                 │
│  - 解析请求参数,调用 Service                          │
│  - 绝不将 gin.Context 传到下层                        │
└─────────────────────────────────────────────────────────┘
                            ⬇(传递普通结构体)
┌─────────────────────────────────────────────────────────┐
│  Service 层(internal/service)                        │
│  - 纯 Go 业务逻辑,无任何框架导入                      │
│  - 计算耗时、生成拖延标签、进度重算                    │
│  - 依赖 Repository 接口(面向接口编程)                │
└─────────────────────────────────────────────────────────┘
                            ⬇(调用接口)
┌─────────────────────────────────────────────────────────┐
│  Repository 接口(定义在 service 包)                  │
│  - 如:TaskRepository 接口                             │
└─────────────────────────────────────────────────────────┘
                            ⬇
┌─────────────────────────────────────────────────────────┐
│  Repository 实现(internal/repository)                │
│  - 唯一导入 GORM 的地方                               │
│  - 实现 service 层定义的接口                          │
└─────────────────────────────────────────────────────────┘

隔离收益:当 Go 版本升级、GinGORM 升级时,受影响的范围被限制在最外层,核心业务逻辑(service 层)无需修改。


4.2 目录结构

cmd/server/main.go                 # 入口(含 defer 自动备份)

internal/
├── config/                        # 配置加载(Viper)
├── handler/                       # 控制器层
│   ├── task.go                    # 任务 CRUD + 完成/放弃/激活
│   ├── subtask.go                 # 子任务管理
│   ├── stats.go                   # 统计接口
│   └── export.go                  # 导出接口(JSON / CSV / HTML)
├── service/                       # 业务逻辑层(纯 Go,无框架依赖)
│   ├── task.go
│   ├── subtask.go
│   ├── stats.go
│   └── repository.go              # Repository 接口定义在这里
├── repository/                    # 数据访问层(GORM 实现)
│   └── task_repo.go
├── model/                         # 数据模型(GORM 标签)
│   ├── task.go
│   └── subtask.go
└── pkg/                           # 独立工具包
    ├── timeutil/                  # 时间格式化、解析(隔离 time 包变化)
    ├── delaytag/                  # 拖延标签生成(阈值可配置)
    └── backup/                    # 数据库备份/恢复工具

migrations/                        # 迁移脚本
config.yaml                        # 配置文件

4.3 API 接口清单


任务基础接口

方法路径说明
GET/api/v1/tasks任务列表
Querystatustypeall = true(忽略分页),pagepageSize
POST/api/v1/tasks创建任务
Body 含 namestart_timetypeexpected_years可选)
PUT/api/v1/tasks/:id编辑任务
(仅允许修改 name 和 start_time
PATCH/api/v1/tasks/:id/complete完成任务
Body 可含 finish_time,默认当前时间)
PATCH/api/v1/tasks/:id/abandon放弃任务
Body 可含 abandon_reason
PATCH/api/v1/tasks/:id/reactivate重新激活任务
statu s→ active, finish_time → null
DELETE/api/v1/tasks/:id软删除任务
(移入回收站)
DELETE/api/v1/tasks/:id/permanent彻底删除
(物理删除)
GET/api/v1/tasks/trash获取回收站列表
deleted_at IS NOT NULL
PATCH/api/v1/tasks/:id/restore从回收站恢复任务
deleted_at → null

子任务接口


方法路径说明
GET/api/v1/tasks/:id/subtasks获取子任务列表
POST/api/v1/tasks/:id/subtasks新增子任务
PUT/api/v1/subtasks/:sub_id修改子任务
PATCH/api/v1/subtasks/:sub_id/done标记完成/未完成
Body{"done": true}
DELETE/api/v1/subtasks/:sub_id删除子任务

导出接口(数据安全 + 分享)


方法路径说明
GET/api/v1/export?format=json导出完整 JSON(含子任务嵌套),
用于迁移/恢复
GET/api/v1/export?format=csv导出 ZIP 包(内含主任务表子任务表两个 CSV
GET/api/v1/export?format=report导出 HTML 可视化报告(含图表)

统计接口

方法路径说明
GET/api/v1/stats/completion近三月完成率,按月分组,含类型细分

5. 关键业务逻辑实现要点


5.1 软删除与恢复

// 软删除(移入回收站)
db.Delete(&task)  // GORM 自动设置 deleted_at

// 恢复(从回收站恢复)
db.Model(&task).Update("deleted_at", nil)

// 彻底删除
db.Unscoped().Delete(&task)

5.2 进度自动计算(长期任务)

  • 在子任务的 Create/Update/Delete 及 done 状态变更时,事务内触发主任务进度重算:

    progress = (done_count / total_count) * 100
    
  • 若 done_count == total_count && total_count > 0,系统发送提醒(不自动完成)。


5.3 定时备份(反脆弱设计)

  • 启动时:利用 defer 在程序优雅退出时自动备份。
  • 每日凌晨 3 点:自动将 tasks.db 复制到 backup/ 目录,文件名带时间戳。
  • 保留最近 30 个备份,自动清理过期文件。

5.4 导出格式设计

格式结构用途
JSON嵌套结构
(主任务 → 子任务数组)
数据迁移、完整恢复
CSV两个表
(主任务表 + 子任务表),打包为 ZIP
Excel 分析、分享给非技术人员
HTML自包含可视化报告
CSS + ECharts 渲染为图片或纯 CSS
分享给只看结论的人

5.5 依赖隔离检查清单

  • service 层无 import "gorm.io/gorm"

  • service 层无 import "github.com/gin-gonic/gin"

  • 所有 time.Now() 调用统一通过 pkg/timeutil 包调用

  • Repository 接口定义在 service 包,实现在 repository 包


6. 前端设计方案(Vue 3 + Element Plus)


6.1 页面布局

┌──────────────────────────────────────────────────────────┐
│  🔹 任务周期记录     [+ 添加任务]   📊 统计看板           │
│  总任务: 45  完成率: 33%   🔥 拖延中: 12                  │
├──────────────────────────────────────────────────────────┤
│  [📋表格] [📊甘特图] [📌看板] [⏳时间轴]  筛选: [状态▼]   │
├──────────────────────────────────────────────────────────┤
│                                                          │
│                     当前视图内容区域                      │
│                                                          │
└──────────────────────────────────────────────────────────┘

6.2 四个视图的具体实现

视图技术方案核心交互
表格el-table行操作按钮,长期任务显示进度条,短期任务显示拖延标签
甘特图ECharts 自定义条形图X 轴为时间,Y 轴为任务名,进行中的任务条右端延伸到当前时间
看板vue-draggable 三列容器拖拽到 “完成/放弃” 列时调用对应接口,支持从已完成拖回进行中
垂直时间轴el-timeline按开始时间倒序排列,操作按钮折叠进 el-dropdown

6.3 状态管理(Pinia)

store = {
  taskList: [],
  currentView: 'table',  // table | gantt | board | timeline
  filters: { status: '', type: '', keyword: '' },
  stats: { total, completed_rate, monthly: [] }
}

7. 数据安全与备份策略


7.1 三层防御体系

层级方案恢复手段
L1 误删防御GORM 软删除
deleted_at
前端回收站一键恢复
L2 损坏防御定时自动备份
(每日凌晨 + 程序退出时)
替换数据库文件重启
L3 终极防御手动导出 JSON / CSV
/export 接口)
导入重建所有数据

7.2 备份文件管理

  • 备份目录:./backups/
  • 命名规则:tasks_backup_20260727_030000.db
  • 保留策略:仅保留最近 30 个备份,自动清理

8. 配置文件示例(config.yaml)


server:
  port: 8080

database:
  driver: sqlite
  dsn: "./data/tasks.db"

backup:
  enabled: true
  interval_hours: 24          # 备份间隔
  retain_days: 30             # 保留天数
  path: "./backups/"

delay_tags:
  - days: 7
    tag: ""
  - days: 14
    tag: "你是在偷懒么?"
  - days: 28
    tag: "别拖延了!行动起来!"
  - days: 56
    tag: "拖延症犯了吧!!"
  - days: 84
    tag: "你是不是在口嗨?!"
  - days: 112
    tag: "再这样下去这任务你就烂尾了!"
  - days: 168
    tag: "你又画了一个饼..."
  - days: 999
    tag: "你果然在放屁!!!"

export:
  max_tasks: 10000            # 导出最大任务数限制

9. 开发排期(总计约 24 个工作日)


阶段内容工时
1需求梳理、数据库设计、配置规范1
2后端基础 CRUD + 完成/放弃/激活接口2
3子任务模块 + 进度自动计算逻辑2
4拖延标签 + 统计接口1
5软删除 + 回收站接口1
6备份模块 + 导出接口( JSON / CSV / HTML2
7前端脚手架、路由、Pinia 状态2
8表格视图 + 增删改查弹窗2
9甘特图视图(ECharts2
10看板视图(拖拽交互)2
11时间轴视图 + 统计看板图表2
12回收站界面 + 导出功能联调2
13整体联调、测试、修复 Bug3
合计约 24 天

10. 扩展性与未来演进


方向改动范围难度
多用户支持增加 users 表 + JWTtasks 加 user_id
云端同步增加 sync 模块,对接 WebDAV 或云存储 API
移动端适配前端响应式设计 + PWA 支持
邮件/通知提醒增加 cron 任务,检查进行中任务并发送提醒
数据导入反向实现 /import 接口,支持 JSON / CSV 导入

11. 附录:设计决策记录


决策点选择原因
数据库SQLite个人项目,无需独立服务,备份方便
ORMGORM支持软删除、迁移方便,社区活跃
Web 框架Gin轻量,性能好,学习曲线平缓
前端框架Vue 3组合式 API 灵活,Element Plus 组件丰富
时间存储UTC避免时区混乱,展示时转换
备份机制文件复制简单可靠,SQLite 无需复杂备份方案
导出格式JSON / CSV / HTML覆盖数据迁移、分析、展示三种场景

最后一句:这份计划书不是一份 “完美” 的方案,而是一份 “经得起推敲” 的方案。它最大的价值不在于用了什么新技术,而在于在动手之前,把 “可能出什么问题” 和 “出了问题怎么兜底” 这两件事想清楚了

正如那篇文章所说:好的架构方案,往往不需要多复杂的技术手段。它需要的是你在动手之前,多花半天时间想想。