App.vue 3.5 KB
Newer Older
6
UPDATE  
64104061f23fda247c679fa8 已提交
1
<template>
6
update  
64104061f23fda247c679fa8 已提交
2 3 4 5 6 7 8 9
  <div class="container ivu-p">
    <div class="dialog">
      <template v-for="(item, index) in dialogs" :key="index">
        <div class="dialog-item" :class="{ 'dialog-item-me': item.role === 'me', 'dialog-item-ai': item.role === 'ai' }">
          <div class="dialog-item-main">{{ item.text }}</div>
        </div>
      </template>
    </div>
10
    <div class="question ivu-mt">
11
      <Input v-model="question" type="textarea" :autosize="{ minRows: 4, maxRows: 6 }" placeholder="输入你的问题" />
6
update  
64104061f23fda247c679fa8 已提交
12 13 14 15 16 17 18 19
      <Row class="ivu-mt">
        <Col>
          <Button type="primary" size="large" icon="md-send" :loading="loading" @click="handleSend">发送</Button>
        </Col>
        <Col>
          <Button size="large" class="ivu-ml" icon="md-add" :disabled="loading" @click="handleNewChat">新对话</Button>
        </Col>
      </Row>
6
update  
64104061f23fda247c679fa8 已提交
20
    </div>
6
622eda98dfef6c4fdb84ccca 已提交
21
  </div>
6
UPDATE  
64104061f23fda247c679fa8 已提交
22
</template>
6
update  
64104061f23fda247c679fa8 已提交
23
<script>
6
UPDATE  
64104061f23fda247c679fa8 已提交
24 25
import { fetchEventSource } from '@microsoft/fetch-event-source';
import { apiKey, apiUrl } from './api';
26

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
export default {
  data() {
    return {
      question: '',
      loading: false,
      dialogs: []
    }
  },
  methods: {
    handleSend() {
      if (this.loading || this.question === '') return;
      this.loading = true;

      const question = this.question;
      this.question = '';

      this.dialogs.push({
        id: this.dialogs.length + 1,
        role: 'me',
        text: question
      });

      const aiDialogID = this.dialogs.length + 1;
50

51 52 53 54 55
      this.dialogs.push({
        id: aiDialogID,
        role: 'ai',
        text: 'AI 思考中...'
      });
56

6
UPDATE  
64104061f23fda247c679fa8 已提交
57
      const dialog = this.dialogs.find(item => item.id === aiDialogID);
6
update  
64104061f23fda247c679fa8 已提交
58

6
UPDATE  
64104061f23fda247c679fa8 已提交
59 60 61 62 63 64 65 66 67 68 69
      /**
       * 发送请求,InsCode 已经集成了 GPT 能力
       * 在 vite.config.js 中已通过环境变量写入了 apiKey(该 key 是动态写入使用者的,在 IDE 中是作者,发布到社区是运行该作品的用户)
       * 发布到社区后,将消耗运行者的额度
       * 注意:如果部署应用,任何人通过部署后的域名访问应用时,都将消耗部署者的额度
       */
      const body = {
        messages: [
          {
            role: 'user',
            content: question
6
update  
64104061f23fda247c679fa8 已提交
70
          }
6
UPDATE  
64104061f23fda247c679fa8 已提交
71 72 73
        ],
        apikey: apiKey
      }
74

6
UPDATE  
64104061f23fda247c679fa8 已提交
75 76 77 78 79 80 81 82 83 84 85
      const source = fetchEventSource(apiUrl, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(body),
        onopen: (response) => {
          dialog.text = '';
        },
        onmessage: (msg) => {
          const data = JSON.parse(msg.data);
6
64104061f23fda247c679fa8 已提交
86 87
          const finish_reason = data.choices[0].finish_reason;
          const finish = finish_reason === 'stop' || finish_reason === 'length';
6
UPDATE  
64104061f23fda247c679fa8 已提交
88 89 90 91 92 93 94 95 96 97 98
          const content = data.choices[0].delta.content;

          if (finish) {
            this.loading = false;
          } else if (content) {
            const text = content;
            dialog.text += text;
          }
        },
        onerror: (err) => {
          console.log("error", err);
99
        }
6
UPDATE  
64104061f23fda247c679fa8 已提交
100
      });
101 102 103
    },
    handleNewChat() {
      this.dialogs = [];
6
update  
64104061f23fda247c679fa8 已提交
104 105
    }
  }
106
}
6
622eda98dfef6c4fdb84ccca 已提交
107
</script>
6
update  
64104061f23fda247c679fa8 已提交
108
<style>
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
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.dialog {
  flex: 1;
  overflow: auto;
}

.dialog-item {
  display: flex;
}

.dialog-item-main {
  max-width: 80%;
  padding: 8px;
  word-wrap: break-word;
  margin-top: 16px;
  border-radius: 4px;
}

.dialog-item-me {
  justify-content: flex-end;
}

.dialog-item-me .dialog-item-main {
  background-color: antiquewhite;
}

.dialog-item-ai .dialog-item-main {
  background-color: #eee;
}
6
update  
64104061f23fda247c679fa8 已提交
143
</style>