fix: 修复背景聊天消失和修复返回

This commit is contained in:
韩庆伟 2025-05-16 16:38:21 +08:00
parent 258eb17281
commit 70625f6ea1
5 changed files with 183 additions and 35 deletions

14
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,14 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug h5",
"type": "chrome",
"runtimeArgs": ["--remote-debugging-port=9222"],
"request": "launch",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}",
"preLaunchTask": "uni:h5"
}
]
}

16
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,16 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "uni:h5",
"type": "npm",
"script": "dev --devtools",
"isBackground": true,
"problemMatcher": "$vite",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}

View File

@ -9,6 +9,8 @@ import 'element-plus/dist/index.css'
import App from './App.vue'
import { prototypeInterceptor, requestInterceptor, routeInterceptor } from './interceptors'
import store from './store'
// import VConsole from 'vconsole'
// new VConsole()
export function createApp() {
const app = createSSRApp(App)

View File

@ -10,18 +10,24 @@
<template>
<div class="flex flex-col h-screen bg-gray-50">
<!-- Navigation Bar -->
<div class="flex-none flex items-center justify-between px-5 py-3 bg-white shadow-md h-10">
<div
class="flex-none flex items-center justify-between px-5 py-3 bg-white shadow-md h-10 pt-10 z-999"
>
<image src="/static/aichat/back.png" class="w-2 h-4" @click="goBack" />
<div class="text-lg font-medium">小墨</div>
<div class="text-lg font-medium ml-12">小墨</div>
<div class="flex items-center space-x-3">
<!-- v-if="rawList.length > 0" -->
<image src="/static/aichat/time.png" class="w-5 h-5" @click="openPopup" />
<image src="/static/aichat/time.png" class="w-5 h-5 mr-4" @click="openPopup" />
<image src="/static/aichat/new.png" class="w-5 h-5" @click="newChat" />
</div>
</div>
<!-- 消息区 -->
<div :class="['flex relative', showActions ? 'h-105' : 'h-130']">
<div
:class="[
'flex relative p-b-10',
showActions ? (uploadList.length ? 'h-118' : 'h-137') : 'h-157',
]"
>
<!-- 背景层 -->
<div
v-if="!messages.length"
@ -171,7 +177,7 @@
]"
>
<!-- 上传列表 -->
<div v-if="uploadList.length" class="flex px-4 py-2 overflow-x-auto space-x-3 bg-#f9fafb">
<div v-if="uploadList.length" class="flex px-4 py-2 overflow-x-auto space-x-3 bg-transparent">
<div
v-for="item in uploadList"
:key="item.id"
@ -233,7 +239,15 @@
placeholder="想对我说点什么~"
class="flex-1 h-10 px-3 border border-gray-100 bg-[#f9f9f9] rounded-full focus:outline-none"
/>
<image src="/static/aichat/add-circle.png" class="w-7 h-7 mx-3" @click="toggleActions" />
<image
src="/static/aichat/add-circle.png"
class="w-7 h-7 mx-3"
@click="toggleActions"
:style="{
transform: `rotate(${rotation}deg)`,
transition: 'transform 0.3s ease',
}"
/>
<image
src="/static/aichat/enter.png"
class="w-7 h-7"
@ -336,11 +350,10 @@ interface IMessage {
content: string | any[]
timestamp: Date
}
const assistantAvatar =
'https://dci-file-new.bj.bcebos.com/fonchain-main/test/runtime/image/avatar/40/b8ed6fea-6662-416d-8bb3-1fd8a8197061.jpg'
const userAvatar = assistantAvatar
const userAvatar = ref('')
const baseUrl = getEnvBaseUrl()
const token = useUserStore().userInfo.token || import.meta.env.VITE_DEV_TOKEN || ''
// const token = useUserStore().userInfo.token || import.meta.env.VITE_DEV_TOKEN || ''
const messages = reactive<IMessage[]>([])
//
const historyUserMsgs = reactive<any[]>([])
@ -365,7 +378,8 @@ const MAX_CONCURRENT_UPLOADS = 6
const showPopup = ref(false)
const fullscreen = ref(false)
function openPopup() {
async function openPopup() {
await fetchHistoryList()
showPopup.value = true
}
function closePopup() {
@ -407,33 +421,120 @@ const groups = computed(() => {
})
//
function goChat(listUuid: string) {
uni.navigateTo({ url: `/pages/chat/index?listUuid=${listUuid}` })
async function goChat(listUuid: string) {
await fetchHistoryDiets(listUuid)
showPopup.value = false
}
// ------------------
// API
// ------------------
onMounted(async () => {
const body = {
page: 1,
pageSize: 10,
}
/** 1. 创建聊天会话 */
const listUuid = ref('')
async function createChatSession() {
try {
const resp: any = await uni.request({
url: `${baseUrl}/chat/list`,
const createResp: any = await uni.request({
url: `${baseUrl}/chat/create`,
method: 'POST',
data: body,
data: {
gptModel: 'gpt-3.5-turbo',
},
header: {
Authorization: token,
},
})
// listUuid
console.log('createChatSession →', createResp)
listUuid.value = createResp.data.data.listUuid
} catch (err) {
console.error('createChatSession error:', err)
}
}
// ------------------
// API
// ------------------
if (resp.data.data) {
rawList.value = resp.data.data
/** 2. 拉取历史记录列表 */
async function fetchHistoryList() {
try {
const resp: any = await uni.request({
url: `${baseUrl}/chat/list`,
method: 'POST',
data: {
page: 1,
pageSize: 30,
},
header: {
Authorization: token,
},
})
if (resp.data && resp.data.data) {
rawList.value = resp.data.data.data
console.log('fetchHistoryList →', rawList.value)
}
} catch (e) {}
} catch (err) {
console.error('fetchHistoryList error:', err)
}
}
/** 3. 拉取历史记录详情 */
async function fetchHistoryDiets(value) {
try {
const resp: any = await uni.request({
url: `${baseUrl}/chat/detail`,
method: 'POST',
data: {
listUuid: value,
gptModel: 'gpt-3.5-turbo',
},
header: {
Authorization: token,
},
})
if (resp.data) {
rawList.value = resp.data
console.log('fetchHistoryLisssst →', rawList.value)
}
} catch (err) {
console.error('fetchHistoryList error:', err)
}
}
const token = ref<string>('')
const userInfo = ref<any>({})
const refreshToken = ref<string>('')
const statusBarHeight = ref<number>(0)
const mask = ref('')
// ---- ----
onMounted(() => {
// 1. init Extras
const init = async () => {
// plusready plus.webview
const wv = plus.webview.currentWebview()
token.value = wv.token || uni.getStorageSync('token')
userInfo.value = JSON.parse(wv.userInfo) || {}
refreshToken.value = wv.refreshToken || uni.getStorageSync('refreshToken')
statusBarHeight.value = wv.statusBarHeight || uni.getSystemInfoSync().statusBarHeight
userAvatar.value = userInfo.value.Avatar
mask.value = userInfo.value.ID
await createChatSession()
await fetchHistoryList()
}
// 2. Plus plusready
if (window.plus && plus.webview) {
document.addEventListener('plusready', init, false)
// plusready
if (plus.webview.currentWebview()) {
init()
}
}
// 3. H5 storage/SystemInfo
else {
token.value = uni.getStorageSync('token')
userInfo.value = uni.getStorageSync('userInfo')
refreshToken.value = uni.getStorageSync('refreshToken')
statusBarHeight.value = uni.getSystemInfoSync().statusBarHeight
createChatSession().then(fetchHistoryList)
}
})
function scrollToBottom() {
@ -479,18 +580,21 @@ const formatDayGroup = (d: Date) => dayjs(d).format('YYYY/MM/DD HH:mm')
const formatTimeShort = (d: Date) => dayjs(d).format('MM/DD HH:mm')
function goBack() {
window.history.back()
const wv = plus.webview.currentWebview()
wv.close('slide-out-right', 300) // wv.close()
}
function viewHistory() {
uni.navigateTo({ url: '/pages/history/history' })
}
function newChat() {
async function newChat() {
messages.splice(0)
await createChatSession()
inputText.value = ''
}
const rotation = ref(0)
function toggleActions() {
showActions.value = !showActions.value
rotation.value += 45
scrollToBottom()
}
@ -506,7 +610,7 @@ const uploadConfig = reactive({
url: 'http://114.218.158.24:9020/upload/img',
formData: {
source: 'chat',
mask: '2076',
mask: mask.value,
type: uploadFileTypeEm.image,
},
image: {
@ -827,6 +931,7 @@ async function sendText(msg) {
model: 'gpt-4-vision-preview',
max_tokens: 1000,
temperature: 1,
listUuid: listUuid.value,
top_p: 1,
presence_penalty: 0,
frequency_penalty: 0,
@ -835,6 +940,8 @@ async function sendText(msg) {
}
try {
aiMsg.content = ''
const resp = await fetch(baseUrl + '/chat/completion', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: token },
@ -854,7 +961,7 @@ async function sendText(msg) {
buffer = parts.pop()!
for (const part of parts) {
scrollToBottom()
console.log('1')
console.log('1', aiMsg.content)
const chunk = part.trim()
if (chunk === '[DONE]') {
done = true
@ -889,8 +996,16 @@ async function sendText(msg) {
function copyText(msg: IMessage) {
if (typeof msg.content === 'string') {
navigator.clipboard.writeText(msg.content)
alert('已复制')
uni.setClipboardData({
data: msg.content,
success() {
uni.showToast({ title: '已复制', icon: 'success' })
},
fail(err) {
console.error('复制失败', err)
uni.showToast({ title: '复制失败', icon: 'error' })
},
})
}
}

View File

@ -27,6 +27,7 @@ export interface IGptRequestBody {
max_tokens: number
temperature: number
top_p: number
listUuid: string
presence_penalty: number
frequency_penalty: number
messages: IMessage[]