Files
Hua.Todo/docs/project/研发工单-v1.3.0/03-04-任务建议与确认UI.md
ShaoHua 9223ceca50 feat(mcp): 新增 MCP 服务基础设施,重构规则文件序号,新增 v1.3.0 工单文档
- 规则重组:全局/ 下 8 个规则合并为 6 个(01+02→01,05+06→04),序号顺延

- 新增项目规则 05-多入口功能同步规范(UI/语音入口覆盖检查)

- 新增 MCP 服务基础设施:Mcp/ 目录(DI 注册、端点扩展、动态工具描述符)、单元测试

- v1.3.0 工单文档:03 系列(会议任务拆分)、04(富文本描述与附件管理)

- MCP 接口与前端集成指南:docs/manual/08、09
2026-06-16 01:15:40 +08:00

11 KiB
Raw Permalink Blame History

研发工单 v1.3.0 - 03-04 任务建议与确认 UI

父工单:03-会议任务拆分

依赖:03-01、03-03(后端 API 就绪)


一、目标

实现会议任务拆分的完整前端 UI:在 TaskItem 中为 Meeting 类型待办项提供录音/纪要/拆分入口,实现建议审阅与确认对话框,打通从会议内容输入到批量创建子任务的端到端用户体验。

二、范围

包含

  • Meeting 类型待办项的特殊 UI(图标、录音/纪要/拆分入口)
  • 录音控件的嵌入(调用 03-02 的 AudioRecorder.vue + useAudioRecorder
  • 纪要输入区域(textarea 保存会议文字内容)
  • AI 拆分请求与加载状态
  • 建议审阅对话框(MeetingBreakdownDialog.vue
  • 建议勾选、编辑、调整优先级、手动补充
  • 确认后批量创建子任务
  • 前端类型扩展(taskTypemeetingNotesaudioDuration

不包含

  • 录音控件本身(由 03-02 提供)
  • 后端逻辑(由 03-01、03-03 提供)

三、前置条件

条件 说明
03-01 完成 后端 API 就绪(meeting 端点 + TaskType
03-02 完成 AudioRecorder 组件和 useAudioRecorder 可用
03-03 完成 breakdown/breakdown/confirm 端点可用

四、详细规格

4.1 前端类型扩展

// src/Hua.Todo.Web/src/types/task.ts

/// <summary>待办项类型</summary>
type TaskType = 0 | 1; // 0=Normal, 1=Meeting

interface Task {
  // ... 已有字段 ...
  /** 待办项类型 */
  taskType?: TaskType;
  /** 会议纪要/转写文字 */
  meetingNotes?: string;
  /** 录音时长(秒) */
  audioDuration?: number;
}

interface CreateTaskDto {
  title: string;
  priority: TaskPriority;
  parentTaskId?: number;
  /** 待办项类型,默认 0 */
  taskType?: TaskType;
}

4.2 会议相关类型

// 新增或扩展 meeting.ts 中的类型

/// <summary>会议任务拆分建议</summary>
interface MeetingTaskSuggestion {
  title: string;
  priority: TaskPriority;
  reason: string;
}

/// <summary>拆分响应</summary>
interface BreakdownResponse {
  taskId: number;
  suggestions: MeetingTaskSuggestion[];
}

/// <summary>待确认的子任务项</summary>
interface PendingSubTask {
  title: string;
  priority: TaskPriority;
  /** 是否被用户勾选 */
  checked: boolean;
  /** LLM 拆分的原始建议(含原因) */
  suggestion?: MeetingTaskSuggestion;
  /** 是否为用户手动添加的条目 */
  isManual?: boolean;
}

4.3 TaskItem.vue 扩展

为 Meeting 类型的待办项显示额外操作入口:

┌──────────────────────────────────────────────┐
│ 📋 ☐ 周一产品评审会           🔴 H     ···   │
│     🎙 会议 · 📝 有纪要 · 0个子任务             │
│                              [🎤] [📝] [🤖]  │
│    ┌─ ✅ 整理需求文档    🔴                  │  ← 已有子任务(若有)
│    └─ ☐ 安排评审会议    🟡                  │
└──────────────────────────────────────────────┘

[🎤] = 录音按钮
[📝] = 打开纪要编辑区
[🤖] = AI 拆分(需有会议内容)

条件渲染逻辑:

  • task.taskType === 1Meeting)时,显示会议图标 🎙 标签
  • 显示三个操作按钮在任务行右侧
  • 拆分子任务入口:点击 [🤖] → 触发 handleAiBreakdown()

4.4 会议纪要编辑区(内联)

点击 [📝] 后展开内联编辑区:

┌──────────────────────────────────────────────┐
│ 📋 ☐ 周一产品评审会                           │
│                                              │
│  会议纪要:                                   │
│  ┌──────────────────────────────────────┐    │
│  │ 今天的产品评审会主要讨论了三个议题:    │    │
│  │ 第一,确定 Q3 产品路线图...           │    │
│  │ 第二,...                            │    │
│  │                                      │    │
│  └──────────────────────────────────────┘    │
│  录音时长:30分15秒                           │
│                                              │
│  [🔊 开始录音]  [🤖 AI拆分]  [💾 保存纪要]   │
└──────────────────────────────────────────────┘

4.5 AI 拆分流程(前端)

// 在 TaskItem.vue 或拆分逻辑中

async function handleAiBreakdown(task: Task) {
    // 1. 检查是否有会议内容
    if (!task.meetingNotes) {
        showToast('请先输入纪要或上传录音', 'warning');
        return;
    }

    // 2. 调用 AI 拆分
    isLoading.value = true;
    try {
        const resp = await meetingApi.requestBreakdown(task.id);
        if (resp.data.suggestions.length === 0) {
            showToast('未从会议内容中提取到待办项,请确认纪要内容', 'info');
            return;
        }

        // 3. 打开审阅对话框
        openBreakdownDialog(task, resp.data.suggestions);
    } catch (err) {
        showToast('AI拆分失败,请稍后重试', 'error');
    } finally {
        isLoading.value = false;
    }
}

4.6 MeetingBreakdownDialog.vue

审阅确认对话框:

┌──────────────────────────────────────────────┐
│  会议任务拆分 — 周一产品评审会          [✕]   │
│                                              │
│  AI 根据会议内容生成了以下待办项建议:         │
│  请勾选需要创建的条目,可编辑标题和优先级。     │
│                                              │
│  ┌──────────────────────────────────────┐    │
│  │ ☑ 整理产品需求文档     [🔴 高 ▼]     │    │
│  │   📝 会议中提到需要在本周五前完成     │    │
│  │                                      │    │
│  │ ☑ 安排技术方案评审     [🟡 中 ▼]     │    │
│  │   📝 张三负责在下周三前输出技术方案   │    │
│  │                                      │    │
│  │ ☑ 跟进客户反馈         [🟢 低 ▼]     │    │
│  │   📝 李四反馈了三个客户问题          │    │
│  │                                      │    │
│  │ ☐ 项目总结报告         [🟡 中 ▼]     │    │
│  │   📝 月末需要汇总各模块进度          │    │
│  └──────────────────────────────────────┘    │
│                                              │
│  [+ 手动添加待办项]                          │
│                                              │
│  已选 3 项                                  │
│  [取消]                    [✅ 确认创建 (3)] │
└──────────────────────────────────────────────┘

交互:

  • 每条建议默认勾选
  • 点击标题可编辑(内联 input
  • 优先级下拉可调整
  • 取消勾选的条目不会被创建
  • [+ 手动添加] 新增空白条目
  • 底部显示已选数量

4.7 确认创建

async function confirmBreakdown() {
    const selected = pendingSubTasks.value
        .filter(s => s.checked)
        .map(s => ({ title: s.title, priority: s.priority }));

    if (selected.length === 0) {
        showToast('请至少选择一个待办项', 'warning');
        return;
    }

    isCreating.value = true;
    try {
        const resp = await meetingApi.confirmBreakdown(task.id, selected);
        showToast(`已成功创建 ${resp.data.createdCount} 个待办项`, 'success');
        closeDialog();
        emit('updated'); // 刷新任务列表
    } catch (err) {
        showToast('创建失败,请重试', 'error');
    } finally {
        isCreating.value = false;
    }
}

4.8 创建任务时的类型选择

TaskList.vue 的快速创建表单中增加类型选择:

┌──────────────────────────────────────────────┐
│ [+ 新待办项]  [_____输入标题_____]           │
│  优先级: [🟡 中 ▼]  类型: [📋 普通 ▼]       │
│              [🎙 会议]                        │
│  [+ 添加]                                    │
└──────────────────────────────────────────────┘

默认类型为 Normal(普通),选择 Meeting 后创建的待办项为会议类型。

五、验收标准

验收项 验证方法 预期结果
创建 Meeting 类型 新建时选择"会议"类型 列表中显示 🎙 图标
会议操作按钮 展开 Meeting 类型任务 显示录音/纪要/拆分三个按钮
普通类型不显示 查看普通待办项 无会议相关按钮
录音入口 点击录音按钮 弹出/展开 AudioRecorder 组件
纪要编辑 输入会议纪要后保存 meetingNotes 保存成功
AI 拆分请求 点击 AI 拆分按钮 加载状态 → 审阅对话框弹出
无内容拒绝拆分 无纪要时点击拆分 提示"请先输入纪要"
建议审阅 审阅对话框中勾选/取消/编辑 操作流畅,状态正确
手动添加 点击"+ 手动添加" 新增空白条目,可编辑
批量创建 确认勾选的条目 子任务创建到父任务下
离线降级提示 离线时点击拆分 提示"AI 拆分仅在线可用"
响应式 缩小浏览器窗口 对话框和控件正常显示

六、风险

风险 影响 应对
组件嵌套复杂 TaskItem 已有子任务递归,再加会议 UI 后层级深 会议功能用可选插槽方式注入,不影响普通任务渲染
录音与拆分同时操作 用户可能在转写期间又点拆分 操作按钮在加载中时禁用
大量建议渲染 LLM 返回 10+ 条建议时列表长 审阅列表设最大高度 + 滚动;建议上限 15 条

七、Touch List

文件路径 修改类型
src/Hua.Todo.Web/src/types/task.ts 修改(新增 TaskType、meetingNotes、audioDuration
src/Hua.Todo.Web/src/api/meeting.ts 新增
src/Hua.Todo.Web/src/components/AudioRecorder.vue 新增(由 03-02 产出,本工单集成)
src/Hua.Todo.Web/src/components/MeetingBreakdownDialog.vue 新增
src/Hua.Todo.Web/src/components/TaskItem.vue 修改(Meeting 类型条件渲染)
src/Hua.Todo.Web/src/components/TaskList.vue 修改(新建任务时类型选择)

工单编号03-04 标题:任务建议与确认 UI 版本v1.3.0 创建日期2026-06-16