7.0 KiB
7.0 KiB
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'(可能是 undefined、null 或其他未定义的值),toggleOption 函数不会执行任何逻辑,导致:
- 用户点击选项 A →
selectedValues不更新 - 用户点击选项 B →
selectedValues仍不更新 - 视觉上表现为"无法切换选项"
代码位置
文件: mini-program/src/components/ClarificationCard.vue:80-95
设计目标
- 选项可自由切换:无论
card_type是什么值,用户都能正常切换选项 - 保持现有功能:不破坏单选、多选、文本输入的现有行为
- 向后兼容:对于正常的
card_type值(single_select、multi_select、text_input),行为保持不变 - 不破坏其他业务功能:不修改 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_type是undefined、null或其他未定义的值,选项也能正常切换
保留的多选逻辑:
- 多选条件(
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 容错性)"
第四步:用户验证
在微信小程序中:
- 进入"心愿实现"页面
- 输入心愿文本,触发澄清卡片
- 点击选项 A(应该被选中)
- 点击选项 B(应该切换到 B,A 取消选中)
- 再次点击选项 A(应该切换回 A)
- 验证:选项可以自由切换
风险评估
风险 1:影响现有正常的卡片类型
可能性:低
缓解措施:
- 修改前的行为对照表显示,所有正常的
card_type值行为不变 - 只改变了未知值的默认行为(从"不响应"改为"单选响应")
风险 2:破坏其他业务功能
可能性:极低
缓解措施:
- 只修改了 ClarificationCard.vue 一个文件
- 不修改 ScriptView.vue 的事件处理
- 不修改后端代码
风险 3:响应式更新问题
可能性:低
缓解措施:
selectedValues.value = [value]是 Vue 3 标准的响应式赋值- 在原有代码中已经使用这种方式,应该是有效的
测试用例
测试用例 1:单选卡片切换
- 输入心愿文本
- 收到澄清卡片(单选类型)
- 点击选项 A
- 验证:选项 A 被选中(有 ✓ 标记)
- 点击选项 B
- 验证:选项 B 被选中,选项 A 取消选中(这是修复的关键点)
测试用例 2:多选卡片(保持原有行为)
- 收到澄清卡片(多选类型)
- 点击选项 A
- 验证:选项 A 被选中
- 点击选项 B
- 验证:选项 A 和 B 都被选中(多选行为不变)
测试用例 3:未知 card_type(修复场景)
- 后端返回
card_type: undefined或其他未知值 - 收到澄清卡片
- 点击选项 A
- 验证:选项 A 被选中
- 点击选项 B
- 验证:选项 B 被选中,选项 A 取消选中(这是修复的核心场景)
完成标准
- ✅ ClarificationCard.vue 的
toggleOption函数已修改 - ✅ 小程序构建成功
- ✅ 修改已提交到 git
- ✅ 用户验证:选项可以自由切换
- ✅ 现有功能(单选、多选、文本输入)未受影响