前语
没想到从五一之后,到现在鸽了那么久。没办法,实话实说,的确忙,五一期间就没怎样休息,开局榜首周,预备IEEE国际会议报告,第二周大创结题预备材料和最后的代码调试组合。上周还跑到武汉去训练,备研大忌估计是被我踩了个遍。依照以前的传统,在520前,我是会做点啥好玩的东西,用来表达啥的,尽管我是真用不上。不过,不过由于忙,这个传统被打破了,那么居然如此,也是时分迈向未来了。咱们寻求的始终是更高层次的精神会晤,精神上的沟通而不单单是生理上的刺激,如果是那样,洗脚脚未必不可。那么已然,以前是写一点好玩的,用程序去表达一种浪漫给喜欢的女孩子,可是这个女孩子一向再出现对我来说。并且咱们要求的是高级的会晤而非生物上的。经过现实生活当中的”概率论“以及救不了我了,那么为什么不去试试“Artificial probability”。
(这一段开个打趣,引入一下,不要确实,便利我后面吹一下)
(具体后端部分见博文:谈天机器人开发实战–(微信小程序+SpringCloud+Pytorch+Flask)【后端部分】) Now!!!
谈天伴侣,猫雨雫 震撼上线!
打造您的贴身伴侣,女朋友能24小时陪同你吗?不,她不能。男朋友能够嘛?不也不可。 可是咱们能够,It all you need!!!!!!!!!!!!!
架构
好了,牛皮吹完了,咱们来点正派的。 首要为什么要做这个项目呢,肯定不是为了那啥,实际上,是为了做期末作孽。没办法,谁那么无聊呢,尽管我有时分这很符合我的风格。那么这儿也说明一下,那便是,由于这个是期末作孽,所以,我不可能做得太杂乱,做的怎样怎样样。很简略的道理,咱们有才能做好,可是做好的条件是她值得。如果值得,那么我会尽我所能。否则,明明100块就能够搞定,我为什么要花200,太亏了呀。
所以的话,整个项目启动,你会见到三个玩意。
小程序端
这个是个人中心
办理端
运维端
其他的就这样了。 这个结构十分简略。
交互
那么之后的话,便是交互。后端的话,根本上七七八八都说了一下,都是挺简略的东西。
那么这边的话咱们,首要把注意力放在,前端这边。还有到后端的交互。
谈天页面
首要,最重要的当然便是谈天了。 谈天页面的话,设计的十分简略,也没有做什么特效,懒得做。 就这个玩意: 这儿的话是封装为了一个组件,当然这样也是原来找的一个,然后改了一下。
<scroll-view class="cu-chat" scroll-y="true" enable-back-to-top enable-flex scroll-into-view="{{scrollId}}"
style="height:{{systemInfo.windowHeight - 50}}px;" bindscrolltoupper="tapTop"
>
<view wx:for="{{chatList}}" wx:key="index" wx:for-item="item">
<!--robot发送的信息-->
<view class="cu-item" wx:if="{{item.type != 'man'}}" id="msg-{{index}}">
<view class="cu-avatar radius" style="background-image:url({{item.avatarUrl}});"></view>
<view class="main">
<view class="content bg-cyan shadow">
<text>{{item.content}}</text>
</view>
</view>
</view>
<!--自己发送的信息-->
<view class="cu-item self" wx:if="{{item.type == 'man' }}" id="msg-{{index}}">
<view class="main">
<view class="content bg-green shadow">
<text>{{item.content}}</text>
</view>
</view>
<view class="cu-avatar radius" style="background-image:url({{item.avatarUrl}});"></view>
</view>
</view>
</scroll-view>
然后是对应的js
// release/components/chatbox
const app = getApp();
// 时间工具类
const timeutil = require('./timeutil');
const cx = Component({
/**
* 组件的一些选项
*/
options: {
addGlobalClass: true,
multipleSlots: true
},
/**
* 组件的特点列表
*/
properties: {
roomId: {
type: Number,
observer: function (newVal, oldVal) {
if (newVal != undefined && newVal != null) {
// console.log(newVal)
}
}
}
},
/**
* 组件注册页面生命周期
*/
pageLifetimes: {
show: function () {
// 页面被展示
},
},
lifetimes: {
attached() {
var that = this;
that.initMessageHistory();
//初始化监听器
// that.initWatcher();
wx.getSystemInfo({
success: function (res) {
that.setData({
systemInfo: res
})
}
})
},
detached() {
try {
} catch (error) {
console.log('--音讯监听器关闭失利--')
}
}
},
/**
* 组件的初始数据
*/
data: {
openid: app.globalData.openid || wx.getStorageSync('openid'),
scrollId: '',
systemInfo: {},
//音讯记载列表
chatList: [],
//符号触顶事情
isTop: false,
cur_page: 2,
limit: 10,
pagesize: 0,
},
/**
* 组件的办法列表
*/
methods: {
loadMsgs(wid,itemid){
var that = this;
var dataList = that.data.chatList;
wx.request({
method: 'POST',
url: 'http://127.0.0.1:88/api/ikunchat/histories/msgs',
header: {
'content-type': 'application/json'
},
data: {
wid: wid,
itemid: itemid,
page: that.data.cur_page,
limit: that.data.limit
},
success(res) {
// 处理呼应数据
let r_code = res.data.code
if (r_code != 0) {
wx.switchTab({
url: "/pages/mycenter/mycenter"
});
wx.showToast({
title: "请先登录",
icon: 'error',
duration: 2000
})
}else{
let page = res.data.page
that.setData({
cur_page: that.data.cur_page+1
})
let list = page.list
if(list.length==0){
wx.showToast({
title: "到顶了吖~",
icon: 'error',
duration: 2000
})
}
for(var i=0;i<list.length;i++){
dataList.unshift(list[i]);
}
}
},
fail(error) {
// 处理恳求失利状况
wx.switchTab({
url: "/pages/mycenter/mycenter"
});
},
})
},
// 预览图片
viewImage(e) {
// console.log(e)
let url = e.currentTarget.dataset.url;
wx.previewImage({
urls: [url],
})
},
//触顶事情
tapTop() {
console.log('--触顶--')
var that = this;
that.setData({
isTop: true
}, () => {
let current_itemid = app.globalData.curr_itemid
let wid = app.globalData.wid
that.loadMsgs(wid,current_itemid)
})
},
//初始化
initMessageHistory() {
let is_new_chat = app.globalData.is_new_chat
if(is_new_chat){
//初始化音讯前史
var that = this;
app.globalData.cht = that
that.setData({
chatList: [
{
"type":"robot",
"avatarUrl":"../index/image/yu.png",
"content":"你好!我是 羽雫,是由Huterox研发的智能虚拟女友,很快乐认识你~(测试阶段,会话自动保存)",
}
]
})
}else{
var that = this;
let current_itemid = app.globalData.curr_itemid
let wid = app.globalData.wid
that.loadMsgs(wid,current_itemid)
}
},
}
})
根本样式的话没有,由于便是堆上去的,而且作为一个组件。
谈天发送流程
那么之后便是这个流程,这个玩意的话,比较简略。 然后这儿的话,用户的验证啥的做的都很简略,直接用wid,感兴趣的自己能够去优化,也十分简略,这个就作为base beta 作孽版本搞了。
然后便是根本的后端处理逻辑。这个就没啥好说的了,还是比较简略的。
前史谈天记载
然后便是这个玩意:
, 这个玩意的前端代码比较简略,无非便是恳求数据啥的。 然后比较首要的是后端的一个交互。 这儿的话有两个玩意: 也便是这两个:
个人中心
个人中心的话其实就两个,一个是注册登录,还有一个是检查当时剩余次数。当时是想要做全套,再来个付出接口的。可是后来没时间,砍掉了。 这个是相应的前端代码完成:
<view class="top-bg"></view>
<view class="box">
<!-- 头像 -->
<view class="head-box">
<button open-type="chooseAvatar" class="avatar" bindchooseavatar="chooseAvatar">
<image class="head-img" src="{{login.avatar}}" mode="widthFix"></image>
</button>
<view class="tip">{{login.show?'欢迎运用':'当时未登录,请登录!'}}</view>
</view>
<!-- 榜首部分列表 -->
<view>
<button class="row" style="width: 100%;" bindtap="basicClick">
<view class="left">
<icon class="icon-small" type="success" size="16"></icon>
<text class="text">今日限额</text>
</view>
<view class="right">》</view>
</button>
<button class="row" style="width: 100%;" bindtap="feedbackClick">
<view class="left">
<icon class="icon-small" type="success" size="16"></icon>
<text class="text">FeedBack</text>
</view>
<view class="right">》</view>
</button>
<button class="row" style="width: 100%;border-bottom: none;" bindtap="aboutClick">
<view class="left">
<icon class="icon-small" type="success" size="16"></icon>
<text class="text">关于咱们</text>
</view>
<view class="right">》</view>
</button>
</view>
</view>
<!-- 第二部分列表 -->
<view class="end">
<button open-type="share" class="row" style="width: 100%;">
<view class="left">
<icon class="icon-small" type="success" size="16"></icon>
<text class="text">分享老友</text>
</view>
<view class="right">》</view>
</button>
</view>
<!-- 第三部分列表 -->
<view class="end">
<button wx:if="{{login.line}}" bindtap="exitClick" class="row" style="width: 100%;border-bottom: none;">
<view class="left">
<icon class="icon-small" type="success" size="16"></icon>
<text class="text">退出登录</text>
</view>
</button>
<button class="row" open-type="chooseAvatar" bindchooseavatar="chooseAvatar" style="width: 100%;border-bottom: none;" wx:else>
<view class="left">
<icon class="icon-small" type="success" size="16"></icon>
<text class="text">当即登录</text>
</view>
</button>
</view>
<view class="footer">
<text>Huterox is awesome!</text>
</view>
然后是js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
login: {
show: false,
avatar: 'https://img0.baidu.com/it/u=3204281136,1911957924&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
},
count: 10,
wid: 0,
},
// 登录监听
chooseAvatar(e) {
console.log(e.detail.avatarUrl)
var that = this;
//恳求后端服务器完成登录
this.setData({
login: {
show: true,
avatar: "../index/image/me.png",
}
})
wx.request({
method: 'POST',
url: 'http://127.0.0.1:88/api/ikunchat/wcenter/login',
header: {
'content-type': 'application/json'
},
data: {
wid: app.globalData.wid
},
success(res) {
// 处理呼应数据
let r_code = res.data.code
if(r_code==0){
that.setData({
login: {
show: true,
avatar: "../index/image/me.png",
}
})
app.globalData.islogin = res.data.itemid
}else{
wx.showToast({
title: res.data.msg,
icon: 'error',
duration: 2000
})
}
},
fail(error) {
// 处理恳求失利状况
wx.showToast({
title: error,
icon: 'error',
duration: 2000
})
}
})
},
// 根本信息
basicClick() {
console.log(app.globalData.wid)
var that = this;
wx.request({
method: 'POST',
url: 'http://127.0.0.1:88/api/ikunchat/wcenter/count',
header: {
'content-type': 'application/json'
},
data: {
wid: app.globalData.wid
},
success(res) {
// 处理呼应数据
let r_code = res.data.code
if(r_code==0){
that.setData({
count: res.data.msg
})
console.log(that.data.count)
//显现
wx.showModal({
title: 'Hello ~',
content: '剩余次数:' + that.data.count,
success(res) {
if (res.confirm) {
console.log('用户点击了确认按钮')
} else if (res.cancel) {
console.log('用户点击了撤销按钮')
}
}
})
}else{
wx.showToast({
title: res.data.msg,
icon: 'error',
duration: 2000
})
}
},
fail(error) {
// 处理恳求失利状况
wx.showToast({
title: error,
icon: 'error',
duration: 2000
})
}
})
console.log('根本信息监听');
},
// 匿名反应
feedbackClick() {
wx.showModal({
title: 'Huterox',
content: '有问题随时email:3139541502@qq.com',
success(res) {
if (res.confirm) {
console.log('用户点击了确认按钮')
} else if (res.cancel) {
console.log('用户点击了撤销按钮')
}
}
})
console.log('匿名反应监听');
},
// 关于咱们
aboutClick() {
wx.showModal({
title: 'Huterox',
content: '嘿,我是一个操练时长一kun年的代码操练生',
success(res) {
if (res.confirm) {
console.log('用户点击了确认按钮')
} else if (res.cancel) {
console.log('用户点击了撤销按钮')
}
}
})
console.log('关于咱们监听');
},
// 退出监听
exitClick() {
let that = this;
wx.showModal({
title: '提示',
content: '确认退出登录吗?',
success(res) {
if (res.confirm) {
that.setData({
login: {
show: false,
avatar: 'https://img0.baidu.com/it/u=3204281136,1911957924&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
}
})
}
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
var app = getApp(); // 获取 App 实例
if (app.globalData.islogin){
this.setData({
login: {
show: true,
avatar: "../index/image/me.png",
}
})
//获取剩余次数
var that = this;
wx.request({
method: 'POST',
url: 'http://127.0.0.1:88/api/ikunchat/wcenter/count',
header: {
'content-type': 'application/json'
},
data: {
wid: app.globalData.wid
},
success(res) {
// 处理呼应数据
let r_code = res.data.code
if(r_code==0){
that.setData({
count: res.data.msg
})
}else{
wx.showToast({
title: res.data.msg,
icon: 'error',
duration: 2000
})
}
},
fail(error) {
// 处理恳求失利状况
wx.showToast({
title: error,
icon: 'error',
duration: 2000
})
}
})
}
},
/**
* 生命周期函数--监听页面初次烘托完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显现
*/
onShow() {
},
/**
* 生命周期函数--监听页面躲藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事情处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事情的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
之后的话是css
page {
background-color: #f1f1f1;
}
/* 设置布景颜色 */
.top-bg {
height: 260rpx;
background-color: #a0cfff;
}
/* 圆角盒子 */
.box {
background-color: white;
margin-top: -120rpx;
border-top-left-radius: 50rpx;
border-top-right-radius: 50rpx;
padding: 0 20rpx;
}
/* 头像部分 */
.head-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-bottom: 1rpx solid #fbdbdc;
padding-bottom: 20rpx;
}
.avatar {
margin-top: -80rpx;
font-weight: inherit;
display: flex;
justify-content: center;
background-color: rgba(0, 0, 0, 0);
}
.avatar::after {
border: none;
}
.head-img {
width: 140rpx;
height: 140rpx;
overflow: hidden;
border-radius: 50%;
background-color: #fbdbdc;
}
.tip {
font-size: 26rpx;
color: gray;
margin: 15rpx 0;
}
/* 列表部分 */
.row {
display: flex;
align-items: center;
padding: 36rpx 10rpx;
font-size: 30rpx;
font-weight: inherit;
background-color: rgba(0, 0, 0, 0);
border-bottom: 1rpx solid #fbdbdc;
}
.row::after {
border: none;
}
.text {
margin-left: 15rpx;
color: #636262;
}
.left {
width: 90%;
text-align: left;
display: flex;
align-items: center;
}
.right {
width: 10%;
text-align: right;
color: rgb(148, 147, 147);
}
.end {
background-color: white;
margin-top: 20rpx;
padding: 0 20rpx;
}
.footer {
display: flex;
justify-content: center;
align-items: center;
padding: 20rpx 0;
font-size: 22rpx;
margin: 30rpx 0;
color: gray;
}
后端对应的便是这两个玩意:
总结
那么以上便是全部内容了,想要源码的话,评论区留言的同时一键三联~ 谢谢