fix: 修复背景聊天消失和修复返回
This commit is contained in:
parent
258eb17281
commit
70625f6ea1
14
.vscode/launch.json
vendored
Normal file
14
.vscode/launch.json
vendored
Normal 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
16
.vscode/tasks.json
vendored
Normal 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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -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)
|
||||
|
@ -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' })
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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[]
|
||||
|
Loading…
Reference in New Issue
Block a user