VUE开发接入ChatGpt教程分析

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

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

官方接口示例

1

2

3

4

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前端示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

<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层

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

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层

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

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());

            }

        }

    }

}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Spring中接入数据库,表爆红可能是由于以下几个原因引起的: 1. 缺少数据库连接依赖:在使用Spring连接数据库时,需要添加相应的数据库连接依赖。例如,如果使用MySQL数据库,需要添加MySQL连接器的依赖。可以通过在项目的pom.xml文件中添加相应的依赖来解决这个问题。\[3\] 2. 数据库配置错误:在Spring的配置文件中,可能存在数据库连接配置错误,比如数据库的URL、用户名、密码等配置不正确。需要检查配置文件中的数据库连接信息是否正确。 3. 数据库驱动版本不兼容:如果使用的数据库驱动版本与Spring版本不兼容,可能会导致表爆红的问题。需要确保使用的数据库驱动版本与Spring版本兼容。 4. 数据库表不存在:如果在数据库中没有创建相应的表,或者表名拼写错误,也会导致表爆红的问题。需要确保数据库中存在相应的表,并且表名与代码中的表名一致。 综上所述,当Spring接入数据库时,表爆红可能是由于缺少数据库连接依赖、数据库配置错误、数据库驱动版本不兼容或数据库表不存在等原因引起的。需要逐一排查这些可能的原因,并进行相应的修正。 #### 引用[.reference_title] - *1* *2* [Spring Integration 实例讲解](https://blog.csdn.net/qq_37556726/article/details/95801082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Springboot+Vue-element个人博客项目开发(二、数据库配置)](https://blog.csdn.net/z972065491/article/details/127452803)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执刀人的工具库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值