优化: df-miniapp 跨端 AI Chat 更新(会话前基线收尾)
- ws.ts 心跳 pong 闭环 + useAiChat 看门狗治半连接挂死 - pages 新增 settings/ + chat/conversations 更新 + types events/relay + mdRenderer + tsconfig
This commit is contained in:
@@ -1,10 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useAiChat } from '@/composables/useAiChat'
|
||||
import type { Conversation } from '@/types/events'
|
||||
|
||||
const ai = useAiChat()
|
||||
|
||||
/**
|
||||
* mp-weixin 模板对嵌套在对象中的 reactive/ref 响应性追踪有问题。
|
||||
* 用本地 ref + watch 同步,确保模板直接拿到响应式数组。
|
||||
*/
|
||||
const conversations = ref<Conversation[]>([])
|
||||
/**
|
||||
* 监听 ai.conversations.length 变化(比 deep watch 更可靠)。
|
||||
* 用 `[...ai.conversations]` 创建普通数组赋值给 ref,确保每次变化都触发模板更新。
|
||||
*/
|
||||
watch(() => ai.conversations.value.length, () => {
|
||||
conversations.value = [...ai.conversations.value]
|
||||
}, { immediate: true })
|
||||
|
||||
/** 点击会话项切换 */
|
||||
function handleSelect(convId: string): void {
|
||||
ai.switchConversation(convId)
|
||||
@@ -66,13 +80,20 @@ function formatTime(ts?: number): string {
|
||||
|
||||
<!-- 会话列表 -->
|
||||
<scroll-view class="conv-list" scroll-y>
|
||||
<view v-if="ai.conversations.length === 0" class="empty-hint">
|
||||
<!-- 加载中骨架屏 -->
|
||||
<view v-if="conversations.length === 0 && ai.loading.value" class="conv-skeleton">
|
||||
<view v-for="i in 5" :key="i" class="conv-sk-item">
|
||||
<view class="conv-sk-line conv-sk-w70"></view>
|
||||
<view class="conv-sk-line conv-sk-w40"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else-if="conversations.length === 0" class="empty-hint">
|
||||
<text>暂无历史会话</text>
|
||||
<text class="empty-sub">在桌面端创建后,此处同步</text>
|
||||
</view>
|
||||
|
||||
<view
|
||||
v-for="conv in ai.conversations"
|
||||
v-for="conv in conversations"
|
||||
:key="conv.id"
|
||||
class="conv-item"
|
||||
:class="{ active: conv.id === ai.activeConversationId.value }"
|
||||
@@ -85,7 +106,7 @@ function formatTime(ts?: number): string {
|
||||
</view>
|
||||
<text v-if="conv.updatedAt" class="conv-time">{{ formatTime(conv.updatedAt) }}</text>
|
||||
</view>
|
||||
<view v-if="ai.conversations.length > 0" class="list-hint">
|
||||
<view v-if="conversations.length > 0" class="list-hint">
|
||||
<text>长按会话可重命名</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
@@ -186,4 +207,26 @@ function formatTime(ts?: number): string {
|
||||
color: $uni-text-color-disable;
|
||||
font-size: $uni-font-size-sm;
|
||||
}
|
||||
/* 骨架屏(下拉刷新/冷启动占位) */
|
||||
.conv-skeleton {
|
||||
padding: 24rpx;
|
||||
}
|
||||
.conv-sk-item {
|
||||
margin-bottom: 32rpx;
|
||||
padding: 24rpx;
|
||||
}
|
||||
.conv-sk-line {
|
||||
height: 24rpx;
|
||||
margin: 8rpx 0;
|
||||
background: linear-gradient(90deg, $uni-bg-color-light 25%, #3a3a3a 50%, $uni-bg-color-light 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: conv-sk-shimmer 1.5s infinite;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
.conv-sk-w70 { width: 70%; }
|
||||
.conv-sk-w40 { width: 40%; }
|
||||
@keyframes conv-sk-shimmer {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user