亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一文帶你搞懂Vue3如何使用訊飛大模型

 更新時(shí)間:2024年12月12日 08:38:12   作者:逆旅行天涯  
這篇文章主要為大家詳細(xì)介紹了Vue3使用訊飛大模型的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

初始化

首先構(gòu)建一個(gè)基礎(chǔ)腳手架項(xiàng)目

用到如下依賴

"dependencies": {
    "crypto-js": "^4.2.0",
    "highlight.js": "^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"
  }

修改 main.js

import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import PiniaPluginPersistedstate from "pinia-plugin-persistedstate"
import App from './App.vue'
import router from './router'
import highlight from 'highlight.js'
import "highlight.js/styles/atom-one-dark.css"
 
const app = createApp(App)
// 配置Pinia并設(shè)置持久化緩存
const pinia = createPinia()
pinia.use(PiniaPluginPersistedstate)
 
app.use(pinia)
app.use(router)
 
// 配置Markdown語法高亮
app.directive("highlight",function(el){
  let blocks = el.querySelectorAll('pre code');
  blocks.forEach((block)=>{
    highlight.highlightBlock(block);
  })
})
 
app.mount('#app')

TTSRecorder

新建 utils/TTSRecorder.js

這個(gè)文件封裝了發(fā)送消息并相應(yīng)消息的核心功能

import CryptoJS from "crypto-js"
const APPID = '' // 從控制臺(tái)可以獲取
const API_SECRET = '' // 從控制臺(tái)可以獲取
const API_KEY = '' // 從控制臺(tái)可以獲取
let total_res = "";
 
function getWebsocketUrl() {
  return new Promise((resolve, reject) => {
    var apiKey = API_KEY
    var apiSecret = API_SECRET
    // var url = 'ws://spark-api.xf-yun.com/v3.1/chat'
    var url = 'ws://spark-api.xf-yun.com/v1.1/chat'
    var host = location.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 = CryptoJS.enc.Base64.stringify(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} = {}) {
    this.appId = appId
    this.msgStore = null
    this.msgDom = null
  }
 
  // 連接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('瀏覽器不支持WebSocket')
        return
      }
      this.ttsWS = ttsWS
      ttsWS.onopen = e => {
        this.webSocketSend()
      }
      ttsWS.onmessage = e => {
        this.result(e.data)
      }
      ttsWS.onerror = e => {
        alert('WebSocket報(bào)錯(cuò),請(qǐng)f12查看詳情')
        console.error(`詳情查看:${encodeURI(url.replace('wss:', 'https:'))}`)
      }
      ttsWS.onclose = e => {
        console.log(e)
      }
    })
  }
 
 
  // websocket發(fā)送數(shù)據(jù)
  webSocketSend() {
    var params = {
      "header": {
        "app_id": this.appId,
      },
      "parameter": {
        "chat": {
          // 指定訪問的領(lǐng)域,general指向V1.5版本,generalv2指向V2版本,generalv3指向V3版本 。
          // 注意:不同的取值對(duì)應(yīng)的url也不一樣!
          // "domain": "generalv3",
          "domain": "lite",
          // 核采樣閾值。用于決定結(jié)果隨機(jī)性,取值越高隨機(jī)性越強(qiáng)即相同的問題得到的不同答案的可能性越高
          "temperature": 0.5,
          // 模型回答的tokens的最大長(zhǎng)度
          "max_tokens": 1024
        }
      },
      "payload": {
        "message": {
          "text": this.msgStore.list
        }
      }
    }
    console.log(params,'請(qǐng)求的參數(shù)')
    this.ttsWS.send(JSON.stringify(params))
  }
 
  start(msgStore,msgDom) {
    this.msgStore = msgStore
    this.msgDom = msgDom.value
    total_res = ""; // 請(qǐng)空回答歷史
    this.connectWebSocket().then(r => {})
  }
 
  // websocket接收數(shù)據(jù)的處理
  result(resultData) {
    let jsonData = JSON.parse(resultData)
    jsonData.payload.choices.text.forEach(res=>{
      this.msgStore.aiAddMsg(res.content,jsonData.header.status)
      this.msgDom.scrollTop = this.msgDom.scrollHeight + 500
    })
    // 提問失敗
    if (jsonData.header.code !== 0) {
      alert(`提問失敗: ${jsonData.header.code}:${jsonData.header.message}`)
      console.error(`${jsonData.header.code}:${jsonData.header.message}`)
      return
    }
    if (jsonData.header.code === 0 && jsonData.header.status === 2) {
      // 關(guān)閉WebSocket
      this.ttsWS.close()
    }
  }
}

msgStore

新建 stores/msgStore.js

用于存放歷史問題

import { defineStore } from 'pinia'
import { marked } from 'marked'
 
export const userMsgStore = defineStore("userMsgStore",{
  // 持久化
  persist: true,
  state: () => {
    return {
      list:[]
    }
  },
  actions: {
    userAddMsg(msg) {
      this.list.push({
        role:"user",
        content:msg,
        status:2
      })
    },
    aiAddMsg(content,status){
      let runMsg = this.list.find(i=>i.status !== 2)
      if(!runMsg){
        this.list.push({
          role:"assistant",
          content:content,
          status:status
        })
      }else{
        runMsg.content += content
        runMsg.status = status
        if(status === 2){
          runMsg.content = marked(runMsg.content)
        }
      }
    }
  },
})

編寫界面代碼

<template>
  <div class="content">
 
    <div class="message" id='message-box'>
      <div v-for="(msg,index) in msgList" :key="index" :class="{
          'user':msg.role === 'user',
          'assistant':msg.role === 'assistant'
        }">
        <div>
          <div>
            <img class='role-img' :src="userImg" v-if="msg.role === 'user'"/>
          </div>
          <div class='imgbox' v-if="msg.role === 'assistant'">
            <img class='role-img' :src="aiImg" />
            <div class='name'>訊飛AI</div>
          </div>
        </div>
        <div v-highlight v-html='msg.content'></div>
      </div>
    </div>
 
 
    <div class="footer">
      <textarea rows="5" placeholder="請(qǐng)輸入問題" class="text" v-model="msgValue"></textarea>
      <button class="btn" @click="submitMsg">發(fā)送</button>
    </div>
  </div>
</template>
 
<script setup>
import userImg from "@/assets/user.png"
import aiImg from "@/assets/ai.png"
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(()=>{
  msgDom.value = document.getElementById("message-box")
  msgList.value = msgStore.list
  scroll()
})
 
// 滾動(dòng)到最底部
const scroll = () => {
  nextTick(()=>{
    msgDom.value.scrollTop = msgDom.value.scrollHeight
  })
}
 
// 發(fā)送消息
const submitMsg = async () => {
  msgStore.userAddMsg(msgValue.value)
  msgValue.value = ""
  // 開始提問
  ttsRecorder.start(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>

main.css 修改

@import './base.css';
 
#app {
    height: 100vh;
    overflow: auto;
}

到此這篇關(guān)于一文帶你搞懂Vue3如何使用訊飛大模型的文章就介紹到這了,更多相關(guān)Vue3使用訊飛大模型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • antd form表單中如何嵌套自定義組件

    antd form表單中如何嵌套自定義組件

    這篇文章主要介紹了antd form表單中如何嵌套自定義組件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 詳解Vue CLI3 多頁應(yīng)用實(shí)踐和源碼設(shè)計(jì)

    詳解Vue CLI3 多頁應(yīng)用實(shí)踐和源碼設(shè)計(jì)

    這篇文章主要介紹了詳解Vue CLI3 多頁應(yīng)用實(shí)踐和源碼設(shè)計(jì),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • Vue和原生JS中如何使用自定義字體

    Vue和原生JS中如何使用自定義字體

    這篇文章主要為大家詳細(xì)介紹了Vue和原生JS中如何使用自定義字體,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解下
    2024-01-01
  • Vue引用vee-validate插件表單驗(yàn)證問題(cdn方式引用)

    Vue引用vee-validate插件表單驗(yàn)證問題(cdn方式引用)

    這篇文章主要介紹了Vue引用vee-validate插件表單驗(yàn)證問題(cdn方式引用),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Vue3+Vite項(xiàng)目使用less的實(shí)現(xiàn)步驟

    Vue3+Vite項(xiàng)目使用less的實(shí)現(xiàn)步驟

    最近學(xué)習(xí)在vite項(xiàng)目中配置less,本文主要介紹了Vue3+Vite項(xiàng)目使用less的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • 詳解Vue3怎么使用element-plus

    詳解Vue3怎么使用element-plus

    本文主要介紹了Vue3怎么使用element-plus,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Vue.js中的圖片引用路徑的方式

    Vue.js中的圖片引用路徑的方式

    當(dāng)我們?cè)赩ue.js項(xiàng)目中引用圖片時(shí),關(guān)于圖片路徑有以下幾種情形,下面通過本文給大家分享Vue.js中的圖片引用路徑的方式,感興趣的朋友一起看看吧
    2017-07-07
  • Element 默認(rèn)勾選表格 toggleRowSelection的實(shí)現(xiàn)

    Element 默認(rèn)勾選表格 toggleRowSelection的實(shí)現(xiàn)

    這篇文章主要介紹了Element 默認(rèn)勾選表格 toggleRowSelection的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • vue-cli配置文件——config篇

    vue-cli配置文件——config篇

    這篇文章主要介紹了vue-cli中的webpack是如何配置的,本篇文章主要是分析vue中關(guān)于config文件夾中的相關(guān)代碼,config的文件結(jié)構(gòu),感興趣的朋友參考下本文
    2018-01-01
  • vue2使用wangeditor實(shí)現(xiàn)手寫輸入功能

    vue2使用wangeditor實(shí)現(xiàn)手寫輸入功能

    這篇文章主要為大家詳細(xì)介紹了vue2如何使用wangeditor實(shí)現(xiàn)手寫輸入功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解下
    2023-12-12

最新評(píng)論