feat: 测试之后修改bug

This commit is contained in:
常东方 2025-06-09 17:38:54 +08:00
parent 81fb19092e
commit b1d2fd47c4
4 changed files with 218 additions and 135 deletions

View File

@ -52,6 +52,7 @@
"build:app-ios": "uni build -p app-ios",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5-dev": "uni build --mode dev",
"build": "uni build",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "uni build -p mp-alipay",

View File

@ -160,7 +160,7 @@
v-for="(file, fileIdx) in msg.content"
:key="fileIdx"
style="flex: 0 0 6rem"
class="relative text-xs h-32 w-80 rounded-md overflow-hidden mr-1 c-black"
class="relative text-xs h-32 rounded-md overflow-hidden mr-1 c-black"
>
<!-- @click="previewVideo(msg.content)"-->
<video
@ -184,11 +184,17 @@
</view>
</view>
<view
v-if="msg.role === 'assistant' && msg.type === 'text'"
v-if="
msg.role === 'assistant' && msg.type === 'text' && messages.length - 1 === idx
"
class="absolute bottom--3.5 flex space-x-3 ml-1"
>
<image src="/static/aichat/copy.png" class="w-4 h-4" @click="copyText(msg)" />
<image src="/static/aichat/resect.png" class="w-4.3 h-4" @click="refreshText()" />
<image
src="/static/aichat/resect.png"
class="w-4.3 h-4"
@click="refreshText(msg)"
/>
</view>
</view>
<image
@ -332,6 +338,7 @@
@focus="onFocus"
@confirm="sendText"
placeholder="想对我说点什么~"
maxlength="5000"
class="flex-1 h-10 px-3 border border-gray-100 bg-[#f9f9f9] rounded-1 focus:outline-none"
/>
<!-- 将keyup替换为confirm -->
@ -349,7 +356,6 @@
v-if="sendTextLoading && inputText.length <= 0"
src="/static/aichat/enter-no.png"
class="w-7 h-7"
@click="sendText()"
:disabled="loading"
:class="[knowledgeOpen ? 'ml-2' : 'ml-0']"
/>
@ -477,6 +483,7 @@
import { ref, reactive, nextTick, watchEffect, watch } from 'vue'
import dayjs from 'dayjs'
import { useUserStore } from '@/store'
// import store from '@/store'
import { getEnvBaseUrl } from '@/utils'
import guid from '@/utils/guid.js'
import type { IGptRequestBody } from '@/service/index/foo'
@ -489,15 +496,16 @@ import {
officeFileTypeList as fileType,
videoFileType as videoType,
picFileType as picType,
isJsonObject,
} from './utils/index'
import 'dayjs/locale/zh-cn'
import { showToastErr, showToastOk, time_format3 } from '@/utils/tools'
import { uploadFileChunk } from './utils/api.js'
// import { TOKEN, AVATAR } from './utils/test'
import { deepClone } from 'wot-design-uni/components/common/util'
import { log } from 'console'
dayjs.locale('zh-cn')
const store = useUserStore()
interface UploadFile {
id: string
@ -605,7 +613,7 @@ async function createChatSession() {
gptModel: chatMode.value,
},
header: {
Authorization: token.value,
// Authorization: token.value,
},
})
// listUuid
@ -627,9 +635,9 @@ const state = reactive({
})
const scrollTop = ref(0)
async function fetchHistoryList() {
// if(state.page*state.pageSize>state.total && state.total!==null){
// return
// }
if (state.page >= state.total / state.pageSize + 1 && state.total !== null) {
return
}
if (state.loading) {
return
}
@ -643,12 +651,18 @@ async function fetchHistoryList() {
pageSize: state.pageSize,
},
header: {
Authorization: token.value,
// Authorization: token.value,
},
})
if (resp.data && resp.data.data) {
rawList.value = rawList.value.concat(resp.data.data.data)
state.total = resp.data.data.count //Math.ceil(resp.data.count/state.page)
if (state.total === null) {
rawList.value = resp.data.data.data
state.total = resp.data.data.count
} else {
rawList.value = rawList.value.concat(resp.data.data.data)
state.total = resp.data.data.count //Math.ceil(resp.data.count/state.page)
}
// scrollTop.value+=60;
}
} catch (err) {
@ -662,7 +676,10 @@ const scrolltolowerLoadData = (e) => {
}
watch(
() => state.page,
async () => {
async (newval) => {
if (newval <= 0) {
return
}
await fetchHistoryList()
},
{ deep: true },
@ -670,9 +687,12 @@ watch(
async function openPopup() {
state.page++
showPopup.value = true
rawList.value = []
}
function closePopup() {
showPopup.value = false
state.page = 0
state.total = null
}
function toggleFullscreen() {
fullscreen.value = !fullscreen.value
@ -689,12 +709,12 @@ async function fetchHistoryDiets(value) {
gptModel: chatMode.value,
},
header: {
Authorization: token.value,
// Authorization: token.value,
},
})
if (resp && resp.data && resp.data.data) {
const rawList = resp.data.data.detail //
listUuid.value = resp.data.data.listUuid
const rawList = resp?.data?.data?.detail //
listUuid.value = resp?.data?.data?.listUuid
// const newMessages = parseBackendMessages(JSON.parse(rawList))
//
messages.splice(0, messages.length, ...JSON.parse(rawList))
@ -971,18 +991,30 @@ onMounted(async () => {
try {
const init = async () => {
const wv = plus.webview.currentWebview() // Webview
token.value = wv.token || uni.getStorageSync('token') || import.meta.env.VITE_DEV_TOKEN
token.value =
wv.token ||
uni.getStorageSync('token') ||
store.userInfo.token ||
import.meta.env.VITE_DEV_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
store.setUserInfo({
token: token.value,
avatar: userInfo.value.Avatar,
refreshToken: refreshToken.value,
statusBarHeight: statusBarHeight.value,
})
await createChatSession()
}
init()
} catch (e) {
console.error('onMounted e: ', e)
} finally {
token.value = store.userInfo.token
await createChatSession()
}
})
@ -1411,12 +1443,60 @@ const onPickImage = () => {
},
})
}
// Android API
const onPickVideo3 = () => {
var cmr = plus.camera.getCamera()
try {
cmr.startVideoCapture(
() => {
alert('ok')
},
() => {
alert('err')
},
{},
)
} catch (e) {
} finally {
cmr.stopVideoCapture()
}
}
//
const onPickVideo = () => {
uni.chooseVideo({
sourceType: ['album', 'camera'],
// sourceType: ['album', 'camera'],
sourceType: ['album'],
maxDuration: 60,
compressed: true,
camera: 'back',
albumMode: 'custom',
// extension: uploadConfig.video.supportType,
success: (res: any) => {
console.log(res)
const tempFile = res.tempFile
tempFile.path = res.tempFilePath
//
addUploadQueue([tempFile], uploadFileTypeEm.video)
},
fail: (err) => {
uni.showToast({
title: '选取视频失败',
icon: 'none',
})
},
})
}
//
const onPickVideo2 = () => {
uni.chooseVideo({
sourceType: ['album', 'camera'],
maxDuration: 60,
compressed: true,
camera: 'back',
// extension: uploadConfig.video.supportType,
success: (res: any) => {
console.log(res)
@ -1561,7 +1641,6 @@ const stopMsg = () => {
stopStreamMsg = true
}
async function sendText() {
console.log('uploadList: ', uploadList)
if (uploadList.length > 0) {
const isUpLoading = uploadList.some((file) => {
// return file.status==="error" || file.status==="pending"
@ -1578,18 +1657,16 @@ async function sendText() {
}
}
const msg = inputText.value.trim()
if (!msg && !refreshSend.value) {
if (!msg) {
return showToastErr('不可以发送空消息!')
}
// if (uploadList.length > 0) {
// return showToastErr('!')
// }
if (!sendTextLoading.value) {
sendTextLoading.value = true
return showToastErr('正在接收消息请稍后')
}
//
sendTextLoading.value = false
//
// +
@ -1741,16 +1818,16 @@ async function sendText() {
}
}
} else {
if (!refreshSend.value) {
//
addMessage({
role: 'user',
type: 'text',
content: msg,
timestamp: new Date(),
mask: 'new',
})
}
// if (!refreshSend.value) {
//
addMessage({
role: 'user',
type: 'text',
content: msg,
timestamp: new Date(),
mask: 'new',
})
// }
//
chatMode.value = 'tongyi-app' //'tongyi-app'; qwen-long
@ -1782,7 +1859,6 @@ async function sendText() {
// +
//
console.log('message: ', messages)
uploadList.splice(0, uploadList.length) //
const list = formatData(messages)
@ -1790,9 +1866,38 @@ async function sendText() {
body.detail = JSON.stringify(messages)
aiMsg.content = ''
addMessage(aiMsg)
send(body)
// return
// return
//
}
const spliceMsg = (list, model) => {
let file = false
let image = false
let video = false
const length = list.length
console.log(list)
for (let i = length - 1; i >= 0; i--) {
const item = list[i]
if (model === 'tongyi-long' && item.type === 'image' && item.type === 'video') {
const index = length - i - 1
return list.splice(i - 1)
} else if (model !== 'tongyi-long' && item.type === 'file') {
const index = i
return list.splice(index + 1)
}
}
return list
}
const send = async (body) => {
// refreshSend.value = true; //
//
sendTextLoading.value = false //
const [aiMsg] = messages.slice(-1)
const recordList = messages.slice(0, messages.length - 1)
body.detail = JSON.stringify(recordList)
// body.messages = spliceMsg(body.messages, chatMode.value)
try {
// aiMsg.content = ''
//
@ -1801,10 +1906,14 @@ async function sendText() {
const signal = controller.signal
const resp = await fetch(baseUrl + '/chat/app/completion', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: token.value },
headers: {
'Content-Type': 'application/json',
Authorization: token.value,
},
body: JSON.stringify(body),
signal: signal,
})
console.log(resp)
const reader = resp.body!.getReader()
const decoder = new TextDecoder()
@ -1839,13 +1948,17 @@ async function sendText() {
const json = JSON.parse(chunk)
const delta = json.choices?.[0]?.delta?.content
if (delta) {
msgLoading.value = false
aiMsg.content += delta
// msgLoading.value = false
//messages
messages[messages.length - 1] = { ...aiMsg }
scrollToBottom()
}
} catch {}
} catch (e) {
console.log(e)
} finally {
console.log('over')
}
}
//
@ -1871,6 +1984,13 @@ async function sendText() {
console.log('chunk------------------: ')
}
}
if (isJsonObject(buffer)) {
const response = JSON.parse(buffer)
if (response.code === 401) {
showToastErr('请重新登录')
}
}
scrollToBottom()
} catch (err) {
// aiMsg.content = ''
@ -1880,7 +2000,7 @@ async function sendText() {
} finally {
sendTextLoading.value = true
showActions.value = false
refreshSend.value = false //
// refreshSend.value = false //
msgLoading.value = false
}
}
@ -1899,7 +2019,16 @@ function copyText(msg: IMessage) {
}
}
function refreshText() {
const msgType = (msg) => {
return (
msg &&
msg.role === 'user' &&
(msg.type === 'text' || msg.type === 'image' || msg.type === 'video')
)
}
function refreshText(msg) {
console.log('refresh msg', msg)
if (!sendTextLoading.value) {
//
return
@ -1910,98 +2039,57 @@ function refreshText() {
// 1.
const userMessages = messages.filter((msg) => msg.role === 'user')
// const lastTwoUserMsgs = userMessages.slice(-2)
const [msg1, msg2] = deepClone(userMessages.slice(-2))
// let text=lastTwoUserMsgs[0] // lastTwoUserMsgs.every((msg)=>msg.type==="text" || msg.type==="image" || msg.type==="video" || msg.type==="file")
// let file=lastTwoUserMsgs[1] // lastTwoUserMsgs.every((msg)=>msg.type==="text" || msg.type==="image" || msg.type==="video" || msg.type==="file")
// const [msg1, msg2, msg3] = deepClone(userMessages.slice(-3))
const newMsgArr = deepClone(userMessages.slice(-3))
// 2.
let refreshText = null
let text = null
const refreshFiles: UploadFile[] = []
if (msg1 && msg1.type === 'text' && msg2 && msg2.type !== 'text') {
msg1.mask = 'new'
msg2.mask = 'new'
refreshFiles.push(msg1)
refreshFiles.push(msg2)
} else if (msg1.type === 'text' && msg1.role === 'user' && !msg2) {
msg1.mask = 'new'
refreshFiles.push(msg1)
} else if (msg2.type === 'text' && msg2.role === 'user' && !msg1) {
msg2.mask = 'new'
refreshFiles.push(msg2)
} else {
msg2.mask = 'new'
refreshFiles.push(msg2)
for (let i = newMsgArr.length - 1; i >= 0; i--) {
const msg = newMsgArr[i]
if (msg.type === 'text') {
refreshFiles.unshift(msg)
break
} else {
refreshFiles.unshift(msg)
}
}
// lastTwoUserMsgs.forEach((msg,i) => {
// console.log('msg: ',msg);
// if (msg.type === 'text' && msg.role==="user") {
// refreshText = msg.content //
// refreshFiles.push({
// content:msg.content,
// type:"text",
// role:"user",
// timestamp:new Date(),
// mask:"new"
// })
// } else if(msg.type==="video"){
// msg.mask="new"
// refreshFiles.push(msg)
// // msg.content.forEach((file : any) => {
// // console.log('lastTwoUserMsgs file: ',file);
// // refreshFiles.push({
// // id: guid.getGuid(),
// // url: file.video_url.url,
// // status: 'success',
// // name: file.name || '',
// // size: file.size || 0,
// // uploadFileType: file.uploadFileType || detectFileType(file.video_url.url),
// // })
// // })
// }else if(msg.type==="image"){
// msg.mask="new"
// refreshFiles.push(msg)
// // msg.content.forEach((file : any) => {
// // console.log('lastTwoUserMsgs file: ',file);
// // refreshFiles.push({
// // id: guid.getGuid(),
// // url: file.image_url.url,
// // status: 'success',
// // name: file.name || '',
// // size: file.size || 0,
// // uploadFileType: file.uploadFileType || detectFileType(file.image_url.url),
// // })
// // })
// }else{
// msg.mask="new"
// refreshFiles.push(msg)
// // msg.content.forEach((file : any) => {
// // console.log('lastTwoUserMsgs file: ',file);
// // refreshFiles.push({
// // id: guid.getGuid(),
// // url: file.content,
// // status: 'success',
// // name: file.name || '',
// // size: file.size || 0,
// // uploadFileType: file.uploadFileType || detectFileType(file.content),
// // })
// // })
// }
// })
// 3.
// inputText.value = refreshText
// inputText.value = text
// uploadList.splice(0, uploadList.length, ...refreshFiles)
refreshFiles.forEach((ele) => {
messages.push(ele)
})
refreshSend.value = true
// inputText.value = refreshText
// return
// refreshSend.value = true
// inputText.value = text
// 4.
setTimeout(() => {
sendText()
}, 100)
// setTimeout(() => {
// sendText()
// }, 100)
let list = formatData(messages)
const aiMsg = {
role: 'assistant',
type: 'text',
content: '',
timestamp: new Date(),
}
messages.push(aiMsg)
const body = {
model: chatMode.value, //
max_tokens: 1000,
top_p: 1,
presence_penalty: 0,
frequency_penalty: 0,
messages: list, // text ? [aiMsg] : historyUserMsgs,
stream: true,
listUuid: listUuid.value,
// listUuid:"eff18a10-1719-4528-ad63-ee5c01d0a412"
}
send(body)
}
// URL

View File

@ -202,4 +202,6 @@ async function sendText1(msgData = '') {
loading.value = false
showActions.value = false
}
}
}
export const TOKEN="79b5c732d96d2b27a48a99dfd4a5566c43aaa5796242e854ebe3ffc198d6876b9628e7b764d9af65ab5dbb2d517ced88170491b74b048c0ba827c0d3741462cb89dc59ed46653a449af837a8262941ca1430937103230a1e32a1715f569f3efdbe6f8cb8b7b8642bd679668081b9b08f693d1b5be6002d936ec51e1e3e0c4927de9e32ac99a109b326e5d2bda27ec87624bb416ec70d2a95a2e190feeba9f0d6bae8571b3dfe89c824712344759a8f2bff9d70747c52525cf6a5614f9c770bca461a9b9c247b6dca97bcf83bbaf99bb726752c4fe1e9a4aa7de5c4cf3e88a3e480801280d45cdc124f9d8221105d852945dc6ce10bc1647e4f09dff4d52ffdfcd57b2349fd3262098015f94b8786aabc0d8a8098a126bf2449839db7ded893783707a3f776e4ff20f9e79ce24ba97e5f82085d12a8e518fe6dedcd453a773bb4cb26657088a4b3cd06b62cd9f9738196"

View File

@ -5,6 +5,10 @@ export const fileSuffix = (str) => {
let reg = /\.\w*$/
return str.match(reg)[0]
}
export const isJsonObject = (json) => {
const str = json.trim()
return str.startsWith('{') && str.endsWith('}')
}
export const officeFileTypeList = ['.docx', '.doc', '.xls', '.xlsx', '.pdf', '.txt']
export const videoFileType = ['.mp4', '.mov', '.wmv']
export const picFileType = ['.jpg', '.png', '.jpeg']
@ -112,7 +116,7 @@ export function formatData(list) {
result.push({
role: 'user',
content: content,
type: 'image',
type: item.type,
mask: item.mask,
})
} else if (item.type === 'file') {
@ -171,15 +175,3 @@ export async function readFile(file, chunkSize = 10 * 1024 * 1024) {
const buffer = await blob.blob()
return sliceFile(buffer, chunkSize)
}
function uploadChunkFile({ chunk, fileName }, index, total, fileId) {
const formData = new FormData()
formData.append('Chunk', chunk)
formData.append('ChunkFileName', `${fileName}_${index}`)
formData.append('total', total)
formData.append('UseType', 100)
formData.append('FileName', fileName)
formData.append('Source', 'aiChat')
formData.append('UseType', 100)
return
}