位置: IT常识 - 正文

国内前端vue对接OpenAI/chatgpt【文本互动/生成图片】(web前端开发 vue)

编辑:rootadmin
国内前端vue对接OpenAI/chatgpt【文本互动/生成图片】

推荐整理分享国内前端vue对接OpenAI/chatgpt【文本互动/生成图片】(web前端开发 vue),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:基于vue的前端架构设计,web前端开发 vue,前端 vue,前端 vue,vue前后端对接,vue前后端对接,vue前端和后端交互,前端 vue,内容如对您有帮助,希望把文章链接给更多的朋友!

 如图;国内通过调用openai接口进行互动,实现图文互动/文本互动

 注意:请求人数较多,需要等待

1、🔔 获取ApiKey

注册 OpenAI 账号,获取你的 ApiKey,过程略。

2、💬 聊天接口

⚠️ 不再推荐使用本接口,后面将废弃。

接口地址 (POST请求)

POST https://api.openai.com/pro/chat/completions

请求参数

参数名类型长度必须备注apiKeyString64是OpenAI 的 ApiKeysessionIdString64是会话ID,关联上下文,推荐使用UUID作为sessionIdcontentString1000是发送的内容

请求示例(Content-Type = application/json)

{    "apiKey": "<your_openai_api_key>",    "sessionId": "8d1cb9b0-d535-43a8-b738-4f61b1608579",    "content": "你是谁?"}国内前端vue对接OpenAI/chatgpt【文本互动/生成图片】(web前端开发 vue)

响应示例

{    "code": 200,    "message": "执行成功",    "data": "我是一名人工智能助手,用于协助回答问题和提供建议。您可以通过与我进行对话来获取您需要的信息或帮助。"}

本接口使用的是 gpt-3.5-turbo 模型,支持通过上下文内容进行连续对话。

本接口对官方的接口进行了封装,开发者只需为每个 ApiKey 下的每个会话分配一个独立的 sessionId 即可实现连续对话 。

推荐使用 uuid 作为 sessionId 以保证全局唯一 ,否则对话可能会“串线”。

对话中的上下文信息有效期为30分钟,过期后再次发送消息无法关联上下文。

# 测试聊天curl https://api.openai.com/v1/chat/completions \                 -H "Content-Type: application/json" \ -H "Authorization: Bearer <your_openai_api_key>" \ -d '{   "model": "gpt-3.5-turbo",   "messages": [{"role": "user", "content": "Hello!"}] }'  # 响应结果   { "id": "chatcmpl-21lvNzPaxlsQJh0BEIb9DqoO0pZUY", "object": "chat.completion", "created": 1680656905, "model": "gpt-3.5-turbo-0301", "usage": {   "prompt_tokens": 10,   "completion_tokens": 10,   "total_tokens": 20 }, "choices": [   {     "message": {       "role": "assistant",       "content": "Hello there! How can I assist you today?"     },     "finish_reason": "stop",     "index": 0   } ]}# 测试生成图片curl https://api.openai.com/v1/images/generations \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <your_openai_api_key>" \ -d '{   "prompt": "A bikini girl",   "n": 2,   "size": "512x512" }'  # 响应结果 { "created": 1680705608, "data": [   {     "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-xxxxxxx"   },   {     "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-xxxxxxx"   } ]}

OpenAI本身是没有记忆的,如果你不告诉他你之前说了什么以及他之前回答了什么,那么他只会根据你最近一次发送的内容进行回答。

所以,要想实现“连续对话”,每次发送消息时,你需要将你之前发送的内容(user)以及OpenAI之前返回的内容(assistant),再结合你本次想发送的内容(user) 按 时序 组合成一个 messages[] 数组,然后再将这个数组发送给OpenAI就行了,就是这么简单。

4 、⭐️ 第三方应用

如果你用的是第三方开发者开发的基于OpenAI 的应用可以参考以下:

名称Github地址StarsOpenAI-TranslatorGitHub - yetone/openai-translator: 基于 ChatGPT API 的划词翻译浏览器插件和跨平台桌面端应用 - Browser extension and cross-platform desktop application for translation based on ChatGPT API.ChatGPT-Next-WebGitHub - Yidadaa/ChatGPT-Next-Web: One-Click to deploy well-designed ChatGPT web UI on Vercel. 一键拥有你自己的 ChatGPT 网页服务。ChatGPT-Webhttps://github.com/Chanzhaoyu/chatgpt-web5、💰 查询余额

接口地址 (GET请求)

GET https://api.openai.com/pro/balance?apiKey=sk-xxxxxxxxxxxxxx

请求参数

参数名类型长度必须备注apiKeyString64是OpenAI 的 ApiKey

响应示例

{    "code": 200,    "message": "执行成功",    "data": {        "total": 18.00,        "balance": 17.92,        "used": 0.08   }}

原OpenAI官方后台查询余额的接口由于被用户滥用,官方给撤销了,现在提供一个折中的方式去计算账户余额。

逻辑是先得到OpenAI给你账户授权的总金额,然后减去最近100天你账户消耗的金额,得到的 balance 即为账户可用余额。

<template> <div class="chat-window"> <div class="top"> <div class="head-pic"> <HeadPortrait :imgUrl="frinedInfo.headImg"></HeadPortrait> </div> <div class="info-detail"> <div class="name">{{ frinedInfo.name }}</div> <div class="detail">{{ frinedInfo.detail }}</div> </div> <div class="other-fun"> <span class="iconfont icon-shipin" @click="video"> </span> <span class="iconfont icon-gf-telephone" @click="telephone"></span> <label for="docFile"> <span class="iconfont icon-wenjian"></span> </label> <label for="imgFile"> <span class="iconfont icon-tupian"></span> </label> <input type="file" name="" id="imgFile" @change="sendImg" accept="image/*" /> <input type="file" name="" id="docFile" @change="sendFile" accept="application/*,text/*" /> <!-- accept="application/*" --> </div> </div> <div class="botoom"> <div class="chat-content" ref="chatContent"> <div class="chat-wrapper" v-for="(item, index) in chatList" :key="item.id" > <!-- <div v-if="isSend && index == chatList.length - 1"> <div class="chat-friend" v-if="item.uid !== '1001'"> <div class="info-time"> <img :src="item.headImg" alt="" /> <span>{{ item.name }}</span> <span>{{ item.time }}</span> </div> <div class="chat-text" v-if="item.chatType == 0"> <span class="flash_cursor"></span> </div> </div> </div>--> <div class="chat-friend" v-if="item.uid !== '1001'"> <div class="info-time"> <img :src="item.headImg" alt="" /> <span>{{ item.name }}</span> <span>{{ item.time }}</span> </div> <div class="chat-text" v-if="item.chatType == 0&&item.type != 1"> <template v-if="isSend && index == chatList.length - 1"> <span class="flash_cursor">请稍后...</span> </template> <template v-else> <pre>{{ item.msg }}</pre> </template> </div> <div class="chat-img" v-if="item.chatType == 1"> <img :src="item.msg" alt="表情" v-if="item.extend.imgType == 1" style="width: 100px; height: 100px" /> <el-image :src="item.msg" :preview-src-list="srcImgList" v-else> </el-image> </div> <div class="chat-img" v-if="item.type == 1"> <img v-for="(items,index) in item.images" :src="items" :key="index" alt="表情" style="width: 100px; height: 100px" /> </div> <div class="chat-img" v-if="item.chatType == 2"> <div class="word-file"> <FileCard :fileType="item.extend.fileType" :file="item.msg" ></FileCard> </div> </div> </div> <div class="chat-me" v-else> <div class="info-time"> <span>{{ item.name }}</span> <span>{{ item.time }}</span> <img :src="item.headImg" alt="" /> </div> <div class="chat-text" v-if="item.chatType == 0"> {{ item.msg }} </div> <div class="chat-img" v-if="item.chatType == 1"> <img :src="item.msg" alt="表情" v-if="item.extend.imgType == 1" style="width: 100px; height: 100px" /> <el-image style="max-width: 300px; border-radius: 10px" :src="item.msg" :preview-src-list="srcImgList" v-else > </el-image> </div> <div class="chat-img" v-if="item.chatType == 2"> <div class="word-file"> <FileCard :fileType="item.extend.fileType" :file="item.msg" ></FileCard> </div> </div> </div> </div> </div> <div class="chatInputs"> <!-- v-show="showEmoji" --> <!-- <div class="emoji boxinput" @click="clickEmoji"> <img src="@/assets/img/emoji/smiling-face.png" alt="" /> </div> --> <div class="emoji-content"> <Emoji @sendEmoji="sendEmoji" v-show="showEmoji" @closeEmoji="clickEmoji" ></Emoji> </div> <input class="inputs" v-model="inputMsg" @keyup.enter="sendText" /> <el-button class="send boxinput" :disabled="isSend" @click="sendText"> <img src="@/assets/img/emoji/rocket.png" alt="" /> </el-button> </div> </div> </div></template><script>import { animation } from "@/util/util";import { getChatMsg, chatgpt } from "@/api/getData";import HeadPortrait from "@/components/HeadPortrait";import Emoji from "@/components/Emoji";import FileCard from "@/components/FileCard.vue";export default { components: { HeadPortrait, Emoji, FileCard, }, props: { frinedInfo: Object, default() { return {}; }, }, watch: { frinedInfo() { this.getFriendChatMsg(); }, }, data() { return { chatList: [], inputMsg: "", showEmoji: false, friendInfo: {}, srcImgList: [], isSend: false, }; }, mounted() { this.getFriendChatMsg(); }, methods: { //获取聊天记录 getFriendChatMsg() { let params = { frinedId: this.frinedInfo.id, }; getChatMsg(params).then((res) => { console.error("333", res); this.chatList = res; // this.chatList.forEach((item) => { // if (item.chatType == 2 && item.extend.imgType == 2) { // this.srcImgList.push(item.msg); // } // }); this.scrollBottom(); }); }, //发送信息 sendMsg(msgList) { this.chatList.push(msgList); this.scrollBottom(); }, //获取窗口高度并滚动至最底层 scrollBottom() { this.$nextTick(() => { const scrollDom = this.$refs.chatContent; animation(scrollDom, scrollDom.scrollHeight - scrollDom.offsetHeight); }); }, //关闭标签框 clickEmoji() { this.showEmoji = !this.showEmoji; }, //发送文字信息 sendText() { if (this.inputMsg) { let chatMsg = { headImg: require("@/assets/img/head_portrait.jpg"), name: "", time: new Date().toLocaleTimeString(), msg: this.inputMsg, chatType: 0, //信息类型,0文字,1图片 uid: "1001", //uid }; this.sendMsg(chatMsg); this.$emit("personCardSort", this.frinedInfo.id); this.inputMsg = ""; let data = { // prompt: chatMsg.msg, // temperature: 1, // top_p: 1, // // model: "text-davinci-003", // max_tokens: 2048, // frequency_penalty: 0, // "model": "gpt-3.5-turbo", // "messages": [{"role": "user", "content": "Hello!"}], // presence_penalty: 0, // stop: ["Human:", "AI:"], model: "gpt-3.5-turbo", messages: [{ role: "user", content: chatMsg.msg }], }; this.loading = true; this.isSend = true; let chatGPT = { headImg: require("@/assets/img/head_portrait1.jpg"), name: "小五", time: new Date().toLocaleTimeString(), msg: "", images: [], chatType: 0, //信息类型,0文字,1图片 uid: "1002", //uid }; this.sendMsg(chatGPT); chatgpt(data).then((res) => { this.isSend = false; if (res.data) { this.chatList[this.chatList.length - 1].images=[]; console.error("555", this.chatList); this.chatList[this.chatList.length - 1].type = 1; this.chatList[this.chatList.length - 1].images.push(res.data[0].url); } else { this.chatList[this.chatList.length - 1].msg = res.choices[0].message.content; } }); } else { this.$message({ message: "消息不能为空哦~", type: "warning", }); } }, //发送表情 sendEmoji(msg) { let chatMsg = { headImg: require("@/assets/img/head_portrait.jpg"), name: "大毛是小白", time: new Date().toLocaleTimeString(), msg: msg, chatType: 1, //信息类型,0文字,1图片 extend: { imgType: 1, //(1表情,2本地图片) }, uid: "1001", }; this.sendMsg(chatMsg); this.clickEmoji(); }, //发送本地图片 sendImg(e) { let _this = this; console.log(e.target.files); let chatMsg = { headImg: require("@/assets/img/head_portrait.jpg"), name: "大毛是小白", time: "09:12 AM", msg: "", chatType: 1, //信息类型,0文字,1图片, 2文件 extend: { imgType: 2, //(1表情,2本地图片) }, uid: "1001", }; let files = e.target.files[0]; //图片文件名 if (!e || !window.FileReader) return; // 看是否支持FileReader let reader = new FileReader(); reader.readAsDataURL(files); // 关键一步,在这里转换的 reader.onloadend = function () { chatMsg.msg = this.result; //赋值 _this.srcImgList.push(chatMsg.msg); }; this.sendMsg(chatMsg); e.target.files = null; }, //发送文件 sendFile(e) { let chatMsg = { headImg: require("@/assets/img/head_portrait.jpg"), name: "大毛是小白", time: "09:12 AM", msg: "", chatType: 2, //信息类型,0文字,1图片, 2文件 extend: { fileType: "", //(1word,2excel,3ppt,4pdf,5zpi, 6txt) }, uid: "1001", }; let files = e.target.files[0]; //图片文件名 chatMsg.msg = files; console.log(files); if (files) { switch (files.type) { case "application/msword": case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": chatMsg.extend.fileType = 1; break; case "application/vnd.ms-excel": case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": chatMsg.extend.fileType = 2; break; case "application/vnd.ms-powerpoint": case "application/vnd.openxmlformats-officedocument.presentationml.presentation": chatMsg.extend.fileType = 3; break; case "application/pdf": chatMsg.extend.fileType = 4; break; case "application/zip": case "application/x-zip-compressed": chatMsg.extend.fileType = 5; break; case "text/plain": chatMsg.extend.fileType = 6; break; default: chatMsg.extend.fileType = 0; } this.sendMsg(chatMsg); e.target.files = null; } }, // 发送语音 telephone() { this.$message("敬请期待一下吧~🥳"); }, //发送视频 video() { this.$message("敬请期待一下吧~🥳"); }, },};</script><style lang="scss" scoped>.flash_cursor { width: auto; height: 30px; display: inline-block; background: #d6e3f5; opacity: 1; animation: glow 800ms ease-out infinite alternate;}@keyframes glow { 0% { opacity: 1; } 25% { opacity: 0.5; } 50% { opacity: 0; } 75% { opacity: 0.5; } 100% { opacity: 1; }}.chat-window { width: 100%; height: 100%; margin: 0 auto; position: relative; .top { margin-bottom: 20px; &::after { content: ""; display: block; clear: both; } .head-pic { float: left; } .info-detail { float: left; margin: 5px 20px 0; .name { font-size: 20px; font-weight: 600; color: #fff; } .detail { color: #9e9e9e; font-size: 12px; margin-top: 2px; } } .other-fun { float: right; margin-top: 20px; span { margin-left: 30px; cursor: pointer; } // .icon-tupian { // } input { display: none; } } } .botoom { width: 100%; height: 70vh; background-color: rgb(50, 54, 68); border-radius: 20px; padding: 20px; box-sizing: border-box; position: relative; .chat-content { width: 100%; height: 85%; overflow-y: scroll; padding: 20px; box-sizing: border-box; &::-webkit-scrollbar { width: 0; /* Safari,Chrome 隐藏滚动条 */ height: 0; /* Safari,Chrome 隐藏滚动条 */ display: none; /* 移动端、pad 上Safari,Chrome,隐藏滚动条 */ } .chat-wrapper { position: relative; word-break: break-all; .chat-friend { width: 100%; float: left; margin-bottom: 20px; display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; .chat-text { max-width: 90%; padding: 20px; border-radius: 20px 20px 20px 5px; background-color: rgb(56, 60, 75); color: #fff; &:hover { background-color: rgb(39, 42, 55); } pre { white-space: break-spaces; } } .chat-img { img { width: 100px; height: 100px; } } .info-time { margin: 10px 0; color: #fff; font-size: 14px; img { width: 30px; height: 30px; border-radius: 50%; vertical-align: middle; margin-right: 10px; } span:last-child { color: rgb(101, 104, 115); margin-left: 10px; vertical-align: middle; } } } .chat-me { width: 100%; float: right; margin-bottom: 20px; position: relative; display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-end; .chat-text { float: right; max-width: 90%; padding: 20px; border-radius: 20px 20px 5px 20px; background-color: rgb(29, 144, 245); color: #fff; &:hover { background-color: rgb(26, 129, 219); } } .chat-img { img { max-width: 300px; max-height: 200px; border-radius: 10px; } } .info-time { margin: 10px 0; color: #fff; font-size: 14px; display: flex; justify-content: flex-end; img { width: 30px; height: 30px; border-radius: 50%; vertical-align: middle; margin-left: 10px; } span { line-height: 30px; } span:first-child { color: rgb(101, 104, 115); margin-right: 10px; vertical-align: middle; } } } } } .chatInputs { width: 100%; position: absolute; bottom: 0; margin: 0 auto; align-items: center; display: flex; padding-bottom: 15px; .boxinput { width: 50px; height: 50px; background-color: rgb(66, 70, 86); border-radius: 15px; border: 1px solid rgb(80, 85, 103); position: relative; cursor: pointer; img { width: 30px; height: 30px; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } } .emoji { transition: 0.3s; &:hover { background-color: rgb(46, 49, 61); border: 1px solid rgb(71, 73, 82); } } .inputs { width: 70%; height: 50px; background-color: rgb(66, 70, 86); border-radius: 15px; border: 2px solid rgb(34, 135, 225); padding: 10px; box-sizing: border-box; transition: 0.2s; margin-right: 10px; font-size: 20px; color: #fff; font-weight: 100; &:focus { outline: none; } } .send { background-color: rgb(29, 144, 245); border: 0; transition: 0.3s; box-shadow: 0px 0px 5px 0px rgba(0, 136, 255); &:hover { box-shadow: 0px 0px 10px 0px rgba(0, 136, 255); } } } }}</style>
本文链接地址:https://www.jiuchutong.com/zhishi/300766.html 转载请保留说明!

上一篇:Vue组件的通信方式有哪些?(vue组件通信方法)

下一篇:CSS的选择器(超详细)(css选择器详解)

  • 城建税的征税范围不包括农村对不对
  • 企业所得税如何做分录
  • 挂车交车船税吗
  • 记账凭证核算形式需要设置的凭证有
  • 根据付款申请单付款
  • 附加税减免如何申报
  • 小规模申报增值税怎么申报
  • 购买车辆交纳的费用
  • 民办非企业单位是私立还是公立
  • 暂估一直不来票,没有纳税调整怎么办
  • 间接持股比例怎么
  • 营改增对房地产行业的影响
  • 成本会计实训要求
  • 以前年度管理费用多计
  • 报关单金额大于合同金额
  • 付拍卖佣金入什么科目核算及会计分录怎么做?
  • 印花税一个月一报吗
  • 施工企业实验用具费用计入什么科目
  • 停工损失会计科目
  • 案例分析一般纳税人的税负率怎么计算?
  • 开发票时税点开里怎么算?
  • 注册资本金印花税税率是多少
  • 小规模专票丢了怎么办
  • 未达起征点纳税申报表怎么填
  • 出口退税远程申报
  • 2018年工会经费返还比例
  • 土地使用权摊销账务处理
  • 华为手机如何用有线耳机
  • 小规模纳税人如何申报增值税
  • 房地产企业的沙盘模型制作费会计处理
  • 附加税异地预缴如何申报
  • 直系亲属股权转让免征个人所得税
  • 厂房修缮
  • PHP:pg_lo_export()的用法_PostgreSQL函数
  • 购买车辆的会计分录该怎样做
  • 接受专利投资会亏本吗
  • uniapp如何使用
  • 国有土地租赁合同规定多少年
  • 耕地开垦费应计入哪个会计科目
  • 防伪税控服务费怎么交
  • php sse
  • 数学建模回归模型例题
  • 网络安全网页设计作品构思
  • 通用机打发票还能用吗
  • mysql主键语句
  • mysql备份数据恢复
  • gin框架使用案例
  • 织梦官方网站
  • 资产捐赠账务处理
  • 给客户买的车票怎么查询
  • 网络贷款需要缴费吗
  • 个体户税务分几种
  • 确认销售收入时不影响应收账款入账金额的是
  • 工会经费的会计分录2022
  • 开出咨询费发票应该注册什么企业?
  • 增值税专用发票和普通发票的区别
  • 信息服务的最终目的是什么
  • 存货损失营业外支出
  • 工程施工人工费,材料费,机械费占多少比例
  • 应收利息审计底稿怎么做
  • 坏账损失的核算方法包括
  • centos下安装虚拟机
  • mysql 1290怎么解决
  • win10无法新建文件夹怎么办?(已解决)
  • xp ie浏览器无法显示网页
  • 在linux2.4.0版本中
  • samba webui
  • win7环境变量在哪打开啊
  • win10改服务器
  • windows7 cpu使用率高
  • window10 不能上网
  • 将jquery.qqFace.js表情转换成微信的字符码
  • linux shell脚本命令
  • jquery源码分析笔记
  • unity之血瓶金币的生成
  • unity怎么删除导入的包
  • 买车险代收车船税合法吗
  • 扬州退契税政策
  • 襄城是现在的哪个城市
  • 中央财经大学法学院
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设