1. 页面概览

1.1 是什么

「项目协作」页面(页面内标题为 Gotham 项目协作,TAD-11)是 LightGotham 的团队分析项目管理页:创建分析项目(如「反洗钱专项」)、管理项目成员角色,以及保存/恢复共享视图(分析上下文 State JSON)。它把「一群人围绕一个分析主题协作」的最小闭环——建项目、拉成员、存视图——集中在一个页面完成。

1.2 核心价值

维度说明
项目列表「我参与的项目」按成员关系过滤,仅展示当前用户参与的项目
成员角色owner/editor/viewer 三级角色;创建者自动成为 owner,写操作需 owner/editor
成员管理添加成员时选角色、移除成员,owner 专属操作
共享视图保存分析上下文(view_type + State JSON),成员可一键「恢复」
归档active 项目可归档(archived),归档后从列表操作列移除归档入口

1.3 一句话总结

建项目、拉成员、存共享视图——Gotham 的协作以项目为边界,以成员角色控制读写,以共享视图传递分析上下文。

2. 访问入口

2.1 路由与菜单

2.2 认证与权限

2.3 端口与 API 前缀

3. 界面布局

页面为「主列表 + 右侧抽屉」布局:

┌──────────────────────────────────────────────────────────────┐
│ Gotham 项目协作 [刷新]                                         │
│ [alert 操作结果提示条(可关闭)]                                │
│ ① 新建项目:项目名称(如 反洗钱专项)/ 项目描述 [创建项目]        │
│ ② 我参与的项目(N)                                            │
│    ID/名称/描述/状态/创建者/操作(详情/成员/共享视图|归档|删除)│
└──────────────────────────────────────────────────────────────┘
  ┌ 抽屉:项目 #id:name [关闭] ─────────────────────┐
  │ 成员管理:用户 ID(注册用户)/ 角色 [添加成员]      │
  │   [搜索已加入成员(渲染层过滤)]                   │
  │   用户 ID/角色/加入时间/移除                      │
  │ 共享视图(恢复分析上下文):视图名称/类型 [保存视图] │
  │   State JSON(可选)                              │
  │   名称/类型/创建人/State/恢复(跳转)/删除          │
  └───────────────────────────────────────────────────┘

4. 交互元素

控件位置含义与作用
「刷新」按钮页头右上重载项目列表
项目名称/描述输入框 + 「创建项目」新建项目卡片名称必填;成功后提示「项目创建成功(id=...,你已自动成为 owner)」并刷新列表
行内「详情 / 成员 / 共享视图」项目列表操作列打开详情抽屉,并行加载成员与共享视图
行内「归档」项目列表操作列仅 active 项目显示;confirm 确认「确认归档项目「name」?」后调用 POST /collab/projects/:id/archive
行内「删除」项目列表操作列所有项目均显示;confirm 中明确说明「软删除(等同归档)、不级联删除任何关联数据、项目仍留在列表」,确认后调用 DELETE /collab/projects/:id
成员表「搜索」输入框抽屉成员管理节渲染层过滤已加载成员(按 user_id 子串,大小写不敏感);后端无用户枚举接口,不能搜索尚未加入的候选用户
「添加成员」抽屉成员管理节输入用户 ID(注册用户)并选角色(editor/viewer/owner)后添加;用户 ID 必填
「移除」成员表操作列confirm 确认「确认移除成员 {user_id}?」后移除
「保存视图」抽屉共享视图节视图名称必填;选择类型(cross_filter/graph/map/timeline/report),State JSON 可空(非法 JSON 自动包成 {raw: 原文}
「恢复」共享视图表操作列解析 State 并提示,同时按 view_type 自动跳转对应分析路由(graph→/gotham、map→/gotham/map、timeline→/gotham/timeline、cross_filter→/gotham/views、report→/gotham/reports),携带 view_id/view_type 查询参数;未知类型仅展示 State 不跳转
「删除」共享视图表操作列confirm 确认「确认删除共享视图「name」?」后删除

5. 后端关联

5.1 API 客户端

5.2 端点表

方法路径说明
GET/collab/projects列出当前用户参与的项目
POST/collab/projects创建项目(创建者自动成为 owner 成员)
GET/collab/projects/:id项目详情
PUT/collab/projects/:id更新项目信息
DELETE/collab/projects/:id删除项目(软删除:状态置 archived,对齐 TAD-11 §4.1 DELETE 语义)
POST/collab/projects/:id/archive归档项目(状态置 archived)
GET/collab/projects/:id/members列出项目成员
POST/collab/projects/:id/members添加成员(body {user_id, role},仅 owner)
DELETE/collab/projects/:id/members/:user_id移除成员(仅 owner)
GET/collab/projects/:id/shared-views列出项目共享视图
POST/collab/projects/:id/shared-views创建共享视图(body {name, view_type, state}
GET/collab/shared-views/:id获取共享视图(恢复分析上下文)
DELETE/collab/shared-views/:id删除共享视图

5.3 响应结构

统一响应体 {code: 0, data: ...}。项目与共享视图示例:

{ "code": 0, "data": [ { "id": 1, "name": "反洗钱专项", "description": "资金链路分析",
  "status": "active", "owner_id": "alice", "created_at": "2026-08-30T..." } ] }
{ "code": 0, "data": { "id": 1, "project_id": 1, "name": "华北情报视图",
  "view_type": "cross_filter", "state": {"filters":[{"field":"region","op":"eq","value":"北京"}]},
  "created_by": "alice" } }

5.4 关键机制

6. 权限与安全

7. 常见问题与排错

问题一:项目列表为空,但项目确实存在

现象:列表页看不到已有项目。原因:列表接口按成员关系过滤,只返回当前用户参与的项目。处理:确认当前登录用户是否是该项目的成员;查看 GET /collab/projects 返回;创建者需先在项目里把自己设为成员(创建时已自动成为 owner)。

问题二:添加成员报「仅项目 owner 可执行该操作」

现象:添加/移除成员被拒绝。原因:当前用户角色为 editor/viewer,成员管理仅限 owner。处理:让 owner 成员执行添加/移除;或在项目中把自己提升为 owner 角色。

问题三:创建项目成功但提示框里没有 id

现象:成功提示未显示项目 id。原因:接口返回体解析异常或网络抖动。处理:刷新项目列表确认是否已出现新项目;用 curl POST /api/v1/collab/projects 复现并检查响应体 {code:0, data:{id}}

问题四:点「恢复」只弹提示,没有跳转到分析页面

现象:点「恢复」后跳转到了分析页面,但上下文未自动还原。原因:「恢复」按 view_type 跳转到对应路由并携带 view_id/view_type 查询参数,目标页面仍以自身查询逻辑为准(State 内容仅完整展示在提示条中,不做跨页状态注入)。处理:查看提示条中的 State JSON,在目标页面按其筛选条件复原上下文;若 view_type 为未知值则不会跳转,仅展示 State。

问题五:保存视图时 State 输入了非法 JSON 但保存成功

现象:非法 JSON 也能保存。原因:前端把非法输入自动包装为 {raw: 原文} 保存,属设计行为。处理:按规范填写 JSON(如 {"filters":[{"field":"region","op":"eq","value":"北京"}]}),非法内容以 raw 形式原样保存,恢复时以原文展示。

8. 已知缺陷与边界

边界说明
项目删除为软删除DELETE /collab/projects/:id 与归档同义(共用 ArchiveProjectcollab/service.go:458):仅置 status=archived,无回收站、无级联删除(成员/任务/评论/共享视图全部保留),项目仍出现在列表中(列表不按状态过滤)。页面已补「删除」入口,确认弹窗与列表说明如实标注该范围
共享视图恢复「恢复」已按 view_type 自动跳转(graph/map/timeline/cross_filter/report → 对应路由,携带 view_id/view_type);未知 view_type 仅展示 State 不跳转
成员即用户(后端缺口)成员按用户 ID(注册用户)添加;后端无用户/成员枚举接口(server.go 无 users 路由),无法提供待添加用户的候选搜索下拉。已补:输入格式校验与提示 + 成员表渲染层搜索(仅过滤已加载成员)。候选枚举需后端新增 /users 类端点
视图类型view_type 选项固定 cross_filter/graph/map/timeline/report,跳转映射以 router/index.js Gotham 子路由为准,不校验 State 内容与页面参数一致
角色变更owner 成员可在成员表行内角色下拉直接改他人角色(PUT 即改);不能修改自己的角色(owner 本人行显示只读徽标)
WebSocket本页不主动建立 WS 连接,实时通知依赖其他页面/协同动态页启动连接
描述截断项目描述列 max-width 220px 超出省略号截断,完整内容需打开详情确认