App.vue 2.8 KB
Newer Older
6
628c9f991a7e4862742d8a2f 已提交
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
<template>
  <div class="main">
    <div class="main-ctx">
      <msg-row
        v-for="item in msgQuenue"
        :key="item"
        :data="item"
      />
    </div>
    <div class="main-footer">
      <div class="main-footer-ctx">
        <send-button @click="send" class="main-footer-btn"/>
        <input v-model="msg" class="main-footer-input" @keypress.enter.native="send"/>
      </div>
    </div>
  </div>
</template>

<script>
import SendButton from './components/send-button.vue'
import MsgRow from './components/msg-row.vue'
import request from './api/index';
import { reactive } from 'vue';

export default {
  components: { SendButton, MsgRow },
  data () {
    return {
      msg: '',
      loading: false,
      msgQuenue: []
    }
  },
  methods: {
    async send () {
      if (this.msg.trim() === '') return
      if (this.loading) return
      this.loading = true
      this.msgQuenue.push({
        role: 'user',
        content: this.msg
      })
      const requestMsg = this.msg
      this.msg = ''
      const item = reactive({
        role: 'assist',
        loading: true,
        content: ''
      })
      this.msgQuenue.push(item)
      this.$nextTick(() => {
        // 测试
        window.scrollTo(0, document.body.scrollHeight)
      })
      request({
        url: 'v1/chat/completions',
        method: 'post',
        data: {
          model: 'gpt-3.5-turbo',
          messages: [{ role: 'user', content: requestMsg }]
        }
      }).then(res => {
        const { data } = res
        const msg = this.getMsg(reactive(data.choices))
        item.content = msg.content
        item.loading = false
        this.$nextTick(() => {
          window.scrollTo(0, document.body.scrollHeight)
        })
      }).catch(err => {
        item.content = '请求超时或失败!'
        item.loading = false
      }).finally(() => {
        this.loading = false
      })
    },
    getMsg (choices = []) {
      if (choices.length) {
        return {
          error: false,
          ...choices[0].message
        }
      }
      return {
        error: true
      }
    }
  }
}
</script>

<style lang="less">
.main {
  background: rgb(55, 56, 67);
  position: relative;
  box-sizing: border-box;
  width: 100%;
  min-height: 100vh;
  padding: 0 0 100px 0;
  &-footer {
    position: relative;
    width: 100%;
    position: fixed;
    bottom: 36px;
    overflow: hidden;
    text-align: center;
    &-ctx {
      display: inline-block;
      position: relative;
      width: 60%;
    }
    &-input {
      width: 100%;
      color: #FFF;
      padding: 0 12px;
      display: inline-block;
      height: 42px;
      margin: 0 auto;
      border-radius: 6px;
      background: rgb(66, 67, 80);
    }
    &-btn {
      position: absolute;
      right: 8px;
      top: 50%;
      margin-top: -13px;
    }
  }
}
</style>