feat(mini-program): ScriptView 恢复小说消息操作按钮组
- 为 kind === 'novel' 的消息添加折叠/展开、复制、播放按钮 - 复用已有函数:getMessageDisplayContent、toggleMessageCollapse、copyMessageContent、playMessageTts - 折叠按钮条件改用 ASSISTANT_MESSAGE_PREVIEW_LENGTH 常量(替代硬编码 120) - 添加 .collapse-toggle-row、.message-actions、.action-btn 样式 - 修复 openScriptChat:payload 只有 id 时从 store 获取完整 script 数据,避免 conversationId 缺失导致 loadMessages 不调用 - H5 验收通过:复制/播放/折叠/展开功能正常 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -183,7 +183,28 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-else-if="msg.kind === 'novel'" class="chat-bubble system">
|
<view v-else-if="msg.kind === 'novel'" class="chat-bubble system">
|
||||||
<text class="novel-text">{{ msg.content }}<text v-if="msg.pending" class="typing-cursor">|</text></text>
|
<text class="novel-text">{{ getMessageDisplayContent(msg) }}</text>
|
||||||
|
<text v-if="msg.pending && !isMessageCollapsed(msg)" class="typing-cursor">|</text>
|
||||||
|
|
||||||
|
<!-- 折叠/展开按钮(内容超过预览长度时显示) -->
|
||||||
|
<view v-if="msg.content && msg.content.length > ASSISTANT_MESSAGE_PREVIEW_LENGTH" class="collapse-toggle-row" @click="toggleMessageCollapse(msg)">
|
||||||
|
<text class="collapse-toggle-text">{{ isMessageCollapsed(msg) ? '展开全文' : '收起全文' }}</text>
|
||||||
|
<view class="collapse-chevron" :class="{ down: isMessageCollapsed(msg) }">
|
||||||
|
<view></view>
|
||||||
|
<view></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 操作按钮组(仅在非 pending 状态显示) -->
|
||||||
|
<view v-if="!msg.pending" class="message-actions">
|
||||||
|
<button class="action-btn" @click="copyMessageContent(msg)">
|
||||||
|
<text>复制</text>
|
||||||
|
</button>
|
||||||
|
<button class="action-btn primary" @click="playMessageTts(msg)">
|
||||||
|
<text class="action-icon">{{ ttsPlayer.playing.value ? 'Ⅱ' : '▶' }}</text>
|
||||||
|
<text>{{ ttsPlayer.playing.value ? '暂停' : '播放' }}</text>
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-else class="chat-bubble system">
|
<view v-else class="chat-bubble system">
|
||||||
@@ -1444,7 +1465,10 @@ const normalizeGeneratedContent = (text) => {
|
|||||||
const openScriptChat = async (payload = {}) => {
|
const openScriptChat = async (payload = {}) => {
|
||||||
uni.removeStorageSync(PENDING_SCRIPT_CHAT_KEY)
|
uni.removeStorageSync(PENDING_SCRIPT_CHAT_KEY)
|
||||||
const scriptIdParam = String(payload?.id || payload?.scriptId || '')
|
const scriptIdParam = String(payload?.id || payload?.scriptId || '')
|
||||||
let script = payload?.script || (payload?.id ? payload : null)
|
// 优先使用 payload 中携带的完整 script 对象;否则按 id 从 store 取完整数据
|
||||||
|
// 修复:payload 只有 id 时,直接用 payload 会导致 conversationId/plotJson 等字段缺失,
|
||||||
|
// 进而 loadMessages 不会被调用,详情页内容为空
|
||||||
|
let script = payload?.script || null
|
||||||
if (!script?.id && scriptIdParam) {
|
if (!script?.id && scriptIdParam) {
|
||||||
script = store.getScriptById(scriptIdParam)
|
script = store.getScriptById(scriptIdParam)
|
||||||
if (!script) {
|
if (!script) {
|
||||||
@@ -4069,4 +4093,107 @@ onUnmounted(() => {
|
|||||||
50% { opacity: 0; }
|
50% { opacity: 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 折叠/展开按钮行 */
|
||||||
|
.collapse-toggle-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 12rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
padding: 16rpx 0;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: rgba(88, 28, 135, 0.12);
|
||||||
|
border: 1rpx solid rgba(192, 132, 252, 0.28);
|
||||||
|
color: rgba(246, 230, 255, 0.96);
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse-toggle-row:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
opacity: 0.92;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse-toggle-text {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 折叠箭头图标 */
|
||||||
|
.collapse-chevron {
|
||||||
|
position: relative;
|
||||||
|
width: 20rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
transition: transform 0.18s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse-chevron.down {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse-chevron view {
|
||||||
|
position: absolute;
|
||||||
|
top: 7rpx;
|
||||||
|
width: 12rpx;
|
||||||
|
height: 4rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: linear-gradient(90deg, #fff3b0, #ffd86b);
|
||||||
|
box-shadow: 0 0 12rpx rgba(255, 216, 107, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse-chevron view:first-child {
|
||||||
|
left: 0;
|
||||||
|
transform: rotate(-38deg);
|
||||||
|
transform-origin: right center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse-chevron view:last-child {
|
||||||
|
right: 0;
|
||||||
|
transform: rotate(38deg);
|
||||||
|
transform-origin: left center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 操作按钮组 */
|
||||||
|
.message-actions {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 14rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
height: 72rpx;
|
||||||
|
min-height: 72rpx;
|
||||||
|
padding: 0 8rpx;
|
||||||
|
border-radius: 28rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #e8ccff;
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.15;
|
||||||
|
text-align: center;
|
||||||
|
white-space: normal;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: rgba(88, 28, 135, 0.18);
|
||||||
|
border: 1rpx solid rgba(192, 132, 252, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.primary {
|
||||||
|
color: #fff;
|
||||||
|
background: linear-gradient(145deg, #8c44f2, #5f1db8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-icon {
|
||||||
|
margin-right: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn::after {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user