js教程

VUE开发接入ChatGpt教程分析

我的站长站 2023-02-13 人阅读

页面仿照微信聊天界面,点击机器人图标,弹出聊天框,消息分为用户消息,机器人消息两种,每次用户发送消息,请求后端接口获取chatgpt返回的信息,添加到消息列表中,推送给用户。

不直接通过前端请求chatgpt官方接口,否则会泄露个人的api-key,在官方接口的基础上封装一层,并添加rsa加密,前端请求时进行rsa加密,后端查取数据前,进行rsa解密,防止恶意请求(加密的字符根据个人而定,比如我加密当前时间戳,解密后比较时间戳和当前时间,时差在一分钟之内则有效)

官方接口示例

curl --location --request POST 'https://api.openai.com/v1/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer 这里用注册chatgpt后个人的api-key替换' \
--data-raw '{"prompt": "讲个故事", "max_tokens": 2048, "model": "text-davinci-003"}'

VUE前端示例

<template>
    <div>
        <el-avatar @click="viewClick" :size="50" src="https://s1.ax1x.com/2023/02/09/pSWy9QU.png"></el-avatar>
        <el-dialog v-model="viewStatus" title="聊天机器人" width="40%">
            <div id="msgarea" >
                <div v-for="msg in msgList" :key="msg">
                    <div v-if="msg.isUser">
                        <el-avatar src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" />
                        <el-card shadow="always"> {{ msg.content }} </el-card>
                    </div>
                    <div v-else>
                        <el-avatar src="https://s1.ax1x.com/2023/02/09/pSWy9QU.png" />
                        <el-card shadow="always"> {{ msg.content }} </el-card>
                    </div>
                </div>
 
 
            </div>
            <template #footer>
                <span v-loading="loading">
                    <el-input v-model="input" placeholder="please input" />
                    <el-button type="primary" @click="sendMsg">
                        send
                    </el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
 
<script>
import { defineComponent, reactive, toRefs } from 'vue'
import { encryptMI } from '@/type/rsa'
import { sendChat } from '@/request/api'
import { requestResultNoti } from '@/request/resultNotification';
 
interface MessageInterface {
    id?: number,
    type?: string,
    isUser: boolean,
    content: string
}
export default defineComponent({
    setup() {
        const data = reactive({
            viewStatus: false,
            icon: "../asset/robot.png",
            input: "",
            count: 0,
            loading: false,
            msgList: [
                {
                    "id": 0,
                    "isUser": false,
                    "content": "我是您的智能助手,请输入一个问题"
                }
            ] as Array<MessageInterface>,
            publicKey: '这里是rsa公钥'
        })
 
        const viewClick = () => {
            data.viewStatus = !data.viewStatus
        }
        const scrollToEnd = () => {
            console.log("滚动展示最新消息");
            const element = document.getElementById('msgarea')
            if (element !== null) {
                element.scrollTop = element.scrollHeight
            }
        }
        const sendMsg = () => {
            if (data.input == "") return
            const msg = {
                "id": ++data.count,
                "isUser": true,
                "content": data.input
            }
            data.msgList.push(msg)
            setTimeout(() => {
                scrollToEnd()
            }, 1000);
            scrollToEnd()
            const sendmsg = data.input
            data.input = ""
            data.loading = true
            sendChat({
                prompt: sendmsg,
                token: encryptMI(new Date().getTime().toString(), data.publicKey) as string
            }).then(
                res => {
                    requestResultNoti(res);
                    if (res.data.content == undefined) {
                        data.loading = false
 
                    }
                    else {
                        const msgRobot = {
                            "id": ++data.count,
                            "isUser": res.data.isUser,
                            "content": res.data.content
                        }
                        data.msgList.push(msgRobot)
                        data.loading = false
                        setTimeout(() => {
                            scrollToEnd()
                        }, 2000);
                    }
                })
 
        }
 
        return {
            ...toRefs(data),
            viewClick,
            sendMsg
        }
    }
})
</script>
 
<style scoped>
.user-msg {
    margin-top: 15px;
    margin-bottom: 15px;
    display: inline;
    float: right;
}
 
.msg-card-user {
    width: 550px;
    float: right;
}
 
.robot-msg {
    margin-top: 15px;
    margin-bottom: 15px;
    text-align: left;
    float: left;
}
 
.msg-card-robot {
    width: 550px;
    float: left;
}
 
.msg-area {
    height: 580px;
    overflow-x: hidden;
    overflow-y: auto;
}
</style>


Java后端示例

seivice层

package com.guojian.student.home.service.impl;/**
 * Created on 2023/2/10.
 *
 * [url=home.php?mod=space&uid=686208]@AuThor[/url] GuoJian
 * -version 1.0.0
 */
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.guojian.student.home.model.param.ChatParam;
import com.guojian.student.home.model.vo.ChatVO;
import com.guojian.student.home.service.ChatGptService;
import com.guojian.student.home.util.RSAUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
 
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.*;
 
/**
 * @ClassName:ChatGptServiceImpl
 * @Author: GuoJian
 * @Date: 2023/2/10 8:57
 * @Description: chatGpt二次封装服务实现
 */
@Service
public class ChatGptServiceImpl implements ChatGptService {
    @Override
    public ChatVO request(ChatParam chatParam){
        String url = "https://api.openai.com/v1/completions";
        Map<String,Object> jparam = new HashMap<>();
        jparam.put("prompt", chatParam.getPrompt());
        jparam.put("max_tokens", 2048);
        jparam.put("model","text-davinci-003");
        Map<String,String> headParams = new HashMap<>();
        headParams.put("Content-Type","application/json");
        headParams.put("Authorization","Bearer 个人aipkey替换这里");
        String resultJson = doPostJson(url, JSONObject.toJSONString(jparam),headParams);
        JSONObject jsonObject = JSON.parseObject(resultJson);
        ChatVO result = new ChatVO();
        result.setContent(jsonObject.getJSONArray("choices").getJSONObject(0).getString("text"));
        result.setIsUser(false);
        return result;
    }
    @Override
    public String decipherin(String ciphertext) throws NoSuchAlgorithmException, InvalidKeySpecException {
        String privateKey = "这里是私钥";
        String decodedData = RSAUtils.privateDecrypt(ciphertext, RSAUtils.getPrivateKey(privateKey)); //传入密文和私钥,得到明文
        return decodedData;
    }
    public static String doPostJson(String url, String params, Map<String,String> headParams) {
        String result = null;
        //1. 获取httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            //2. 创建post请求
            HttpPost httpPost = new HttpPost(url);
 
            //3.设置请求和传输超时时间
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(120000).build();
            httpPost.setConfig(requestConfig);
 
            //4.提交参数发送请求
            httpPost.setEntity(new StringEntity(params, ContentType.create("application/json", "utf-8")));
 
            //设置请求头
            for (String head : headParams.keySet()) {
                httpPost.addHeader(head,headParams.get(head));
            }
 
            response = httpClient.execute(httpPost);
            System.out.println(response);
            //5.得到响应信息
            int statusCode = response.getStatusLine().getStatusCode();
            //6. 判断响应信息是否正确
            if (HttpStatus.SC_OK != statusCode) {
                //结束请求并抛出异常
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            //7. 转换成实体类
            HttpEntity entity = response.getEntity();
            if (null != entity) {
                result = EntityUtils.toString(entity, "UTF-8");
            }
            EntityUtils.consume(entity);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //8. 关闭所有资源连接
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
}

Java后端代码示例

controller层

package com.guojian.student.home.controller;/**
 * Created on 2023/2/10.
 *
 * @author GuoJian
 * -version 1.0.0
 */
 
import com.guojian.student.home.common.ResponseBean;
import com.guojian.student.home.model.param.ChatParam;
import com.guojian.student.home.service.ChatGptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
 
/**
 * @ClassName:ChatGptController
 * @Author: GuoJian
 * @Date: 2023/2/10 9:56
 * @Description: chatgpt二次封装controller
 */
@RestController
@RequestMapping("/student/home/api")
@Slf4j
@CrossOrigin
public class ChatGptController {
    @Autowired
    ChatGptService chatGptService;
 
    @RequestMapping(value = "/chatgpt/send", method = RequestMethod.POST)
    public ResponseBean chat(@RequestBody ChatParam param) throws NoSuchAlgorithmException, InvalidKeySpecException {
        if (System.currentTimeMillis() - Long.parseLong(chatGptService.decipherin(param.getToken())) >= 60000) {
            return ResponseBean.fail("无效的token");
        } else {
            try {
                return ResponseBean.success(chatGptService.request(param));
            } catch (Exception e) {
                log.error("请求失败:", e);
                return ResponseBean.fail("请求失败:" + e.getMessage());
            }
        }
    }
}


相关专题
ChatGPT
ChatGPT
2023-02-13 201

ChatGPT是一款最近非常火的人工智能系统,我的站长站为了体验一下ChatGPT的强大,在网络上收集了许多关于ChatGPT的信息,分享给大家.包含大家最关系的ChatGPT注册方...

相关推荐
  • ChatGpt教程
  • vue教程
  • VUE开发接入ChatGpt教程分析

    页面仿照微信聊天界面,点击机器人图标,弹出聊天框,消息分为用户消息,机器人消息两种,每次用户发送消息,请求后端接口获取chatgpt返回的信息,添加到消息列表中,推送给用户。不直接通过前端请求chatgpt官方接口,否则会泄露个人的api-key,在官方接口的基础上封装...

    js教程 110 1年前
  • Python开发一个ChatGPT GUI

    1、首先去下载这个ChatGPT库,用到的库是这个:https://github.com/acheong08/ChatGPT2、安装这个ChatGPT库:pip3 install revChatGPT==0.0.a423、同目录还需要一个“config.json”:{ "session_token": "", "cf_clearance": "", "user_agent": "...

    python教程 107 1年前
  • 利用ChatGPT开源api开发一个聊天库

    准备工作第一步:注册OpenAI账号,如果搭建了科学还是提示不对你的国家提供服务的话,尝试清空浏览器缓存或者打开浏览器的无痕窗口。Chrome默认在右上角三个点打开就能找到“打开新的无痕式窗口”。ChatGPT聊天库代码示例1.网页获取所需token和cookie我们...

    经验分享 243 1年前
  • vue2.0 新闻客户端 实战视频教程
    vue2.0 新闻客户端 实战视频教程

    课程介绍首先,我们对Vue2.0做个基本的介绍,Vue.2.0是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,它不仅易于上手,还便于与...

    视频教程 125 4年前
  • 2019最新Vue+Vuex+MintUi+ElementUi+Mpvue入门实战视频教程
    2019最新Vue+Vuex+MintUi+ElementUi+Mpvue入门实战视频教程

    课程介绍2019更新6小时学会Vue入门实战视频教程6小时让你学会Vue开发,没错就是6小时,细致的讲解,详细的剖析,幽默的案例,由浅入深,逐步深入,让你快速了解并掌握Vue的组件、Vue中的请求数据、Vue的路由、...

    视频教程 182 4年前
  • web前端开发ReactJS,AngularJS, Vue.js优劣对比分析

    在全球大范围看,React和Angular依然遥遥领先,Vue.js这位后起之秀还需努力做到全球化!为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。JavaScript框架的更新节奏可以说日新月异,我们可以看到Angular不停地在发布新的版本,R...

    js教程 153 4年前
最新更新
  • js截取字符串教程

    slice()方法接受两个参数,起始索引和结束索引(可选)。它返回从起始索引到结束索引(不包括结束索引)之间的子字符...

    js教程 2个月前
  • find findIndex indexOf索引选择器使用方法

    find使用方法find方法是ES6引入的一种数组方法,可以用来查找数组中符合条件的元素。语法是:array.find(callba...

    js教程 3个月前
  • js复制网页内容教程

    Async Clipboard API方法HTML5新增的方法,无需引入第三方插件,直接就可以复制内容。低版本的浏览器可能会不兼...

    js教程 3个月前
  • js获取字符长度函数分享

    js获取字符长度函数function objLen(str) { if (str == null) return 0; if (typeof str != "string") { ...

    js教程 3个月前
  • 网站LED跑马灯效果广告代码

    网站可以看到很多的论坛网站都会用到这种网站LED跑马灯效果,这种效果实现也很简单,分享给大家。LED跑马灯效果...

    js教程 4个月前