当前位置:   article > 正文

VUE开发接入ChatGpt教程分析_vue chatgpt

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

            }

        }

    }

}

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/906844
推荐阅读
相关标签
  

闽ICP备14008679号