1. 页面概览
1.1 是什么
「任务看板」页面(页面内标题为 Gotham 任务看板,TAD-11)是 LightGotham 的项目任务协作看板:选择一个「我参与的」项目,把项目内分析任务按 待办 → 进行中 → 审核 → 完成 四列排布,支持卡片拖拽流转、新建/编辑任务、按成员指派负责人并关联图实体。它是项目协作页的延续——项目管「人」,看板管「事」。
1.2 核心价值
| 维度 | 说明 |
|---|---|
| 四列看板 | todo(待办)/ in_progress(进行中)/ review(审核)/ done(完成),每列带任务计数 |
| 拖拽流转 | HTML5 原生拖拽把卡片拖到目标列即调用状态机流转;失败可点卡片按钮兜底 |
| 任务编辑 | 标题/描述/优先级/负责人/关联实体 ID/截止日期,新建与编辑共用抽屉 |
| 负责人指派 | assignee 选项来自项目成员列表,指派后任务状态变更会通知负责人 |
| 状态机约束 | 后端强制 todo→in_progress→review→done(含回退),非法流转返回 409 |
1.3 一句话总结
2. 访问入口
2.1 路由与菜单
- 路由:
/gotham/tasks;路由名称:GothamTasks - 路由 meta:
title: Gotham 任务看板,requiresAuth: true,挂在父路由/gotham(GothamLayout)下 - 菜单位置:Gotham 左侧边栏「协作工作流」分组下的「任务看板」
- 前端源码:
action/web/src/views/GothamTasksPage.vue - API 客户端:
action/web/src/api/gothamClient.js
2.2 认证与权限
- 路由挂
requiresAuth: true,未登录访问被全局守卫重定向到/login。 - 请求走 gothamClient:请求拦截器自动附带
Authorization: Bearer <aip_token>;响应拦截器遇 401 时用gotham_refresh_token换发新 token 并重放原请求。 - 后端 collab 服务按成员角色鉴权:读任务需项目成员,写任务(创建/流转/编辑/删除)需 owner/editor。
2.3 端口与 API 前缀
- Gotham 后端端口:18083(Vite 将
/gotham-api前缀代理到该端口并重写为/api/v1)。 - API 前缀:
/gotham-api/v1(gothamClient 的 baseURL)。
3. 界面布局
页面为「顶部选择栏 + 四列看板」布局:
┌──────────────────────────────────────────────────────────────┐
│ Gotham 任务看板 [选择项目▾] [刷新] [新建任务] │
│ [alert 操作结果提示条(可关闭)] │
│ ┌ 待办(2) ┐ ┌ 进行中(1) ┐ ┌ 审核(0) ┐ ┌ 完成(3) ┐ │
│ │ [任务卡] │ │ [任务卡] │ │ │ │ [任务卡] │ │
│ │ 标题 │ │ 标题 │ │ 拖拽任务 │ │ 标题 │ │
│ │ 优先级@人 │ │ 优先级@人 │ │ 到此列 │ │ 优先级@人 │ │
│ │ 编辑置为..│ │ 编辑置为.. │ │ │ │ 编辑置为..│ │
│ │ 删除 │ │ 删除 │ │ │ │ 删除 │ │
│ └─────────┘ └──────────┘ └─────────┘ └─────────┘ │
└──────────────────────────────────────────────────────────────┘
┌ 任务编辑抽屉:新建任务 / 编辑任务 [关闭] ────────┐
│ 标题 */描述/优先级/负责人/关联实体 ID/截止日期 │
│ [创建任务|保存修改] │
└──────────────────────────────────────────────────┘
- 顶部选择栏:项目下拉 + 「刷新」+「新建任务」(未选项目时禁用)。
- 四列看板:每列列头为状态名 + 计数;未选项目时整块显示「请先选择项目加载任务看板。」
- 任务卡片:标题、优先级徽标、负责人
@id,下方「编辑/置为{状态}/删除」按钮。 - 编辑抽屉:右侧滑出,新建与编辑共用表单。
4. 交互元素
| 控件 | 位置 | 含义与作用 |
|---|---|---|
| 项目下拉「选择项目」 | 页头左侧 | 列出「我参与的」项目(#id 名称),切换即加载该项目的任务与成员 |
| 「刷新」按钮 | 页头 | 重载项目、任务与成员列表 |
| 「新建任务」按钮 | 页头 | 打开任务编辑抽屉(未选项目时置灰) |
| 任务卡片(拖拽) | 看板 | HTML5 拖拽到目标列后调用状态流转接口;目标列拖入时高亮(col-over) |
| 「置为{状态}」按钮 | 卡片操作列 | 拖拽失败兜底:按 todo→in_progress→review→done 逐级前移一格;无去向时提示「当前状态无可流转去向」 |
| 「编辑」 | 卡片操作列 | 打开编辑抽屉并回填任务字段 |
| 「删除」 | 卡片操作列 | confirm 确认「确认删除任务「title」?」后删除 |
| 编辑抽屉表单 | 抽屉 | 标题 *、描述、优先级(high/medium/low)、负责人 assignee(选项来自项目成员,含「(未分配)」)、关联实体 ID(逗号分隔)、截止日期(date) |
| 「创建任务」「保存修改」 | 抽屉底部 | 提交创建/更新;标题必填;成功后提示「任务已创建/任务已更新」并关闭抽屉 |
5. 后端关联
5.1 API 客户端
- 文件:
action/web/src/api/gothamClient.js;baseURL/gotham-api/v1,超时 30000ms。 - 加载任务与成员并行(
Promise.allSettled),单个失败不阻断另一个;统一响应体{code: 0, data: ...}。
5.2 端点表
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /collab/projects | 项目列表(我参与的,下拉选项来源) |
| GET | /collab/projects/:id/tasks | 列出项目任务(支持 status/assignee_id 过滤) |
| POST | /collab/projects/:id/tasks | 创建任务 |
| GET | /collab/tasks/:id | 任务详情 |
| PUT | /collab/tasks/:id | 更新任务 |
| DELETE | /collab/tasks/:id | 删除任务 |
| POST | /collab/tasks/:id/transition | 任务状态流转,body {to} |
| GET | /collab/projects/:id/members | 项目成员列表(负责人下拉选项来源) |
5.3 响应结构
统一响应体 {code: 0, data: ...}。任务记录示例:
{ "code": 0, "data": [ { "id": 1, "project_id": 1, "title": "核实北京大额转账",
"description": "关联张远账户", "status": "in_progress", "priority": "high",
"assignee_id": "alice", "related_entity_ids": "[\"graph:person:zhangyuan\"]",
"due_date": "2026-09-10T00:00:00Z", "created_by": "alice" } ] }
5.4 关键机制
- 任务状态机:后端
taskTransitions:todo→in_progress→review→done 主线,含 in_progress→todo、review→in_progress 回退;done 为终态。非法流转返回 409(GOTHAM_COLLAB_INVALID_TRANSITION)。前端拖拽可拖到任意列,后端拒绝时报「流转失败:{err}(状态机 todo→in_progress→review→done)」;「置为{状态}」按钮只前移一格。 - 任务字段:title/description/priority(low|medium|high,缺省 medium)/assignee_id(须为项目成员)/related_entity_ids(JSON 数组字符串,前端按逗号拆分)/due_date(前端拼
T00:00:00Z提交)。 - 通知联动:状态流转写 Activity(
task_moved)并给负责人发task_status通知;指派任务时发task_assigned通知,均经 ws.Hub 实时推送。 - 本地乐观更新:拖拽流转成功后直接改本地任务状态(
t.status = toStatus)再提示,无需整表刷新。
6. 权限与安全
- 认证:全部
/collab/*端点位于 protected 组,JWT 无效一律 401,前端自动刷新/跳登录。 - 项目级隔离:任务读取/流转要求项目成员,写操作要求 owner/editor(requireWrite),非成员 403。
- 写操作防护:删除任务经
window.confirm二次确认;流转操作即时生效,误拖可再拖回(允许回退路径内)。 - 负责人校验:assignee_id 选项来自项目成员列表,后端会校验负责人是项目成员,避免指派外部用户。
7. 常见问题与排错
问题一:拖拽任务到另一列后报「流转失败」
现象:拖拽后出现红色错误提示。原因:跨过了非法的状态(如 done 拖回 todo,或跳过中间态回退超范围)。处理:用卡片「置为{状态}」按钮按 todo→in_progress→review→done 逐格流转;或先拖回合法前置状态再前进。
问题二:「置为{状态}」按钮提示「当前状态无可流转去向」
现象:点击置为按钮无效果。原因:任务已是 done(终态)或当前状态无前移去向。处理:done 任务不可再流转,需要修改请点「编辑」;如误置可把另一张任务作对照,确认状态机语义。
问题三:新建任务后看板列里没有出现该任务
现象:创建成功但卡片未出现。原因:创建成功但 loadTasks 未刷新成功,或项目选错了。处理:点「刷新」重载;确认当前项目下拉选中的项目与创建时一致;用 GET /api/v1/collab/projects/{id}/tasks 直接查询。
问题四:负责人下拉为空,只有「(未分配)」
现象:assignee 无选项。原因:项目还没有成员(除 owner 外),或成员加载失败。处理:到「项目协作」页添加成员后返回刷新;查看网络请求中 /members 是否 200。
问题五:关联实体 ID 填了逗号分隔的多项,保存后只显示一项
现象:回填时关联实体缺失。原因:前端按逗号拆分后提交 related_entity_ids 数组,编辑回填时以 , 连接展示。处理:确认输入无全角逗号(应为半角 ,);保存后重新打开编辑抽屉检查回填。
8. 已知缺陷与边界
| 边界 | 说明 |
|---|---|
| 状态机 | 前端拖拽不做本地预校验,依赖后端 409 拒绝 |
| 卡片列表 | 任务按项目全量加载,无分页;项目任务量大时页面卡顿风险 |
| 关联实体 | related_entity_ids 为纯文本 JSON 数组,前端不校验格式与图节点是否存在 |
| 截止日期 | 前端 date 输入拼 T00:00:00Z 提交,后端不强制校验逾期 |
| 乐观更新 | 拖拽成功后本地改状态,若后端实际失败但响应异常时可能出现状态不一致(需刷新校正) |
| WebSocket | 本页不主动建立 WS 连接,任务通知依赖后端推送,需其他页面/协同动态页建立连接后可见 |
| 拖拽依赖 | 卡片流转依赖 HTML5 拖放 API,触屏设备拖拽体验有限,建议用「置为」按钮兜底 |
注:「置为」done 列按钮与空列「新建到此列」已于 2026-09-06 修复(done 列按钮修正,列头新建并预填状态)。