vue+AI智能機(jī)器人回復(fù)功能實(shí)現(xiàn)
本文實(shí)例為大家分享了vue+AI智能機(jī)器人回復(fù)的具體代碼,供大家參考,具體內(nèi)容如下
操作步驟
- 引入前端代碼
前端代碼是參考github上的一個(gè)開(kāi)源項(xiàng)目,里面包括AI機(jī)器人回復(fù)和聊天室兩個(gè)模塊,這里只抽取出來(lái)一個(gè)AI機(jī)器人回復(fù)的前端,有興趣的話(huà),可以點(diǎn)擊查看
- 封裝好代理與請(qǐng)求
因?yàn)榈谌紸PI的請(qǐng)求是外網(wǎng)的,存在跨域問(wèn)題,所以要配置代理,配置如下:
文件:vue.config.js
const vueConfig = {
//上面還有項(xiàng)目的其他配置
devServer: {
port: 8000,
proxy: {
'/ai': {
target: 'http://openapi.tuling123.com/',
changeOrigin: true,
pathRewrite: {'^/ai': ''}
}
}
},
}
module.exports = vueConfig
配完代理后,創(chuàng)建請(qǐng)求實(shí)例:
文件: request.js
// 創(chuàng)建AI機(jī)器人回復(fù)請(qǐng)求axios實(shí)例
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
}
- 調(diào)用第三方AI機(jī)器人的API
第三方AI機(jī)器人有很多,筆者嘗試過(guò)阿里和圖靈兩個(gè),調(diào)用方式都差不多,但是阿里的有點(diǎn)小貴,所以這里以圖靈的為示例:
aiAxios.post('/openapi/api/v2', {
reqType: '0',
perception: {
inputText: {
text: this.inputContent
}
},
userInfo: {
//圖靈上注冊(cè)后自己的機(jī)器人apikey
apiKey: '****',
//登錄用戶(hù)用賬戶(hù)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: '智能機(jī)器人',
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 智能機(jī)器人</h2>
</div>
<div class="chatting-menu">
<i class="icon-menu"></i>
</div>
</div>
<!-- 聊天內(nèi)容區(qū)域 -->
<div ref="chattingContent" id="chattingContent" class="chatting-content">
<div v-for="item of msgs">
<!--用戶(hù)輸入內(nèi)容-->
<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回復(fù)內(nèi)容-->
<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>
<!-- 輸入?yún)^(qū)域 -->
<div class="chatting-input">
<input @keyup.enter="send" v-model.trim="inputContent" placeholder="與智能機(jī)器人聊些啥">
<button @click="send">發(fā)送</button>
</div>
</div>
</transition>
</template>
<script>
import {aiAxios} from '../../../utils/request'
import moment from 'moment'
//下面兩張頭像自己從網(wǎng)上隨便找兩張
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: {
//發(fā)送消息
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機(jī)器人回復(fù)
getClientRobotReply() {
aiAxios.post('/openapi/api/v2', {
reqType: '0',
perception: {
inputText: {
text: this.inputContent
}
},
userInfo: {
//圖靈上注冊(cè)后自己的機(jī)器人apikey
apiKey: '****',
//登錄用戶(hù)用賬戶(hù)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: '智能機(jī)器人',
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>
關(guān)于vue.js組件的教程,請(qǐng)大家點(diǎn)擊專(zhuān)題vue.js組件學(xué)習(xí)教程進(jìn)行學(xué)習(xí)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
mpvue小程序循環(huán)動(dòng)畫(huà)開(kāi)啟暫停的實(shí)現(xiàn)方法
這篇文章主要介紹了mpvue小程序循環(huán)動(dòng)畫(huà)開(kāi)啟暫停的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
手把手教你創(chuàng)建vue3項(xiàng)目的最佳方式
如今的Vue3已經(jīng)勢(shì)不可擋,當(dāng)然搭建一個(gè)全新的Vue3項(xiàng)目也有了全新的方式,下面這篇文章主要給大家介紹了關(guān)于如何手把手教你創(chuàng)建vue3項(xiàng)目的最佳方式,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
vue-quill-editor二次封裝,實(shí)現(xiàn)自定義文件上傳方式
這篇文章主要介紹了vue-quill-editor二次封裝,實(shí)現(xiàn)自定義文件上傳方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
vue 實(shí)現(xiàn)的樹(shù)形菜的實(shí)例代碼
這篇文章主要介紹了vue 實(shí)現(xiàn)的樹(shù)形菜單,需要的朋友可以參考下2018-03-03
Vuejs開(kāi)發(fā)環(huán)境搭建及熱更新【推薦】
Vue.js是目前很火的一個(gè)前端框架,采用MVVM模式設(shè)計(jì),它是以數(shù)據(jù)驅(qū)動(dòng)和組件化的思想構(gòu)建的。本文重點(diǎn)給大家介紹Vuejs開(kāi)發(fā)環(huán)境搭建及熱更新的相關(guān)知識(shí),需要的朋友參考下吧2018-09-09
Vue element-UI el-select循環(huán)選中的問(wèn)題
這篇文章主要介紹了Vue element-UI el-select循環(huán)選中的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10

