Refactor(云灵AI):1、使用新模型逻辑对接;2、订单查询

This commit is contained in:
lifizer
2026-04-13 15:33:59 +08:00
parent 2f5b17da92
commit 2f5bb204bb
12 changed files with 1614 additions and 235 deletions
+36
View File
@@ -18,6 +18,29 @@ export const chatMixins = {
token: cookie.get('login_status'),
userInfo: cookie.get('userInfo'),
webUrl: this.$VUE_APP_RESOURCES_URL,
bottomTools: Object.freeze([
{
icon: 'icon-50',
text: '我要送礼',
type: 'prompt',
prompt: '我要送礼,请给我推荐一些平台的礼品',
url: ''
},
{
icon: 'icon-51',
text: '订单查询',
type: 'prompt',
prompt: '订单查询',
url: ''
},
{
icon: 'icon-52',
text: '拍照识图',
type: 'link',
prompt: '',
url: '/aiChat/views/imageRecognition'
}
]),
scrollData: {},
scrollTop: 0,
isScrollToBottom: false,
@@ -524,6 +547,19 @@ export const chatMixins = {
console.log('------------end')
this.isPlayAudio = false
}
},
bottomToolClickHandle(item) {
if (item.type === 'prompt') {
this.streamReq({
prompt: item.prompt,
init: 0
})
}
if (item.type === 'link') {
uni.navigateTo({
url: item.url
})
}
}
}
}
+556
View File
@@ -0,0 +1,556 @@
import {
getSseConfigV1,
getCompletionsV3,
deleteChatItemByConversationId,
// getAnalyzeKeywordsV1,
getAnalyzeKeywordsChangeV1
} from '@/api/chat/index'
import { VUE_APP_API_URL } from '@/config'
import settings from '@/config/baseSetting.js'
import { formatAiMsgContent } from '../utils/aiChat'
import cookie from '@/utils/store/cookie'
import { handleLoginFailure } from '@/utils'
const plugin = requirePlugin('WechatSI')
const removeMarkdown = require('remove-markdown')
export const chatMixinsV2 = {
data() {
return {
token: cookie.get('login_status'),
userInfo: cookie.get('userInfo'),
webUrl: this.$VUE_APP_RESOURCES_URL,
bottomTools: Object.freeze([
{
icon: 'icon-50',
text: '我要送礼',
type: 'prompt',
prompt: '我要送礼,请给我推荐一些平台的礼品',
url: ''
},
{
icon: 'icon-51',
text: '订单查询',
type: 'prompt',
prompt: '订单查询',
url: ''
},
{
icon: 'icon-52',
text: '拍照识图',
type: 'link',
prompt: '',
url: '/aiChat/views/imageRecognition'
}
]),
scrollData: {},
scrollTop: 0,
isScrollToBottom: false,
// 状态栏高度
statusBarHeight: 20,
fileHttpStr: Object.freeze(VUE_APP_API_URL + settings.sysPrefix),
keyboardHeight: 0,
optionsFrom: '',
onFocus: false,
loading: false,
chatNumber: '',
infoResData: {},
chatMessageList: [
/*
{
type: -2,
isError: false,
showCursor: false,
conversationId: '',
prompt: '',
nodes: '-------------监听 WebSocket 接受到服务器的消息事件',
content: '-------------监听 WebSocket 接受到服务器的消息事件',
listQuestion: [
'监听 WebSocket 接受到服务器的消息事件',
'监听 WebSocket 接受到服务器的消息事件',
'监听 WebSocket 接受到服务器的消息事件'
]
}
*/
],
errorMsg: Object.freeze('您提的问题未能理解,云灵思想跑偏啦,重新整理一下问题或者重新提问,让云灵再试试!'),
audioAyy: [],
isPlayAudio: false,
audioContext: null,
audioPlayId: ''
}
},
computed: {
chatMessageListLength() {
return this.chatMessageList.length
}
},
onPageScroll(e) {
this.scrollData = e
const scrollTop = e.scrollTop
this.scrollTop = scrollTop
const query = wx.createSelectorQuery().in(this)
query.select('#fixTbabarBody').boundingClientRect(function(rect) {
const contentHeight = rect.height
const windowInfo = wx.getWindowInfo()
const windowHeight = windowInfo.windowHeight
if (scrollTop + windowHeight + 30 >= contentHeight) {
this.isScrollToBottom = true
} else {
this.isScrollToBottom = false
}
}.bind(this)).exec()
},
onUnload() {
if (this.audioContext) {
this.audioContext.stop()
}
wx.getBackgroundAudioManager().stop()
this.closeWsFn()
},
created() {
const _this = this
uni.getSystemInfo({
success: (e) => {
let statusBar = 0
// #ifdef MP-WEIXIN
statusBar = e.statusBarHeight
const custom = uni.getMenuButtonBoundingClientRect()
_this.rightDistance = e.windowWidth - custom.left + 10
// #endif
// 状态栏高度
_this.statusBarHeight = statusBar
}
})
_this.createdCallbak()
},
methods: {
createdCallbak() {
console.log('页面初始话回调')
},
inputFocusHandle(value) {
this.onFocus = value === 1
this.scrollToBottomHandle()
},
historyViewHandle() {
console.log(this.$refs.historyView)
this.$refs.historyView.showView()
},
copyContentHandle(data) {
uni.setClipboardData({
data,
success: () => {
uni.showToast({
title: '已复制'
})
}
})
},
copyMoreInfoHandle(item) {
uni.setClipboardData({
data: JSON.stringify(item.showMoreInfo),
success: () => {
uni.showToast({
title: '已复制'
})
}
})
},
shareHandle() {
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline'],
success: (res) => {
console.log(res)
},
fail: err => {
console.log(err)
}
})
},
scrollToBottomHandle() {
uni.pageScrollTo({
duration: 100,
selector: '#bottom_postion'
})
this.isScrollToBottom = true
},
// 重新生成
regenerateHandle(item) {
this.audioStopHandle()
deleteChatItemByConversationId(item.conversationId).then(res => {
const { success } = res
if (success) {
this.chatMessageList.splice(this.chatMessageListLength - 1, 1)
this.streamReq({
prompt: item.prompt,
init: 1
})
}
})
},
// 建议提问
suggestionItemClickHandle(question) {
this.streamReq({
prompt: question,
init: 0
})
},
// 大家都在问
topicItemClickHandle(question) {
this.streamReq({
prompt: question,
init: 0
})
},
streamReq(params) {
const _this = this
// 需要校验登录状态
if (!_this.token) {
handleLoginFailure()
return
}
const prompt = params.prompt
if (params.init !== 1) {
_this.chatMessageList.push({
prompt,
type: -1
})
}
_this.$nextTick(() => {
_this.scrollToBottomHandle()
})
_this.chatMessageList.push({
content: '',
nodes: '',
isError: false,
showCursor: false,
conversationId: '',
prompt,
listQuestion: [],
orderList: [],
type: -2,
showMoreInfo: {}
})
_this.loading = true
_this.showCursor = false
getSseConfigV1({
'chatNumber': _this.chatNumber,
prompt
}).then(resConfig => {
const conversationId = resConfig.data.conversationId
_this.chatNumber = resConfig.data.chatNumber || ''
_this.chatMessageList[_this.chatMessageListLength - 1].showCursor = true
_this.chatMessageList[_this.chatMessageListLength - 1].conversationId = conversationId
if (conversationId) {
_this.initWebSocket(conversationId, () => {
getCompletionsV3({
conversationId,
ws: true,
isNoNeedPublicErrorNotification: 1
}).then(sseRes => {
console.log(sseRes)
// _this.closeWsFn()
}).catch(err => {
console.log(err)
_this.chatErrorSetContent()
})
})
} else {
_this.chatErrorSetContent()
}
}).catch(err => {
console.log(err)
_this.chatErrorSetContent()
})
},
initWebSocket(conversationId, cb) {
const _this = this
console.log('------------------创建连接')
uni.connectSocket({
url: VUE_APP_API_URL.replace('https', 'wss') + settings.sysPrefix + `v1/chat/websocket/${_this.userInfo.unionId}`,
header: {
'content-type': 'application/json'
},
timeout: 10 * 1000,
success: () => {
console.log('------------WebSocket初始化成功')
},
fail: (err) => {
uni.showModal({
showCancel: false,
content: err
})
}
})
uni.onSocketMessage(res => {
_this.websocketOnmessage(res)
})
uni.onSocketOpen(() => {
cb && cb()
_this.websocketOnopen()
})
uni.onSocketError(err => {
_this.websocketOnerror(err)
})
},
websocketOnmessage(res) {
console.log('-------------监听 WebSocket 接受到服务器的消息事件')
const resData = JSON.parse(res.data)
if (resData) {
console.log(resData)
const message = resData.message
if (message && this.chatMessageListLength > 1) {
const mesContent = message.content
const contentType = message.contentType
const finish = message.finish
// todo:判断是文本还是列表
if (contentType ==='text') {
if (!finish && mesContent) {
this.chatMessageList[this.chatMessageListLength - 1].nodes = formatAiMsgContent(mesContent)
this.chatMessageList[this.chatMessageListLength - 1].content = mesContent
this.chatMessageList[this.chatMessageListLength - 1].listQuestion = message.listQuestion || []
}
}
if (contentType ==='order') {
if (!finish && message.listCards) {
this.chatMessageList[this.chatMessageListLength - 1].orderList = message.listCards || []
}
}
this.$forceUpdate()
this.$nextTick(() => {
this.scrollToBottomHandle()
if (finish) {
this.closeWsFn()
}
})
}
}
},
websocketOnopen() {
console.log('------------------监听 WebSocket 连接打开事件')
// this.websocketSend(JSON.stringify({ msg: '1' }))
},
websocketOnerror(e) {
console.log('-----------------监听 WebSocket 错误事件')
console.log(e)
},
websocketSend(msg) {
// 数据发送
try {
uni.sendSocketMessage({
data: msg,
success: () => {
console.log('-----------发送消息成功了')
}
})
} catch (err) {
console.log('send failed (' + err.code + ')')
}
},
analyzeKeywordsChangeHandle(conversationId, showMoreInfo) {
getAnalyzeKeywordsChangeV1({
conversationId,
...showMoreInfo
}).then(res => {
const { success, data } = res
if (success) {
let resultItems = []
let idx = -1
this.chatMessageList.map((item, index) => {
if (item.conversationId === conversationId) {
resultItems = data.resultItems || []
idx = index
}
})
if (idx > -1) {
this.$set(this.chatMessageList[idx].showMoreInfo, 'resultItems', resultItems)
this.$forceUpdate()
}
}
})
},
productItemClickHandle(item) {
this.audioStopHandle()
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: {
id: item.id
}
})
},
hotelItemClickHandle(item) {
this.audioStopHandle()
this.$yrouter.push({
path: '/pagesInn/inn/innHome',
query: {
id: item.id
}
})
},
ichItemClickHandle(item) {
this.audioStopHandle()
this.$yrouter.push({
path: '/pkg_product/views/heritage/details',
query: {
id: item.id
}
})
},
qianxianItemClickHandle(item) {
this.audioStopHandle()
this.$yrouter.push({
path: '/pkg_product/views/famousQianxianShop',
query: {
id: item.id
}
})
},
prizeItemClickHandle() {
this.audioStopHandle()
this.$yrouter.push({ path: '/pkg-video/views/lottery' })
},
chatErrorSetContent() {
this.chatMessageList[this.chatMessageListLength - 1].isError = true
this.chatMessageList[this.chatMessageListLength - 1].content = this.errorMsg
this.chatMessageList[this.chatMessageListLength - 1].nodes = this.errorMsg
this.closeWsFn()
},
closeWsFn() {
this.loading = false
if (this.chatMessageListLength) {
this.chatMessageList[this.chatMessageListLength - 1].showCursor = false
}
uni.closeSocket({
success: () => {
console.log('-----关闭连接')
}
})
this.$nextTick(() => {
this.scrollToBottomHandle()
})
},
audioStopHandle() {
// Fix bug#4049
this.audioAyy = []
if (this.audioContext) {
this.audioContext.stop()
}
this.isPlayAudio = false
wx.getBackgroundAudioManager().stop()
},
ttsHandle(item) {
this.audioAyy = []
if (this.audioContext) {
this.audioContext.stop()
// this.audioContext.destroy()
}
// 如果正在播放,点击当前播放的则认为是暂停
if (this.isPlayAudio && item.conversationId === this.audioPlayId) {
this.isPlayAudio = false
this.audioPlayId = ''
return
}
this.isPlayAudio = false
this.audioPlayId = item.conversationId
const flag = 1
if (flag === 1) {
console.log(removeMarkdown(item.content).replace(/[\n\t\s]/g, ''))
uni.showLoading({
title: '合成中...'
})
this.splitAndSynthesize(removeMarkdown(item.content).replace(/[\n\t\s]/g, ''))
} else {
// 调试数据
this.audioAyy = [
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749075_2f71887cc48d9b3753c39d119862d4bb&filekey=871027724&source=miniapp_plugin',
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749077_0970508786c5e3edc3a68a5eb9de048c&filekey=871027724&source=miniapp_plugin',
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749079_e77cec52cc077ba981892887c3df4cdf&filekey=871027724&source=miniapp_plugin',
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749080_02db4235771f5561cdb73c06d8c67e53&filekey=871027724&source=miniapp_plugin',
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749082_534e455c5d6ac5e9a4192ecf9952851a&filekey=871027724&source=miniapp_plugin',
'https://ae.weixin.qq.com/cgi-bin/mmasrai-bin/getmedia?filename=1750749083_78c4a2fecad538561f81c48dc4ecd645&filekey=871027724&source=miniapp_plugin'
]
this.playNextChunk()
}
},
splitAndSynthesize(text) {
const _this = this
if (text) {
const textLength = text.length
const chunkSize = 100
const chunk = text.slice(0, textLength > chunkSize ? chunkSize : textLength)
plugin.textToSpeech({
// 语言
lang: 'zh_CN',
tts: true,
// 要转换的文字
content: chunk,
success: function(res) {
console.log("语音文件路径:", res.filename)
_this.audioAyy.push(res.filename)
// 首次就立即播放,增强体验
if (!_this.isPlayAudio) {
_this.playNextChunk()
}
if (textLength > chunkSize) {
// 递归调用,播放一定要按照文本分割顺序
_this.splitAndSynthesize(text.substr(chunkSize, textLength))
} else {
// 最后一条合成,没有正在播放则立即播放
if (!_this.isPlayAudio) {
_this.playNextChunk()
}
}
uni.hideLoading()
},
fail: function(err) {
console.log("转换失败:", err)
uni.hideLoading()
}
})
} else {
if (!_this.isPlayAudio) {
_this.playNextChunk()
}
uni.hideLoading()
}
},
playNextChunk() {
if (this.audioAyy.length > 0 && this.audioPlayId) {
const src = this.audioAyy.shift()
this.isPlayAudio = true
const audioContext = uni.createInnerAudioContext({
// 是否使用 WebAudio 作为底层音频驱动,默认关闭。对于短音频、播放频繁的音频建议开启此选项,开启后将获得更优的性能表现。由于开启此选项后也会带来一定的内存增长,因此对于长音频建议关闭此选项
useWebAudioImplement: false
})
this.audioContext = audioContext
audioContext.src = src
audioContext.onEnded(() => {
audioContext.destroy()
this.playNextChunk()
})
audioContext.play()
console.log('------------src:' + src)
} else {
console.log('------------end')
this.isPlayAudio = false
}
},
bottomToolClickHandle(item) {
if (item.type === 'prompt') {
this.streamReq({
prompt: item.prompt,
init: 0
})
}
if (item.type === 'link') {
uni.navigateTo({
url: item.url
})
}
},
viewOrderTrackHandle(order) {
uni.navigateTo({
url: '/pages/order/OrderDetails/index?id=' + order.orderId
})
}
}
}