vue+AI智能機器人回覆

操作步驟

  • 引入前端代碼

    前端代碼是參考github上的一個開源項目,裏面包括AI機器人回覆和聊天室兩個模塊,這裏只抽取出來一個AI機器人回覆的前端,有興趣的話,可以點擊查看

  • 封裝好代理與請求

    因爲第三方API的請求是外網的,存在跨域問題,所以要配置代理,配置如下:

    文件:vue.config.js

    const vueConfig = {
        //上面還有項目的其他配置
        
        devServer: {
            port: 8000,
            proxy: {
              '/ai': {
                target: 'http://openapi.tuling123.com/',
                changeOrigin: true,
                pathRewrite: {'^/ai': ''}
              }
            }
        },
    }
    module.exports = vueConfig
    

    配完代理後,創建請求實例:

    文件: request.js

    // 創建AI機器人回覆請求axios實例
    const aiService = axios.create({
      //VUE_APP_AI_BASE_URL=/ai
      //baseURL: process.env.VUE_APP_AI_BASE_URL,
      baseURL: '/ai',
      timeout: 10000
    })
    
    ……
    
    export {
      aiService as aiAxios
    }
    
  • 調用第三方AI機器人的API

    第三方AI機器人有很多,筆者嘗試過阿里和圖靈兩個,調用方式都差不多,但是阿里的有點小貴,所以這裏以圖靈的爲示例:

    aiAxios.post('/openapi/api/v2', {
          reqType: '0',
          perception: {
            inputText: {
              text: this.inputContent
            }
          },
          userInfo: {
            //圖靈上註冊後自己的機器人apikey
            apiKey: '****',
            //登錄用戶用賬戶ID
            userId: '123456'
          }
        }).then(res => {
          let text= res.data.results[0].values.text;
          this.msgs.push({
            date: moment().format('YYYY-MM-DD HH:mm:ss'),
            from: '智能機器人',
            content: text,
            self: false,
            avatarUrl: aiHeadImg
          })
          this.$refs.chattingContent.scrollTop = this.$refs.chattingContent.scrollHeight
        }).catch(err => {
          this.$message.info(err);
    })
    

整體示例代碼

<template lang="html">
  <transition name="slide-right">
    <div class="chatting">
      <!-- 聊天界面頭部 -->
      <div class="chatting-header">
        <div class="chatting-back">
          <i class="icon-back"></i>
        </div>
        <div class="chatting-title">
          <h2>AI 智能機器人</h2>
        </div>
        <div class="chatting-menu">
          <i class="icon-menu"></i>
        </div>
      </div>
      <!-- 聊天內容區域 -->
      <div ref="chattingContent" id="chattingContent" class="chatting-content">
        <div v-for="item of msgs">
          <!--用戶輸入內容-->
          <div v-if="item.self" class="chatting-item self clearfix">
            <div class="msg-date">
              {{ item.date }}
            </div>
            <div class="msg-from">
              <span class="msg-author">{{ item.from}}</span>
              <img :src="item.avatarUrl" alt="">
            </div>
            <div class="msg-content">{{ item.content }}</div>
          </div>
          <!--AI回覆內容-->
          <div v-else class="chatting-item other clearfix">
            <div class="msg-date">
              {{ item.date }}
            </div>
            <div class="msg-from">
              <img :src="item.avatarUrl" alt="">
              <span class="msg-author">{{ item.from }}</span>
            </div>
            <div class="msg-content">{{ item.content }}</div>
          </div>
        </div>
      </div>
      <!-- 輸入區域 -->
      <div class="chatting-input">
        <input @keyup.enter="send" v-model.trim="inputContent" placeholder="與智能機器人聊些啥">
        <button @click="send">發送</button>
      </div>
    </div>
  </transition>

</template>

<script>
  import {aiAxios} from '../../../utils/request'
  import moment from 'moment'
  //下面兩張頭像自己從網上隨便找兩張
  import aiHeadImg from '../../../assets/web/pub/images/head-ai.svg'
  import clientHeadImg from '../../../assets/web/pub/images/pltx.png'

  export default {
    name: 'chatting',
    data() {
      return {
        msgs: localStorage.msgs_ai && JSON.parse(localStorage.msgs_ai) || [],
        inputContent: '',
        oContent: {}
      }
    },
    watch: {
      msgs(val) {
        localStorage.msgs_ai = JSON.stringify(val);
      }
    },

    mounted() {
      this.oContent = document.getElementById('chattingContent');
      setTimeout(() => {
        this.$refs.chattingContent.scrollTop = this.$refs.chattingContent.scrollHeight
      }, 0)
    },
    methods: {
      //發送消息
      send() {
        this.oContent.scrollTop = this.oContent.scrollHeight;
        if (this.inputContent === '') {
          return;
        }

        this.msgs.push({
          date: moment().format('YYYY-MM-DD HH:mm:ss'),
          from: this.userInfo.personname || '匿名',
          content: this.inputContent,
          self: true,
          avatarUrl: clientHeadImg
        });
        setTimeout(() => {
          this.$refs.chattingContent.scrollTop = this.$refs.chattingContent.scrollHeight
        }, 0)

        this.getClientRobotReply()
        this.inputContent = '';
      },
      //圖靈AI機器人回覆
      getClientRobotReply() {
        aiAxios.post('/openapi/api/v2', {
          reqType: '0',
          perception: {
            inputText: {
              text: this.inputContent
            }
          },
          userInfo: {
            //圖靈上註冊後自己的機器人apikey
            apiKey: '****',
            //登錄用戶用賬戶ID
            userId: '123456'
          }
        }).then(res => {
          let text= res.data.results[0].values.text;
          this.msgs.push({
            date: moment().format('YYYY-MM-DD HH:mm:ss'),
            from: '智能機器人',
            content: text,
            self: false,
            avatarUrl: aiHeadImg
          })
          this.$refs.chattingContent.scrollTop = this.$refs.chattingContent.scrollHeight
        }).catch(err => {
          this.$message.info(err);
        })
      }
    }
  }
</script>

<style  lang="less" scoped>
  .chatting {
    display: flex;
    flex-direction: column;

    width: 100%;
    height: 100%;

    .chatting-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 50px;
      width: 100%;
      background-color: #2196f3;
      color: white;
      padding-left: 10px;
      padding-right: 15px;

      .chatting-back {
        width: 30px;
        height: 30px;
        i.icon-back {
          /*background: url('../../common/icons/icon-group2.svg') no-repeat;*/
          background-size: contain;
        }
      }

      .chatting-title {
        i.icon-group {
          vertical-align: top;
          width: 30px;
          height: 30px;
          //background: url('./images/icon-group.svg') no-repeat;
          background-size: contain;
          margin-right: 3px;
        }
      }

      .chatting-menu {
        width: 30px;
        height: 30px;
        i.icon-menu {
          /*background: url('../../common/icons/icon-index.svg') no-repeat;*/
          background-size: contain;
        }
      }
    }

    .chatting-content {
      flex: 1;
      width: 100%;
      background-color: rgba(0, 0, 0, .1);
      overflow: auto;
      .chatting-item {
        padding: 10px;
        width: 100%;
        .msg-date {
          text-align: center;
          color: gray;
          font-size: 80%;
        }
        .msg-from {
          display: flex;
          align-items: center;
          span.loc {
            color: gray;
            font-size: 60%;
            margin-right: 5px;
          }
          .msg-author {
            font-size: 1.2rem;
          }
          img {
            width: 30px;
            height: 30px;
            border-radius: 15px;
          }
        }
        .msg-content {
          margin-top: 5px;
          background-color: white;
          width: 200px;
          padding: 6px 10px;
          border-radius: 10px;
        }
      }

      .chatting-item + .chatting-item {
        margin-top: 10px;
      }
      .self {
        .msg-from {
          display: flex;
          justify-content: flex-end;
          align-items: center;
          img {
            margin-left: 10px;
          }
        }

        .msg-content {
          float: right;
          word-wrap: break-word;
          word-break: break-all;
          margin-right: 10px;
        }


      }

      .other {
        .msg-from {
          display: flex;
          justify-content: flex-start;
          align-items: center;
          img {
            margin-right: 10px;
          }
        }

        .msg-content {
          float: left;
          margin-left: 10px;
          word-wrap: break-word;
          word-break: break-all;
        }

      }

      .online {
        width: 200px;
        // max-width: 100%;
        margin: 3px auto;
        border-radius: 4px;
        text-align: center;
        background-color: #FFFDE7;
      }
    }

    .chatting-input {
      display: flex;
      height: 40px;
      width: 100%;
      input {
        flex: 1;
        padding-left: 10px;
        // padding-top: 10px;
        height: 100%;
        font-size: 1.3rem;
      }
      button {
        width: 60px;
        height: 100%;
        background-color: #2196f3;
        color: white;
        font-size: 1.2rem;
      }
    }
  }
</style>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章