14 KiB
author, created_at, purpose
| author | created_at | purpose |
|---|---|---|
| claude | 2026-06-27 | AI 消息卡片功能按钮统一实现计划 |
AI 消息卡片功能按钮统一实现计划
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 统一小程序实现心愿页面中所有 AI 消息卡片的功能按钮,并修复 story-card 展开失效 bug
Architecture: 在现有单文件组件 ScriptView.vue 内修复 + 扩展,不提取独立组件,保持现有文件结构
Tech Stack: Vue 3, UniApp, 微信小程序
文件结构
修改:
mini-program/src/pages/main/ScriptView.vue- 主页面组件(模板 + 脚本 + 样式)
Task 1: 修复 story-card 展开失效 bug
Files:
-
Modify:
mini-program/src/pages/main/ScriptView.vue:192-210 -
Step 1: 移除 resultHasScriptReplies 条件包裹
打开 mini-program/src/pages/main/ScriptView.vue,找到第 192 行的 <template v-if="!resultHasScriptReplies">,删除这个条件包裹标签和对应的 </template> 闭合标签(第 210 行)。
修改前:
<template v-if="!resultHasScriptReplies">
<scroll-view
v-if="storyCollapsed"
class="story-body-scroll"
scroll-y
:enhanced="true"
:show-scrollbar="true"
>
<text class="story-body" :selectable="true" :user-select="true">{{ displayedResultContent }}</text>
</scroll-view>
<text v-else class="story-body" :selectable="true" :user-select="true">{{ displayedResultContent }}</text>
<view class="collapse-row" @click="toggleStoryCollapse">
<text class="collapse-row-text">{{ storyCollapsed ? '展开全文' : '收起全文' }}</text>
<view class="collapse-chevron" :class="{ down: storyCollapsed }">
<view></view>
<view></view>
</view>
</view>
</template>
修改后:
<scroll-view
v-if="storyCollapsed"
class="story-body-scroll"
scroll-y
:enhanced="true"
:show-scrollbar="true"
>
<text class="story-body" :selectable="true" :user-select="true">{{ displayedResultContent }}</text>
</scroll-view>
<text v-else class="story-body" :selectable="true" :user-select="true">{{ displayedResultContent }}</text>
<view class="collapse-row" @click="toggleStoryCollapse">
<text class="collapse-row-text">{{ storyCollapsed ? '展开全文' : '收起全文' }}</text>
<view class="collapse-chevron" :class="{ down: storyCollapsed }">
<view></view>
<view></view>
</view>
</view>
- Step 2: 验证修复
在微信开发者工具中编译运行,进入「实现心愿」页面:
- 输入心愿并生成故事
- 点击「继续生成」创建 script 类型消息
- 点击 story-card 的展开/收起按钮,验证故事正文能正确展开和收起
- 确认控制台无报错
- Step 3: 提交代码
git add mini-program/src/pages/main/ScriptView.vue
git commit -m "fix: 修复 story-card 展开失效 bug
移除 resultHasScriptReplies 条件包裹,让故事正文始终由 storyCollapsed 控制展开/收起"
Task 2: 添加新方法支持消息卡片功能
Files:
-
Modify:
mini-program/src/pages/main/ScriptView.vue(script 部分) -
Step 1: 添加 copyMessageContent 方法
在 toggleMessageCollapse 方法之后(约第 450 行),添加复制消息内容的方法:
const copyMessageContent = (message) => {
const content = message?.content || ''
if (!content.trim()) {
uni.showToast({ title: '暂无可复制内容', icon: 'none' })
return
}
uni.setClipboardData({
data: content,
success: () => {
uni.showToast({ title: '已复制', icon: 'success' })
}
})
analytics.track('script_message_copy_click', {
message_id: message?.id || '',
content_length: content.length
}, { eventType: 'script', pagePath })
}
- Step 2: 添加 playMessageTts 方法
在 copyMessageContent 方法之后,添加播放 TTS 的方法:
const playMessageTts = (message) => {
const scriptId = currentResult.value?.id || ''
ttsPlayer.playSource(scriptId)
analytics.track('script_message_tts_click', {
message_id: message?.id || '',
script_id: scriptId
}, { eventType: 'script', pagePath })
}
- Step 3: 修改 toggleMessageCollapse 方法添加埋点
找到 toggleMessageCollapse 方法(约第 442-450 行),在方法开头添加埋点代码:
修改前:
const toggleMessageCollapse = (message) => {
collapsedMessageIds.value[message.id] = !isMessageCollapsed(message)
}
修改后:
const toggleMessageCollapse = (message) => {
collapsedMessageIds.value[message.id] = !isMessageCollapsed(message)
analytics.track('script_message_collapse_toggle', {
message_id: message?.id || '',
collapsed: collapsedMessageIds.value[message.id]
}, { eventType: 'script', pagePath })
}
- Step 4: 验证方法添加
在微信开发者工具中编译运行,确认控制台无语法错误。新方法暂时不会被调用,后续任务会在模板中使用。
- Step 5: 提交代码
git add mini-program/src/pages/main/ScriptView.vue
git commit -m "feat: 添加消息卡片功能方法
- copyMessageContent: 复制消息内容到剪贴板
- playMessageTts: 播放故事 TTS 音频
- toggleMessageCollapse: 添加展开/收起埋点"
Task 3: 在 result-chat-list 中添加功能按钮组
Files:
-
Modify:
mini-program/src/pages/main/ScriptView.vue:245-270 -
Step 1: 在 assistant 消息中添加功能按钮组
找到 result-chat-list 部分(约第 245-270 行),在消息内容和展开/收起按钮之后、时间戳之前,添加功能按钮组。
修改前:
<view
v-for="(message, index) in resultMessages"
:key="message.id"
class="result-chat-list"
>
<view
v-if="isAssistantMessage(message)"
class="chat-bubble assistant"
>
<text class="message-content">{{ getMessageContent(message) }}</text>
<view class="message-toggle" @click="toggleMessageCollapse(message)">
<text>{{ isMessageCollapsed(message) ? '展开全文' : '收起全文' }}</text>
<view class="collapse-chevron" :class="{ down: isMessageCollapsed(message) }">
<view></view>
<view></view>
</view>
</view>
<text class="message-time">{{ formatMessageTime(message.createdAt) }}</text>
</view>
<!-- user message -->
</view>
修改后:
<view
v-for="(message, index) in resultMessages"
:key="message.id"
class="result-chat-list"
>
<view
v-if="isAssistantMessage(message)"
class="chat-bubble assistant"
>
<text class="message-content">{{ getMessageContent(message) }}</text>
<view class="message-toggle" @click="toggleMessageCollapse(message)">
<text>{{ isMessageCollapsed(message) ? '展开全文' : '收起全文' }}</text>
<view class="collapse-chevron" :class="{ down: isMessageCollapsed(message) }">
<view></view>
<view></view>
</view>
</view>
<view class="message-actions">
<view class="action-btn" @click="copyMessageContent(message)">
<text>复制</text>
</view>
<view class="action-btn" @click="changeDirection">
<text>换个方向</text>
</view>
<view class="action-btn" @click="notLikeMe">
<text>不像我</text>
</view>
<view class="action-btn" @click="continueInChat">
<text>继续生成</text>
</view>
<view class="action-btn primary" @click="playMessageTts(message)">
<text>▶ 播放</text>
</view>
</view>
<text class="message-time">{{ formatMessageTime(message.createdAt) }}</text>
</view>
<!-- user message -->
</view>
说明:
-
按钮组使用
.message-actions容器,2 列网格布局 -
复制、换个方向、不像我、继续生成使用
.action-btn样式 -
播放按钮使用
.action-btn.primary样式(主色调突出) -
所有按钮都调用 Task 2 中定义的方法或复用现有方法
-
Step 2: 验证按钮组显示
在微信开发者工具中编译运行:
- 进入「实现心愿」页面,生成故事
- 点击「继续生成」创建 assistant 消息
- 验证每条 assistant 消息下方显示 5 个功能按钮(复制、换个方向、不像我、继续生成、播放)
- 验证按钮布局为 2 列网格
- Step 3: 验证按钮功能
逐个测试按钮功能:
- 复制:点击后应复制消息内容,显示「已复制」提示
- 换个方向:点击后应进入「换方向」修订确认流程
- 不像我:点击后应进入「不像我」修订确认流程
- 继续生成:点击后应收起故事并聚焦输入框
- 播放:点击后应播放故事 TTS 音频
确认控制台无报错,所有功能正常。
- Step 4: 提交代码
git add mini-program/src/pages/main/ScriptView.vue
git commit -m "feat: 在 result-chat-list 中添加功能按钮组
为每条 assistant 消息添加完整功能按钮:
- 复制:复制消息内容到剪贴板
- 换个方向:进入换方向修订确认
- 不像我:进入不像我修订确认
- 继续生成:收起故事并聚焦输入框
- 播放:播放故事 TTS 音频"
Task 4: 添加消息按钮组样式
Files:
-
Modify:
mini-program/src/pages/main/ScriptView.vue(style 部分) -
Step 1: 添加 .message-actions 样式
在 <style scoped> 部分(约第 1500 行之后),找到 .message-toggle 样式附近,添加按钮组样式:
.message-actions {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16rpx;
margin-top: 24rpx;
}
.message-actions .action-btn {
padding: 16rpx 24rpx;
background: rgba(255, 255, 255, 0.08);
border: 2rpx solid rgba(255, 255, 255, 0.15);
border-radius: 16rpx;
color: #e0e0e0;
font-size: 24rpx;
text-align: center;
transition: all 0.2s;
}
.message-actions .action-btn:active {
background: rgba(255, 255, 255, 0.12);
transform: scale(0.98);
}
.message-actions .action-btn.primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-color: transparent;
color: #ffffff;
font-weight: 500;
}
.message-actions .action-btn.primary:active {
opacity: 0.85;
}
- Step 2: 验证样式效果
在微信开发者工具中编译运行:
- 进入「实现心愿」页面,生成故事
- 点击「继续生成」创建 assistant 消息
- 验证按钮样式:
- 按钮组为 2 列网格布局
- 普通按钮为半透明白色背景,圆角边框
- 播放按钮为主色调渐变(紫色)
- 点击时有缩放反馈效果
- 验证按钮在不同屏幕尺寸下的响应式表现
- Step 3: 提交代码
git add mini-program/src/pages/main/ScriptView.vue
git commit -m "style: 添加消息按钮组样式
- .message-actions: 2 列网格布局,间距 16rpx
- .action-btn: 半透明白色背景,圆角边框,点击反馈
- .action-btn.primary: 主色调渐变(紫色),白色文字"
Task 5: 最终验证和边界情况测试
Files:
-
无需修改文件,仅做验证
-
Step 1: 测试 story-card 展开/收起
在微信开发者工具中编译运行:
- 进入「实现心愿」页面
- 输入心愿并生成故事
- 点击 story-card 的「展开全文」按钮,验证故事正文展开
- 点击「收起全文」按钮,验证故事正文收起
- 点击「继续生成」创建 script 类型消息
- 再次点击 story-card 的展开/收起按钮,验证功能正常(之前会失效)
预期结果: 所有展开/收起操作正常工作
- Step 2: 测试 assistant 消息功能按钮
继续在上一步的基础上:
- 验证每条 assistant 消息下方显示 5 个功能按钮
- 点击「复制」按钮,验证复制成功提示
- 点击「换个方向」按钮,验证进入修订确认流程
- 点击「不像我」按钮,验证进入修订确认流程
- 点击「继续生成」按钮,验证故事收起且输入框获得焦点
- 点击「播放」按钮,验证 TTS 音频播放
预期结果: 所有按钮功能正常
- Step 3: 测试边界情况
测试以下边界场景:
场景 1:空内容的 assistant 消息
- 手动构造一条空内容的 assistant 消息(或等待 AI 返回空内容)
- 点击「复制」按钮
- 预期: 显示「暂无可复制内容」提示
场景 2:pending 状态的 assistant 消息
- 生成故事后,快速点击「继续生成」
- 观察正在加载的 assistant 消息(pending 状态)
- 预期: pending 消息不显示功能按钮组
场景 3:user 消息
- 查看用户发送的消息
- 预期: user 消息不显示功能按钮组
场景 4:无 currentResult 时的播放
-
如果可能,测试在未生成故事时点击播放按钮
-
预期: 按钮仍可点击,TTS 播放器内部处理空 id
-
Step 4: 验证埋点
打开微信开发者工具的控制台,查看埋点日志:
- 点击 assistant 消息的展开/收起按钮,验证
script_message_collapse_toggle埋点 - 点击「复制」按钮,验证
script_message_copy_click埋点 - 点击「播放」按钮,验证
script_message_tts_click埋点
预期结果: 所有埋点正确触发,包含正确的参数
- Step 5: 检查控制台错误
在整个测试过程中,持续关注微信开发者工具的控制台:
- 确认无 Vue 警告
- 确认无 JavaScript 错误
- 确认无网络请求错误
预期结果: 控制台干净,无任何错误
- Step 6: 最终提交(如有修改)
如果在前面的测试中发现了需要修复的问题,修复后提交:
git add mini-program/src/pages/main/ScriptView.vue
git commit -m "fix: 修复最终验证中发现的问题
[描述修复的具体问题]"
如果测试全部通过,无需额外提交。
- Step 7: 创建 Pull Request(可选)
如果项目使用 PR 流程,创建 PR 合并这些更改:
git push origin HEAD
然后在代码托管平台创建 PR,标题:
feat: 统一 AI 消息卡片功能按钮并修复 story-card 展开失效
PR 描述包含:
- 修复 story-card 展开失效 bug
- 为每条 assistant 消息添加完整功能按钮组
- 添加相应的样式和埋点
- 所有功能已通过测试