222 lines
8.9 KiB
Markdown
222 lines
8.9 KiB
Markdown
---
|
||
author: Peanut
|
||
created_at: 2026-06-29
|
||
purpose: ScriptView 简化为纯对话流模式:删除 read/chat 二段切换 + 按旧版布局统一 AI 消息按钮组
|
||
---
|
||
|
||
# ScriptView 简化为纯对话流模式
|
||
|
||
## 背景
|
||
|
||
`bf6f279 feat: ScriptView 改造为对话中心查看/修改模式` 引入了 read/chat 二段切换,但偏离了原始设计。用户的原始设计意图:
|
||
|
||
- **从剧本库点卡片进入**:直接以对话形式查看完整的从创建剧本开始的对话(用户心愿 → AI 剧本 → 改写对话 → 续写对话 → ...)
|
||
- **AI 消息卡片**:按旧版布局展示按钮组
|
||
- **不要二段切换**:不要先 read 再点按钮进 chat
|
||
|
||
## 旧版布局参考(来自 commit `cbf5157` 和 `0db434c`)
|
||
|
||
```
|
||
MessageCard 顶部(story-head-actions):
|
||
┌──────────────────────────────────┐
|
||
│ [剧本标题] [收起/展开] [复制] │
|
||
└──────────────────────────────────┘
|
||
|
||
MessageCard 底部(result-actions):
|
||
┌──────────────────────────────────┐
|
||
│ [换个方向] [不像我] [继续生成] [▶ 播放] │
|
||
└──────────────────────────────────┘
|
||
```
|
||
|
||
## 设计
|
||
|
||
### 1. 入口流程简化
|
||
|
||
| 入口 | 改动 |
|
||
|---|---|
|
||
| 剧本库点卡片 | `openScriptChat` → 直接设 `viewState='result'`,`viewMode='chat'` |
|
||
| 首页心愿输入生成新剧本 | 保持现状(home → generating → result) |
|
||
| read 模式 | **整个删除** |
|
||
|
||
### 2. 删除 read 模式相关代码
|
||
|
||
**删除的位置**:
|
||
|
||
| 文件 | 位置 | 内容 |
|
||
|---|---|---|
|
||
| `mini-program/src/pages/main/ScriptView.vue` | template `view v-if="viewMode === 'read'"` | 整个版本切换器 + 章节展示 + read-action-bar |
|
||
| `mini-program/src/pages/main/ScriptView.vue` | `selectedVersionMessageId` ref | 只被 read 模式用 |
|
||
| `mini-program/src/pages/main/ScriptView.vue` | `onSelectVersion` | 版本切换(read 模式用) |
|
||
| `mini-program/src/pages/main/ScriptView.vue` | `setAsCurrentVersion` | 设为当前版本(read 模式用) |
|
||
| `mini-program/src/pages/main/ScriptView.vue` | `enterChatMode` | read → chat 切换(不再需要) |
|
||
| `mini-program/src/pages/main/ScriptView.vue` | `rewriteCurrentVersion` | read 模式改写入口 |
|
||
| `mini-program/src/pages/main/ScriptView.vue` | `continueCurrentVersion` | read 模式续写入口 |
|
||
|
||
`currentVersionMessageId` 保留:chat 模式下 AI 消息的"删除版本"按钮需要它来判断 `canDelete`。
|
||
|
||
### 3. 按旧版布局统一 AI 消息按钮组
|
||
|
||
**MessageCard 改造**:
|
||
|
||
```vue
|
||
<template>
|
||
<!-- 短消息气泡:保持现状 -->
|
||
<view v-if="isShortMessage && messageType !== 'script'" class="chat-bubble system">
|
||
<text>{{ content }}</text>
|
||
</view>
|
||
|
||
<!-- 长文本卡片:story-card -->
|
||
<view v-else class="story-card" :class="{ collapsed }">
|
||
<!-- 顶部 story-head-actions:收起/展开 + 复制 + 版本号 -->
|
||
<view class="story-head">
|
||
<view class="story-title-wrap">
|
||
<text v-if="versionLabel" class="version-label">{{ versionLabel }}</text>
|
||
<text class="story-title">{{ title || '我的人生剧本' }}</text>
|
||
<view v-if="tags?.length" class="tag-row">
|
||
<text v-for="tag in tags" :key="tag" class="tag">{{ tag }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="story-head-actions">
|
||
<button class="collapse-icon" @click="$emit('toggle-collapse')">
|
||
<text class="collapse-icon-text">{{ collapsed ? '展开' : '收起' }}</text>
|
||
<view class="collapse-chevron" :class="{ down: collapsed }">
|
||
<view></view><view></view>
|
||
</view>
|
||
</button>
|
||
<button class="copy-card-btn" @click="$emit('copy')">复制</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 正文 -->
|
||
<scroll-view v-if="collapsed" class="story-body-scroll" scroll-y>
|
||
<text class="story-body" :selectable="true" :user-select="true">{{ content }}</text>
|
||
</scroll-view>
|
||
<text v-else class="story-body" :selectable="true" :user-select="true">{{ content }}</text>
|
||
|
||
<!-- 底部收起/展开行 -->
|
||
<view class="collapse-row" @click="$emit('toggle-collapse')">
|
||
<text class="collapse-row-text">{{ collapsed ? '展开全文' : '收起全文' }}</text>
|
||
<view class="collapse-chevron" :class="{ down: collapsed }">
|
||
<view></view><view></view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部 result-actions:按旧版布局 + 加上 script 专属按钮 -->
|
||
<view class="result-actions">
|
||
<!-- 旧版基础按钮 -->
|
||
<button class="action-btn" @click="$emit('change-direction')">换个方向</button>
|
||
<button class="action-btn" @click="$emit('not-like-me')">不像我</button>
|
||
<button v-if="canContinue" class="action-btn" @click="$emit('continue-script')">续写</button>
|
||
|
||
<!-- script 专属功能按钮 -->
|
||
<button v-if="canRewrite" class="action-btn" @click="$emit('rewrite')">改写</button>
|
||
<button v-if="hasChildren" class="action-btn" @click="$emit('view-versions')">查看历史版本</button>
|
||
<button v-if="canDelete" class="action-btn danger" @click="$emit('delete-version')">删除版本</button>
|
||
|
||
<!-- TTS 播放 -->
|
||
<button class="action-btn primary" @click="$emit('play-tts')">
|
||
<text class="action-icon">{{ ttsIcon || '▶' }}</text>
|
||
<text>{{ ttsText || '播放' }}</text>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
```
|
||
|
||
**关键变化**:
|
||
- `messageType === 'script'` 分支去掉(长文本统一渲染)
|
||
- `result-actions` 在 script 类型下按旧版布局 + 加 script 专属按钮
|
||
- 短消息气泡(chat/system)保持不变
|
||
|
||
### 4. ScriptView template 简化
|
||
|
||
**简化前的 read 模式 section**:
|
||
```vue
|
||
<view v-if="viewMode === 'read'">
|
||
<view class="version-bar">...</view>
|
||
<view class="script-read-content">...</view>
|
||
<view class="read-action-bar">...</view>
|
||
</view>
|
||
```
|
||
|
||
**删除**。
|
||
|
||
**简化后的 chat 模式 section**:
|
||
```vue
|
||
<view class="result-chat-view">
|
||
<view class="conversation compact">
|
||
<!-- 用户心愿气泡 -->
|
||
<view class="chat-bubble user">
|
||
<text>{{ wishText }}</text>
|
||
<text class="bubble-time">{{ currentMessageTime }}</text>
|
||
</view>
|
||
<!-- 系统提示 -->
|
||
<view class="chat-bubble system done">
|
||
<text>心愿已实现,故事已为你展开</text>
|
||
<text class="bubble-time">{{ currentResultTime }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 对话消息列表 -->
|
||
<view v-if="displayMessages.length" class="result-chat-list">
|
||
<view v-for="message in displayMessages" :key="message.id">
|
||
<MessageCard
|
||
v-if="message.sender === 'assistant' || message.type === 'script'"
|
||
message-type="script"
|
||
:version-label="formatVersionLabel(message)"
|
||
:has-children="messageHasChildren(message)"
|
||
:can-delete="message.id !== currentVersionMessageId && message.parentMessageId !== null"
|
||
:can-rewrite="true"
|
||
:can-continue="true"
|
||
:content="message.content"
|
||
:collapsed="isMessageCollapsed(message)"
|
||
:content-length="message.content.length"
|
||
:is-short-message="false"
|
||
:tts-icon="..."
|
||
:tts-text="..."
|
||
@toggle-collapse="..."
|
||
@copy="..."
|
||
@rewrite="..."
|
||
@continue-script="..."
|
||
@view-versions="..."
|
||
@delete-version="..."
|
||
@play-tts="..."
|
||
@change-direction="..."
|
||
@not-like-me="..."
|
||
/>
|
||
<view v-else class="chat-bubble user">
|
||
<text>{{ message.content }}</text>
|
||
<text class="bubble-time">{{ message.time || formatMessageTime() }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 输入栏 -->
|
||
<view class="result-chat-bar">...</view>
|
||
</view>
|
||
```
|
||
|
||
### 5. ScriptView 的 `continue` / `change-direction` / `not-like-me` emits
|
||
|
||
旧版 emit 在 script-actions 下不存在,需要保留以兼容旧版按钮。
|
||
|
||
- `continue`(旧版 "继续生成"按钮)→ 触发 `continueMessage` 或 `continueInChat`
|
||
- `change-direction`("换个方向")→ 触发 `changeDirection`
|
||
- `not-like-me`("不像我")→ 触发 `notLikeMe`
|
||
|
||
**这些函数已经存在于 ScriptView.vue 中**(来自旧版代码)。直接绑定。
|
||
|
||
## 验收标准
|
||
|
||
- [ ] 从剧本库点卡片 → 直接进入对话流(无需点"进入对话修改")
|
||
- [ ] 对话流完整显示:用户心愿 + AI 剧本 + 改写/续写对话
|
||
- [ ] AI 消息卡片顶部:收起/展开、复制、版本号标签
|
||
- [ ] AI 消息卡片底部:换个方向、不像我、续写、改写、查看历史版本、删除版本、TTS 播放
|
||
- [ ] read 模式相关代码完全删除(不再有任何切换按钮)
|
||
- [ ] Console 无报错
|
||
|
||
## 风险与回退
|
||
|
||
- **风险低**:只删除 read 模式 + 调整 MessageCard 按钮布局,不影响后端
|
||
- **回退**:`git revert` 单个 commit 即可恢复
|