关于ElectronVue3中集成讯飞星火AI
前言:我的最终目的是为了在QQ上集成一个AI机器人,因此在这里先实现一个简单的集成
先上效果图

总体还是很简单的,我在调用websock获取回复内容的基础上另外集成了一个事件总线,让我们在调用获取消息的时候能够更加方便快捷
工具代码如下:
import CryptoJS from 'crypto-js'export function getWebsocketUrl(API_KEY: string, API_SECRET: string) {return new Promise((resolve, reject) => {var apiKey = API_KEYvar apiSecret = API_SECRETvar url = 'wss://spark-api.xf-yun.com/v1.1/chat'var host = location.hostvar date = new Date().toGMTString()var algorithm = 'hmac-sha256'var headers = 'host date request-line'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 {appId: string;apiKey: string;apiSecret: string;status: string;onWillStatusChange: any;ttsWS: any;content: string;revertText: string;_events: any[];constructor(appId: string, API_KEY: string, API_SECRET: string) {this.appId = appIdthis.apiKey = API_KEYthis.apiSecret = API_SECRETthis._events = [];this.status = 'init'}// 修改状态setStatus(status: string) {this.onWillStatusChange && this.onWillStatusChange(this.status, status)this.status = status}// 连接websocketconnectWebSocket() {this.setStatus('ttsing')return getWebsocketUrl(this.apiKey, this.apiSecret).then(url => {let ttsWSif ('WebSocket' in window) {ttsWS = new WebSocket(url as string)} else if ('MozWebSocket' in window) {ttsWS = new MozWebSocket(url)} else {alert('浏览器不支持WebSocket')return}this.ttsWS = ttsWSttsWS.onopen = e => {this.webSocketSend()}ttsWS.onmessage = e => {this.result(e.data)}ttsWS.onerror = e => {clearTimeout(this.playTimeout)this.setStatus('error')alert('WebSocket报错,请f12查看详情')console.error(`详情查看:${encodeURI(url.replace('wss:', 'https:'))}`)}ttsWS.onclose = e => {console.log(e)}})}// websocket发送数据webSocketSend() {var params = {"header": {"app_id": this.appId,"uid": "fd3f47e4-d"},"parameter": {"chat": {"domain": "general","temperature": 0.5,"max_tokens": 1024}},"payload": {"message": {"text": [{"role": "user","content": this.content}]}}}console.log(JSON.stringify(params))this.ttsWS.send(JSON.stringify(params))}start(text: string) {this.revertText = ""; // 请空回答历史this.content = textthis.connectWebSocket()}// websocket接收数据的处理result(resultData: string) {let jsonData = JSON.parse(resultData)// 提问失败if (jsonData.header.code !== 0) {const data = {code: jsonData.header.code,content: jsonData.header.message}this.emit('error', data)return}if (jsonData.header.code === 0 && jsonData.header.status === 2) {this.ttsWS.close()this.setStatus("init")this.emit('message', {content: this.revertText,code: 0})this.emit('endRecord', {content: this.revertText,code: 0})}// 记录回答const textArr = jsonData.payload.choices.text && jsonData.payload.choices.text.map(item => item.content) || []this.revertText = this.revertText + textArr.join('')}on(event: string, fn: Function) {if (Array.isArray(event)) {for (let i = 0, l = event.length; i < l; i++) {this.on(event[i], fn)}} else {// 存在直接push, 不存在创建为空数组再push(this._events[event] || (this._events[event] = [])).push(fn)}}once(event: string, fn: Function) {let _self = this;function handler() {_self.off(event, handler);fn.apply(null, arguments);//emit里面调用时会给on方法传参}handler.fn = fn;//off里面根据这个判断销毁事件this.on(event, handler);}off(event: string, fn: Function) {//不传参数表示清空所有if (!arguments.length) {this._events = [];}//数组循环清空if (Array.isArray(event)) {for (let i = 0, l = event.length; i < l; i++) {this.off(event[i], fn)}}const cbs = this._events[event];if (!cbs) {return;}//不传第二参表示清空某事件所有监听函数if (arguments.length == 1) {this._events[event] = null}let cb, i = cbs.lengthwhile (i--) {cb = cbs[i]if (cb === fn || cb.fn === fn) { //cb.fn===fn用来移除once注册的事件cbs.splice(i, 1)break}}}emit(event: string, ...args: any[]) {console.log(args, typeof args)// 不存在event,直接返回if (!this._events[event]) {return}let cbs = [...this._events[event]];if (cbs) {for (let i = 0, l = cbs.length; i < l; i++) {try {cbs[i].apply(null, [...arguments].slice(1))} catch (e) {new Error(`event handler for "${e}"`)}}}}
}
不管你是想一次性接收到所有的内容,还是想像官方一样一点一点的接收,都能很方便的使用,视图调用代码如下:
const xfConfig = reactive({appid: "",apisecret: "",apikey: "",
});function testXfSend() {if (!sendTest.content) {ElNotification.error({title: "请输入发送内容",});return;}const XfBot = new XfUtil(xfConfig.appid, xfConfig.apikey, xfConfig.apisecret);sendTest.revert = "";sendTest.loading = true;XfBot.start(sendTest.content);XfBot.on("endRecord", (data) => {console.log("回复内容", data.content);sendTest.loading = false;sendTest.revert = data.content;});// XfBot.on("message", (data) => {});XfBot.on("error", (data) => {sendTest.loading = false;ElNotification.error({title: data.content,});});
}
相关文章:
关于ElectronVue3中集成讯飞星火AI
前言:我的最终目的是为了在QQ上集成一个AI机器人,因此在这里先实现一个简单的集成 先上效果图 总体还是很简单的,我在调用websock获取回复内容的基础上另外集成了一个事件总线,让我们在调用获取消息的时候能够更加方便快捷 工具代…...
初识JVM(简单易懂),解开JVM神秘的面纱
目录 一、什么是JVM(Java虚拟机)? 二、JVM的功能 三、JVM的功能-即时编译 四、常见的JVM 五、JVM的组成 五、JVM的工作流程 参考资料 一、什么是JVM(Java虚拟机)? 在Java的世界里,Java虚…...
Open3D (C++) 计算两点云之间的最小距离
目录 一、 算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、 算法原理 Open3D中ComputePointCloudDistance函数提供了计算从源点云到目标点云的距离的方法,计算点云的距离。也…...
51单片机演奏兰亭序
使用开发板为普中51-实验板 普中-2 时钟频率:11.001081MHZ 演示视频: 【51单片机演奏兰亭序】 https://www.bilibili.com/video/BV12G411D7uK/?share_sourcecopy_web&vd_source0f48f7cc0fef720b95e067122ac83437 源码如下: 数组较大&a…...
计算机编程零基础编程学什么语言,中文编程工具构件简介软件下载
计算机编程零基础编程学什么语言,中文编程工具构件简介软件下载 给大家分享一款中文编程工具,零基础轻松学编程,不需英语基础,编程工具可下载。 这款工具不但可以连接部分硬件,而且可以开发大型的软件,象如…...
zookeeper单机版的搭建
一 zookeeper的搭建 1.1 上传zkjar包 1.2 搭建配置 1.解压压缩包 [rootlocalhost export]# tar -zxvf zookeeper-3.7.0-bin.tar.gz 2.创建data文件夹 [rootlocalhost export]# cd apache-zookeeper-3.7.0-bin/ [rootlocalhost apache-zookeeper-3.7.0-bin]# ls bin conf…...
roseha for windows 11+oracle 11g部署过程
文章目录 一、环境准备关闭防火墙配置hosts共享存储准备 二、部署步骤1.主机A、B安装数据库软件2.主机A进行数据库实例创建3.主机B创建数据库4.安装配置roseha软件 一、环境准备 windows server 2019 oracle 11.2.0.3 EE roseha for windows 11 5个IP地址:2心跳、3…...
机器学习与因果推断的高级实践 | 数学建模
文章目录 因果推断因果推断的前世今生(1)潜在结果框架(Potential Outcome Framework)(2)结构因果模型(Structual Causal Model,SCM) 身处人工智能爆发式增长时代的机器学…...
go语言实现高性能自定义ip管理模块(ip黑名单)
ip黑名单设计 对于IPV4而言,理论上有256^4个,也就是约42亿个。我想了好久,也查了挺多资料,但是,确实没有通用现成的解决方案。 PS:以下方案的讨论,适用于对于IP管理不那么严苛的情况。当然也可…...
检索增强生成架构详解【RAG】
生成式AI技术很强大,但它们受到知识的限制。 虽然像 ChatGPT 这样的LLM可以执行许多任务,但每个LLM的基线知识都存在基于其训练数据的差距。 如果你要求LLM写一些关于最近趋势或事件的文章,LLM不会知道你在说什么,而且回答最好是混…...
高清动态壁纸软件Live Wallpaper Themes 4K mac中文版功能
Live Wallpaper & Themes 4K mac是一款提供各种高清动态壁纸和主题的应用程序。该应用程序提供了大量的动态壁纸和主题,包括自然、动物、城市、抽象等各种类别,可以满足用户不同的需求。除了壁纸和主题之外,该应用程序还提供了许多其他功…...
Kafka配置SASL认证密码登录
1、修改config/server.properties,添加如下内容 listenersSASL_PLAINTEXT://内网ip:9092 advertised.listenersSASL_PLAINTEXT://外网ip:9092 security.inter.broker.protocolSASL_PLAINTEXT sasl.mechanism.inter.broker.protocolPLAIN sasl.enabled.…...
两年功能五年自动化测试面试经验分享
最近有机会做一些面试工作,主要负责面试软件测试人员招聘的技术面试。 之前一直是应聘者的角色,经历了不少次的面试之后,多少也积累一点面试的经验,现在发生了角色转变。初次的面试就碰到个工作年限比我长的,也没有时…...
大数据基础设施搭建 - Kafka(with ZooKeeper)
文章目录 一、简介二、单机部署2.1 上传压缩包2.2 解压压缩包2.3 修改配置文件(1)配置zookeeper地址(2)修改kafka运行日志(数据)存储路径 2.4 配置环境变量2.5 启动/关闭2.6 测试(1)查看当前服务器中的所有…...
[JVM] 京东一面~说一下Java 类加载过程
系统加载 Class 类型的文件主要三步:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。 通过全限定名来加载生成 class 对象到内存中,然后进行验证这个 class 文件,包括文件格式校验、元数据验证…...
2023 年 认证杯 小美赛 ABC题 国际大学生数学建模挑战赛 |数学建模完整代码+建模过程全解全析
当大家面临着复杂的数学建模问题时,你是否曾经感到茫然无措?作为2022年美国大学生数学建模比赛的O奖得主,我为大家提供了一套优秀的解题思路,让你轻松应对各种难题。 cs数模团队在认证杯 小美赛前为大家提供了许多资料的内容呀&am…...
N-134基于java实现捕鱼达人游戏
开发工具eclipse,jdk1.8 文档截图: package com.qd.fish;import java.awt.Graphics; import java.io.File; import java.util.ArrayList; import java.util.List;import javax.imageio.ImageIO;public class Fishes {//定义一个集合来管理鱼List<Fish> fish…...
MTK联发科MT6762/MT6763/MT6765安卓核心板参数规格比较
MT6762安卓核心板 MTK6762安卓核心板是一款工业级高性能、可运行 android9.0 操作系统的 4G智能模块。 CPU:4xCortex-A53 up to 2.0Ghz/4xCortex-A53 up to 1.5GhzGraphics:IMG GE8320 Up to 650MhzProcess:12nmMemory:1xLP3 9…...
仿ChatGPT对话前端页面(内含源码)
仿ChatGPT对话前端页面(内含源码) 前言布局样式和Js部分关键点全部源码 前言 本文主要讲解如何做出类似ChatGPT的前端页面。具体我们的效果图是长这样,其中除了时间是动态的之外,其他都是假数据。接下来让我们从布局和样式的角度…...
js粒子效果(一)
效果: 代码: <!doctype html> <html> <head><meta charset"utf-8"><title>HTML5鼠标经过粒子散开动画特效</title><style>html, body {position: absolute;overflow: hidden;margin: 0;padding: 0;width: 100%;height: 1…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
