import { getSseConfigV1, getCompletions, deleteChatItemByConversationId } 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' export const chatMixins = { data() { return { token: cookie.get('login_status'), userInfo: cookie.get('userInfo'), webUrl: this.$VUE_APP_RESOURCES_URL, scrollData: {}, scrollTop: 0, isScrollToBottom: false, // 状态栏高度 statusBarHeight: 20, fileHttpStr: Object.freeze(VUE_APP_API_URL + settings.sysPrefix), optionsFrom: '', loading: false, chatNumber: '', infoResData: {}, chatMessageList: [ /* { type: -2, isError: false, showCursor: false, conversationId: '', prompt: '', nodes: '-------------监听 WebSocket 接受到服务器的消息事件', content: '-------------监听 WebSocket 接受到服务器的消息事件', listQuestion: [ '监听 WebSocket 接受到服务器的消息事件', '监听 WebSocket 接受到服务器的消息事件', '监听 WebSocket 接受到服务器的消息事件' ] } */ ], errorMsg: Object.freeze('您提的问题未能理解,云灵思想跑偏啦,重新整理一下问题或者重新提问,让云灵再试试!') } }, 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() }, 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('页面初始话回调') }, copyContentHandle(data) { uni.setClipboardData({ data, 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) { 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 } _this.initWebSocket(() => { 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: [], type: -2 }) _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 getCompletions({ conversationId, ws: true, isNoNeedPublicErrorNotification: 1 }).then(sseRes => { console.log(sseRes) // _this.closeWsFn() }).catch(err => { console.log(err) _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() }) }).catch(err => { console.log(err) _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 this.chatMessageList[this.chatMessageListLength - 1].showCursor = false uni.closeSocket({ success: () => { console.log('-----关闭连接') } }) this.$nextTick(() => { this.scrollToBottomHandle() }) }, initWebSocket(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) { const message = resData.message if (message && this.chatMessageListLength > 1) { const mesContent = message.content this.chatMessageList[this.chatMessageListLength - 1].nodes = formatAiMsgContent(mesContent) this.chatMessageList[this.chatMessageListLength - 1].content = mesContent this.chatMessageList[this.chatMessageListLength - 1].listQuestion = message.listQuestion || [] this.$forceUpdate() this.$nextTick(() => { this.scrollToBottomHandle() if (message.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 + ')') } } } }