initialization
First build a basic scaffolding project
Use the following dependencies
"dependencies": { "crypto-js": "^4.2.0", "": "^11.9.0", "marked": "^9.1.3", "pinia": "^2.1.7", "pinia-plugin-persistedstate": "^3.2.0", "vue": "^3.3.4", "vue-router": "^4.2.5" }
Revise
import './assets/' import { createApp } from 'vue' import { createPinia } from 'pinia' import PiniaPluginPersistedstate from "pinia-plugin-persistedstate" import App from './' import router from './router' import highlight from '' import "/styles/" const app = createApp(App) // Configure Pinia and set persistent cacheconst pinia = createPinia() (PiniaPluginPersistedstate) (pinia) (router) // Configure Markdown syntax highlighting("highlight",function(el){ let blocks = ('pre code'); ((block)=>{ (block); }) }) ('#app')
TTSRecorder
Create new utils/
This file encapsulates the core function of sending messages and corresponding messages
import CryptoJS from "crypto-js" const APPID = '' // You can get it from the consoleconst API_SECRET = '' // You can get it from the consoleconst API_KEY = '' // You can get it from the consolelet total_res = ""; function getWebsocketUrl() { return new Promise((resolve, reject) => { var apiKey = API_KEY var apiSecret = API_SECRET // var url = 'ws:///v3.1/chat' var url = 'ws:///v1.1/chat' var host = var date = new Date().toGMTString() var algorithm = 'hmac-sha256' var headers = 'host date request-line' // var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v3.1/chat HTTP/1.1` var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v1.1/chat HTTP/1.1` var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret) var signature = .(signatureSha) var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"` var authorization = btoa(authorizationOrigin) url = `${url}?authorization=${authorization}&date=${date}&host=${host}` resolve(url) }) } export default class TTSRecorder { constructor({appId = APPID} = {}) { = appId = null = null } // Connect to websocket connectWebSocket() { return getWebsocketUrl().then(url => { let ttsWS if ('WebSocket' in window) { ttsWS = new WebSocket(url) } else if ('MozWebSocket' in window) { ttsWS = new MozWebSocket(url) } else { alert('The browser does not support WebSocket') return } = ttsWS = e => { () } = e => { () } = e => { alert('WebSocket error, please check the details for f12') (`View details:${encodeURI(('wss:', 'https:'))}`) } = e => { (e) } }) } // websocket sends data webSocketSend() { var params = { "header": { "app_id": , }, "parameter": { "chat": { // Specify the accessed realm, general points to V1.5 version, generalv2 points to V2 version, and generalv3 points to V3 version. // Note: The corresponding urls of different values are also different! // "domain": "generalv3", "domain": "lite", // Nuclear sampling threshold. Used to determine the randomness of the result. The higher the value, the stronger the randomness, that is, the higher the possibility of different answers obtained by the same question. "temperature": 0.5, // Maximum length of tokens answered by the model "max_tokens": 1024 } }, "payload": { "message": { "text": } } } (params,'Requested Parameters') ((params)) } start(msgStore,msgDom) { = msgStore = total_res = ""; // Please answer history ().then(r => {}) } // Processing of websocket receiving data result(resultData) { let jsonData = (resultData) (res=>{ (,) = + 500 }) // Failed to ask if ( !== 0) { alert(`Failed to ask a question: ${}:${}`) (`${}:${}`) return } if ( === 0 && === 2) { // Close WebSocket () } } }
msgStore
Create new stores/
Used to store historical issues
import { defineStore } from 'pinia' import { marked } from 'marked' export const userMsgStore = defineStore("userMsgStore",{ // Persistence persist: true, state: () => { return { list:[] } }, actions: { userAddMsg(msg) { ({ role:"user", content:msg, status:2 }) }, aiAddMsg(content,status){ let runMsg = (i=> !== 2) if(!runMsg){ ({ role:"assistant", content:content, status:status }) }else{ += content = status if(status === 2){ = marked() } } } }, })
Writing interface code
<template> <div class="content"> <div class="message" id='message-box'> <div v-for="(msg,index) in msgList" :key="index" :class="{ 'user': === 'user', 'assistant': === 'assistant' }"> <div> <div> <img class='role-img' :src="userImg" v-if=" === 'user'"/> </div> <div class='imgbox' v-if=" === 'assistant'"> <img class='role-img' :src="aiImg" /> <div class='name'>iFlytekAI</div> </div> </div> <div v-highlight v-html=''></div> </div> </div> <div class="footer"> <textarea rows="5" placeholder="Please enter a question" class="text" v-model="msgValue"></textarea> <button class="btn" @click="submitMsg">send</button> </div> </div> </template> <script setup> import userImg from "@/assets/" import aiImg from "@/assets/" import { nextTick, onMounted, ref } from 'vue' import TTSRecorder from "@/utils/TTSRecorder" import { userMsgStore } from '@/stores/msgStore' const msgStore = userMsgStore() const msgValue = ref("") let ttsRecorder = new TTSRecorder() const msgList = ref([]) let msgDom = ref(null) onMounted(()=>{ = ("message-box") = scroll() }) // Scroll to the bottomconst scroll = () => { nextTick(()=>{ = }) } // Send a messageconst submitMsg = async () => { () = "" // Start asking questions (msgStore,msgDom) scroll() } </script> <style scoped lang="less"> .content{ height: 100%; position: relative; .message{ position: absolute; top: 0; left: 20%; right: 20%; bottom: 150px; display: flex; overflow: auto; flex-direction: column; .user{ background-color: #ebf7f8; padding: 15px; box-sizing: border-box; display: flex; flex-direction: column; align-items: flex-end; border-bottom: 1px solid #dfdfdf; } .assistant{ background-color: #f7f7f7; padding: 15px; box-sizing: border-box; border-bottom: 1px solid #dfdfdf; } } .footer{ position: absolute; bottom: 50px; left: 20%; right: 20%; display: flex; align-items: flex-end; gap: 15px; .text{ width: 100%; } .btn{ width: 100px; height: 40px; background-color: #1a60ea; color: white; border: none; } } @media screen and (max-width: 768px) { .message,.footer { left: 0; right: 0; } .message{ bottom: 100px; } .footer{ bottom: 10px; } } } .imgbox{ display: flex; align-items: center; gap: 10px; margin-bottom: 10px; .name{ font-size: 13px; color: #fd919e; font-weight: 400; } } .role-img{ width: 40px; height: 40px; border-radius: 50%; overflow: hidden; } </style>
Revise
@import './'; #app { height: 100vh; overflow: auto; }
This is the article about this article about how to use iFlytek's big model in Vue3. For more related content on using iFlytek's big model, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!