Files
happy-life-star/docs/superpowers/specs/2026-07-22-clarification-card-option-switching-fix-design.md
T

7.0 KiB
Raw Blame History

author, created_at, purpose
author created_at purpose
AI Assistant 2026-07-22 修复 ClarificationCard 选项无法切换的 bug

ClarificationCard 选项切换修复设计

问题概述

现象

在"心愿实现"页面(生成剧本页面),当后端返回澄清卡片(clarification_card 事件)时,用户在选项卡中选择了一个选项后,无法切换到其他选项。

根本原因

ClarificationCard.vue 组件的 toggleOption 函数(第 80-95 行)依赖 card_type 字段判断是单选还是多选:

function toggleOption(opt) {
  const value = opt.value
  if (isSingle.value) {  // 仅当 card_type === 'single_select' 时执行
    selectedValues.value = [value]
  } else if (isMulti.value) {  // 仅当 card_type === 'multi_select' 或 'mixed' 时执行
    // 多选逻辑...
  }
  // 如果 card_type 不是上述任何值,函数什么都不做!
}

关键问题:如果后端返回的 card.card_type 不是 'single_select''multi_select''mixed'(可能是 undefinednull 或其他未定义的值),toggleOption 函数不会执行任何逻辑,导致:

  • 用户点击选项 A → selectedValues 不更新
  • 用户点击选项 B → selectedValues 仍不更新
  • 视觉上表现为"无法切换选项"

代码位置

文件: mini-program/src/components/ClarificationCard.vue:80-95

设计目标

  1. 选项可自由切换:无论 card_type 是什么值,用户都能正常切换选项
  2. 保持现有功能:不破坏单选、多选、文本输入的现有行为
  3. 向后兼容:对于正常的 card_type 值(single_selectmulti_selecttext_input),行为保持不变
  4. 不破坏其他业务功能:不修改 ScriptView.vue 或后端代码

技术方案

方案:增强 toggleOption 容错性

核心思路:将条件判断从"是否为单选"改为"是否为多选或文本输入",如果都不是则默认当作单选处理。

修改位置: mini-program/src/components/ClarificationCard.vue:80-95

修改前的代码:

function toggleOption(opt) {
  const value = opt.value
  if (isSingle.value) {
    selectedValues.value = [value]
  } else if (isMulti.value) {
    const idx = selectedValues.value.indexOf(value)
    if (idx >= 0) {
      selectedValues.value.splice(idx, 1)
    } else {
      const maxSel = props.card.max_selections || selectedValues.value.length + 1
      if (selectedValues.value.length < maxSel) {
        selectedValues.value.push(value)
      }
    }
  }
}

修改后的代码:

function toggleOption(opt) {
  const value = opt.value
  // 修复:默认当作单选处理(当不是多选也不是文本输入时)
  if (isMulti.value) {
    // 多选逻辑
    const idx = selectedValues.value.indexOf(value)
    if (idx >= 0) {
      selectedValues.value.splice(idx, 1)
    } else {
      const maxSel = props.card.max_selections || selectedValues.value.length + 1
      if (selectedValues.value.length < maxSel) {
        selectedValues.value.push(value)
      }
    }
  } else if (!isTextInput.value) {
    // 单选逻辑(默认行为,包括 card_type 未定义或未知的情况)
    selectedValues.value = [value]
  }
}

关键变更:

  • if (isSingle.value) 改为 else if (!isTextInput.value)
  • 这意味着:只要不是多选(isMulti.value)也不是文本输入(isTextInput.value),就当作单选处理
  • 这样即使 card_typeundefinednull 或其他未定义的值,选项也能正常切换

保留的多选逻辑:

  • 多选条件(isMulti.value)保持不变
  • 多选逻辑(添加/删除选项)保持不变
  • 最大选择数限制(max_selections)保持不变

保留的文本输入逻辑:

  • 文本输入卡片(isTextInput.value)不会有选项,所以 toggleOption 不会被调用
  • 但保留这个判断是为了代码的可读性和未来的扩展性

行为对照表

card_type 值 修改前行为 修改后行为
'single_select' 单选切换 单选切换(行为不变)
'multi_select' 多选切换 多选切换(行为不变)
'mixed' 多选切换 多选切换(行为不变)
'text_input' 无选项,不调用 无选项,不调用(行为不变)
undefined / null 无法切换 默认单选切换
其他未知值 无法切换 默认单选切换

实施步骤

第一步:修改 ClarificationCard.vue

打开 mini-program/src/components/ClarificationCard.vue,定位到第 80-95 行的 toggleOption 函数,将其修改为上述"修改后的代码"。

第二步:构建小程序

cd mini-program
npm run build:mp-weixin

预期输出:DONE Build complete.

第三步:提交修改

git add mini-program/src/components/ClarificationCard.vue
git commit -m "fix: 修复 ClarificationCard 选项无法切换的 bug(增强 toggleOption 容错性)"

第四步:用户验证

在微信小程序中:

  1. 进入"心愿实现"页面
  2. 输入心愿文本,触发澄清卡片
  3. 点击选项 A(应该被选中)
  4. 点击选项 B(应该切换到 B,A 取消选中)
  5. 再次点击选项 A(应该切换回 A
  6. 验证:选项可以自由切换

风险评估

风险 1:影响现有正常的卡片类型

可能性:低

缓解措施

  • 修改前的行为对照表显示,所有正常的 card_type 值行为不变
  • 只改变了未知值的默认行为(从"不响应"改为"单选响应"

风险 2:破坏其他业务功能

可能性:极低

缓解措施

  • 只修改了 ClarificationCard.vue 一个文件
  • 不修改 ScriptView.vue 的事件处理
  • 不修改后端代码

风险 3:响应式更新问题

可能性:低

缓解措施

  • selectedValues.value = [value] 是 Vue 3 标准的响应式赋值
  • 在原有代码中已经使用这种方式,应该是有效的

测试用例

测试用例 1:单选卡片切换

  1. 输入心愿文本
  2. 收到澄清卡片(单选类型)
  3. 点击选项 A
  4. 验证:选项 A 被选中(有 ✓ 标记)
  5. 点击选项 B
  6. 验证:选项 B 被选中,选项 A 取消选中(这是修复的关键点)

测试用例 2:多选卡片(保持原有行为)

  1. 收到澄清卡片(多选类型)
  2. 点击选项 A
  3. 验证:选项 A 被选中
  4. 点击选项 B
  5. 验证:选项 A 和 B 都被选中(多选行为不变)

测试用例 3:未知 card_type(修复场景)

  1. 后端返回 card_type: undefined 或其他未知值
  2. 收到澄清卡片
  3. 点击选项 A
  4. 验证:选项 A 被选中
  5. 点击选项 B
  6. 验证:选项 B 被选中,选项 A 取消选中(这是修复的核心场景)

完成标准

  1. ClarificationCard.vue 的 toggleOption 函数已修改
  2. 小程序构建成功
  3. 修改已提交到 git
  4. 用户验证:选项可以自由切换
  5. 现有功能(单选、多选、文本输入)未受影响