---
title: 开发任务模块（DevTask）设计规格
date: 2026-06-11
module: dev-task
status: approved
---

# 开发任务模块（DevTask）— 设计规格

## 1. 定位与层级

DevTask 是"执行层"实体，归属于版本下某条需求，代表一个可分配、可追踪工时的开发工作项。

```
Version（版本）
├── VersionPlan（计划层：调研/产品/UI）← 已有
├── DevTask（执行层：开发任务）← 本文档
│   └── 归属于 Requirement（需求）
│       └── TaskWorklog（工时记录）
└── TestCase / Bug（后续）
```

### 归属关系

- DevTask **必须**归属于一条需求（`requirementId` 必填）
- `versionId` 从需求推导，不冗余存储
- 通过 `Requirement → Version` 链路追溯到版本和产品

## 2. 数据模型

### 2.1 DevTask（开发任务）

```typescript
interface DevTask {
  id: string;
  taskNo: string;              // 自动生成，DEV-001、DEV-002...

  requirementId: string;       // 所属需求（必填）

  title: string;
  description?: string;

  categoryId: string;          // 任务类型（字典表 TaskCategory）
  assigneeId: string;          // 负责人
  reviewerId?: string;         // 验收人（预留，V1 可选不填）
  priority: 'P0' | 'P1' | 'P2' | 'P3';  // 默认继承需求优先级，允许覆盖

  estimateHours: number;       // 预计工时（小时）
  actualHours: number;         // 实际工时（只读，= Σ TaskWorklog.hours）

  startDate?: string;          // 开始日期 YYYY-MM-DD
  dueDate?: string;            // 截止日期 YYYY-MM-DD
  completedAt?: string;        // 完成日期 YYYY-MM-DD

  status: DevTaskStatus;
  isBlocked: boolean;          // 阻塞标记（正交于 status）
  blockReason?: string;        // 阻塞原因
  blockedById?: string;        // 造成阻塞的任务 ID（可选）

  predecessorIds?: string[];   // 前置任务 ID 列表

  riskLevel?: 'low' | 'medium' | 'high';  // 系统计算字段，不可手动编辑

  createdBy: string;
  createdAt: string;
  updatedAt: string;
}

type DevTaskStatus = 'todo' | 'in_progress' | 'testing' | 'submitted' | 'done';
```

### 2.2 TaskWorklog（工时记录）

```typescript
interface TaskWorklog {
  id: string;
  taskId: string;              // 所属 DevTask
  userId: string;              // 登记人
  date: string;                // YYYY-MM-DD
  hours: number;               // 当日投入小时数
  workContent: string;         // 工作内容（必填，为日报系统提供数据源）
  createdAt: string;
}
```

- DevTask.actualHours = 该任务下所有 TaskWorklog.hours 的累加
- actualHours 字段只读，不允许直接编辑
- workContent 必填，格式示例："完成排班页面基础布局"、"对接排班接口"
- V2 与加班记录、日报模块打通，统一为"工时记录中心"
- 日报可直接聚合当日 workContent 生成：`排班页面布局（4h）+ 接口联调（2h）= 6h`

### 2.3 TaskCategory（任务类型字典）

```typescript
interface TaskCategory {
  id: string;
  name: string;                // 显示名称
  group: 'development' | 'testing' | 'implementation' | 'other';  // 分组，用于报表统计
  color?: string;              // 图表配色
  sortOrder: number;           // 排列顺序
  isSystem: boolean;           // 系统预置不可删除
}
```

系统预置值：

| 名称 | 分组 | 说明 |
|------|------|------|
| 前端开发 | development | Web/移动端页面 |
| 后端开发 | development | API/服务层 |
| 数据库设计 | development | 表结构/迁移 |
| 接口联调 | development | 前后端对接 |
| 测试验证 | testing | 测试执行 |
| 缺陷修复 | testing | Bug 修复 |
| 数据处理 | implementation | ETL/数据清洗 |
| 实施支持 | implementation | 部署/实施 |

管理员可在"系统管理"中增删自定义类型。

## 3. 状态机

```
todo → in_progress → testing → submitted → done
                ↑         │          │
                └─────────┘          │
                ↑                    │
                └────────────────────┘
```

| 状态 | 含义 | 推导进度 |
|------|------|---------|
| todo | 待开发 | 0% |
| in_progress | 开发中 | 50% |
| testing | 自测 | 80% |
| submitted | 提测 | 90% |
| done | 已完成 | 100% |

### 状态流转规则

正向流转：

- todo → in_progress → testing → submitted → done

允许回退（有限）：

- testing → in_progress（自测发现需要返工）
- submitted → in_progress（测试打回）

禁止回退：

- done → 任何状态（完成是终态，返工走新任务或 Bug）
- todo → 非 in_progress（不能跳级）

回退时记录操作日志（操作人、时间、原因）。

## 4. 阻塞设计（正交标记）

阻塞不是状态枚举值，而是叠加在任何状态之上的标记：

| 字段 | 类型 | 说明 |
|------|------|------|
| isBlocked | boolean | 是否被阻塞 |
| blockReason | string? | 阻塞原因描述 |
| blockedById | string? | 造成阻塞的任务 ID |

示例场景：

- `status=in_progress + isBlocked=true`：开发中但等后端接口
- `status=testing + isBlocked=true`：自测发现问题等需求确认
- `status=todo + isBlocked=true`：依赖的前置任务未完成

工作台筛选 `isBlocked=true` 可一键拉出所有阻塞项。

## 5. 进度计算规则

### 5.1 单任务进度

由 status 推导（见状态机表），不设人工填写的百分比字段。

### 5.2 需求级开发进度

```
需求开发进度 = Σ(任务.estimateHours × 任务状态推导进度) / Σ(任务.estimateHours)
```

示例：

| 任务 | 预计工时 | 状态 | 推导进度 | 加权 |
|------|---------|------|---------|------|
| 排班界面 | 16h | done | 100% | 16 |
| 排班规则组件 | 8h | in_progress | 50% | 4 |
| 排班算法接口 | 24h | todo | 0% | 0 |

需求进度 = (16 + 4 + 0) / (16 + 8 + 24) = 20 / 48 = **41.7%**

### 5.3 版本开发进度

```
版本开发进度 = Σ(版本下所有 DevTask.estimateHours × 状态推导进度) / Σ(estimateHours)
```

### 5.4 工时投入展示（辅助指标，不参与进度）

```
工时投入比 = Σ actualHours / Σ estimateHours
```

展示为：`已投入 32h / 预计 56h (57%)`

用途：工时偏差分析、健康度评估、加班趋势关联。

## 6. 工时展示规则

存储单位始终为**小时(h)**。展示时自动转换：

| 值 | 展示 |
|---|---|
| 4h | 4h |
| 8h | 8h（1人天） |
| 16h | 16h（2人天） |
| 24h | 24h（3人天） |

转换规则：`1人天 = 8h`，仅当 ≥ 8h 时附带人天标注。

## 7. 优先级继承

```
Requirement.priority = P1
    ↓ 创建任务时默认继承
DevTask.priority = P1（可覆盖为 P0/P2/P3）
```

UI 行为：创建任务弹窗中，优先级字段预填为需求优先级，允许手动修改。

## 8. 前置任务（依赖）

| 字段 | 说明 |
|------|------|
| predecessorIds | string[]，前置任务 ID 列表 |

V1 功能范围：

- 创建/编辑时可选择同版本内的其他 DevTask 作为前置
- 详情页展示前置任务列表，可跳转
- 前置任务未完成时，系统不阻止本任务开始（仅展示提示）

V2 扩展：

- 甘特图依赖线
- 关键路径计算
- 自动阻塞提醒

## 9. 风险等级（系统自动计算，不可手动编辑）

V1 预留 `riskLevel` 字段，由系统自动计算，UI 上不提供手动编辑入口。

V2 自动规则：

| 条件 | 风险等级 |
|------|---------|
| actualHours > estimateHours × 1.5 | high |
| today > dueDate 且 status ≠ done | high |
| isBlocked 持续超过 2 天 | high |
| actualHours > estimateHours × 1.2 | medium |
| today > dueDate - 3天 | medium |
| 其他 | low |

风险逐层汇总：任务 → 需求 → 版本 → 项目，与已有 `version.riskLevel` 计算保持一致。

设计原则：风险等级反映客观数据，不允许人为干预（避免"明明很危险但负责人填低风险"）。

## 10. "与我相关"统一聚合层

### 10.1 统一工作项模型（锁定契约）

所有可分配实体必须遵守以下统一语义，新增实体类型时不得打破此契约：

```typescript
type WorkItem = {
  entityType: 'plan' | 'devTask' | 'testCase' | 'bug';
  entityId: string;
  title: string;
  status: string;
  isBlocked?: boolean;
  assigneeId: string;          // 必须：负责人
  reviewerId?: string;         // 可选：验收人
  versionId: string;           // 必须：从各实体推导
  versionName?: string;
  priority?: string;           // 必须：优先级
  dueDate?: string;            // 必须：截止日期
  categoryLabel?: string;      // 任务类型名称
};
```

未来新增实体（发布任务、实施任务、运维任务等）只需实现此接口，即可自动接入工作台，无需修改聚合逻辑。

### 10.2 工作台分组

左侧导航扩展：

| 分组 | 数据来源 | 状态 |
|------|---------|------|
| 全部待办 | 所有 entityType | — |
| 调研 | VersionPlan(type=research) | 已有 |
| 产品方案 | VersionPlan(type=product) | 已有 |
| UI设计 | VersionPlan(type=ui) | 已有 |
| 开发任务 | DevTask | 本次新增 |
| 测试/Bug | TestCase + Bug | 后续 |

### 10.3 右侧状态视图

按状态分列展示：

- 待处理（todo / pending）
- 进行中（in_progress）
- 阻塞（isBlocked = true，跨所有状态）
- 待验收（testing / submitted）

### 10.4 联动规则

- 创建 DevTask 并指定 assigneeId → 自动出现在该成员"与我相关"
- 变更 assigneeId → 从原负责人工作台移除，加入新负责人工作台
- 状态变更 → 自动在工作台内移动列

## 11. 与加班模块的关系

已有加班记录存储小时数。未来数据链路：

```
TaskWorklog（任务工时）
    ↓ 当日工时 > 8h 部分
OvertimeRecord（加班记录）
    ↓ 按月汇总
加班统计仪表盘
```

V1 两个模块独立运行。V2 建立工时 → 加班自动关联。

## 12. 涉及新增文件（预估）

| 路径 | 说明 |
|------|------|
| `apps/web/lib/dev-task.ts` | DevTask 类型定义 + 进度计算函数 |
| `apps/web/lib/task-worklog.ts` | TaskWorklog 类型 + 聚合函数 |
| `apps/web/lib/task-category.ts` | TaskCategory 类型 + 预置数据 |
| `apps/web/stores/useDevTaskStore.ts` | DevTask 状态管理（localStorage V1） |
| `apps/web/stores/useTaskWorklogStore.ts` | 工时记录状态管理 |
| `apps/web/components/dev-task/` | DevTask 相关组件目录 |
| `apps/web/app/versions/[id]/` | 版本详情页 DevTask Tab |

## 13. 不在本次范围

- 甘特图依赖线渲染
- 风险等级自动计算
- 工时 → 加班自动关联
- 测试用例 / Bug 模块
- 后端 API 实现（V1 全部 localStorage）
