Files
happy-life-star/docs/superpowers/specs/2026-06-29-scriptview-dialog-flow-only-design.md
T

8.9 KiB
Raw Blame History

author, created_at, purpose
author created_at purpose
Peanut 2026-06-29 ScriptView 简化为纯对话流模式:删除 read/chat 二段切换 + 按旧版布局统一 AI 消息按钮组

ScriptView 简化为纯对话流模式

背景

bf6f279 feat: ScriptView 改造为对话中心查看/修改模式 引入了 read/chat 二段切换,但偏离了原始设计。用户的原始设计意图:

  • 从剧本库点卡片进入:直接以对话形式查看完整的从创建剧本开始的对话(用户心愿 → AI 剧本 → 改写对话 → 续写对话 → ...)
  • AI 消息卡片:按旧版布局展示按钮组
  • 不要二段切换:不要先 read 再点按钮进 chat

旧版布局参考(来自 commit cbf51570db434c

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 改造

<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

<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

<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(旧版 "继续生成"按钮)→ 触发 continueMessagecontinueInChat
  • change-direction"换个方向")→ 触发 changeDirection
  • not-like-me"不像我")→ 触发 notLikeMe

这些函数已经存在于 ScriptView.vue 中(来自旧版代码)。直接绑定。

验收标准

  • 从剧本库点卡片 → 直接进入对话流(无需点"进入对话修改")
  • 对话流完整显示:用户心愿 + AI 剧本 + 改写/续写对话
  • AI 消息卡片顶部:收起/展开、复制、版本号标签
  • AI 消息卡片底部:换个方向、不像我、续写、改写、查看历史版本、删除版本、TTS 播放
  • read 模式相关代码完全删除(不再有任何切换按钮)
  • Console 无报错

风险与回退

  • 风险低:只删除 read 模式 + 调整 MessageCard 按钮布局,不影响后端
  • 回退git revert 单个 commit 即可恢复