关于微信小程序制作消息部分时方法

本文详细描述了如何在微信小程序中实现用户接收到的消息展示、云端数据上传与调用,以及用户信息的获取和聊天界面的跳转。重点介绍了数据库操作、用户openid的管理以及消息列表的动态渲染。
摘要由CSDN通过智能技术生成

这个界面主要以两个界面组成:

1、展示用户接收到的消息

2、用户与用户的聊天界面

1.上传云端的数据

如果去做这个,首先第一就是如何将信息部分放入数据库,以及从数据库中调用

在上传的时候可以上传形似data这样的形式:

{
  const data={
    sender: "person1"   //消息的发送者openid
    receiver: "person2" //消息的接收者openid
    content: {message:"hello world",time:""}  //正文内容,存放文本内容,以及文本的发送时间
    num:id //为信息标号
    //其他信息    
  }
}

2.界面一的主要数据部分

pages({
  data:{
    sender_user=[] //存放发送者的openid
  }

  onLoad(){
    this.getSender()
  }

  getSender(){ //获取发送者openid
    var sender_user=[] //存放发送者的openid
    var that=this
    wx.cloud.database().collection('chat').where({receiver:"MyOpenid"}).get().then(res=>{
      for(var i=0;i<res.data.length;i++) sender_user.push(res.data[i].sender)
      let message = Array.from(new Set(sender_user));//去除sender_user里的重复元素
      that.setData({sender_user:message)}
    })
  }

})

也就是说在这个代码里面,sender是消息的发送者,而receiver是消息的接收者,这样就成功把聊天的信息上传到了自己的云服务器,那么在调用

的时候应该怎么去调用呢,这个也是个问题

如果是我上述的第一个界面,也就是取用户的信息,将其展示出来,并且点击后能跳到对应的聊天窗口。那么就必须要知道用户的openid,和我的openid,在这里由于我是信息的接收者,所以在查找数据的时候要满足一个条件,也就是where({receiver:"MyOpenid"}),那么我们在寻找的时候就可以把sender的openid找出来,存放再sender_user里面,代码如下


 

找出sender的openid后就可以通过其openid找出具体的用户信息,也就是找出用户的名字和头像,让其渲染出来,那么假设我在数据库中有一个集合user,里面存放着用户信息,其中就有用户头像(avatarUrl)和用户名字(nickName),那么就会有如下代码:

pages({
  data:{
    sender_user:[] //存放sender的openid
    sender_message:[]//存放sender的用户信息
  }

  onLoad(){
    this.getSender()
  }

  getSender(){ //获取发送者openid、头像以及头像名字
    var sender_user=[] //存放发送者的openid
    var sender_message=[]//存放sender的用户信息
    var that=this

    wx.cloud.database().collection('chat').where({receiver:"MyOpenid"}).get().then(res=>{
      for(var i=0;i<res.data.length;i++) sender_user.push(res.data[i].sender)
      let message = Array.from(new Set(sender_user));//去除sender_user里的重复元素
      that.setData({sender_user:message)}

      wx.cloud.database().collection('user').get().then(res=>{
        var user=res.data//用user存放所有用户的信息
        for(var i=0;i<message.length;i++){ //取用message[i]的信息,也就是用户openid
          for(var j=0;j<user.length;j++){ //通过message[i]查找对应的用户信息
            if(message[i]==user[j]._openid){ //如果查找到了
              avatarUrl=user[j].avatarUrl //获取头像信息
              nickName=user[j].nickName   //获取用户名字
              sender_message.push({avatarUrl:avatarUrl,nickName:nickName})
            }
          }
        }
        that.setData({sender_message:sender_message})
      })
    })
  }

})

那么,到目前位置,这个界面的数据构造就完成了,接下来就是渲染部分:

<!--wxml-->
<view class="menu">
  <view wx:for="{{sender_message}}" data-index="{{index}}" class="user" bindtap="jump_chat" data-username="User1">
    <image class="avatar" src="{{item.avatarUrl}}"></image>
    <text>{{item.nickName}}</text>
  </view>
  <!-- More user bars go here -->
</view>
/* wxss */
.menu {
  padding: 10px;
}

.user {
  display: flex;
  align-items: center;
  padding: 10px;
  margin-bottom: 10px;
  background-color: #f2f2f2;
  cursor: pointer;
}

.avatar {
  width: 60px; 
  height: 60px;
  border-radius: 50%;
  margin-right: 10px;
}

.user text {
  font-size: 18px; 
}

在上述wxml里面有个bindtap部分没有对其进行介绍,这个事件使用户点击其他用户框时会跳转到对应的聊天界面下面就是这个bindtap的具体代码 ,在这串代码中,yourID,也就是receiver将会是用户自己,故在进行这个事件时需要获取用户自己的openid

  jump_chat(e){
    console.log(e.currentTarget.dataset.index)
    let user=this.data.user
    var x=user[e.currentTarget.dataset.index]
    var chat_user={sender:"openid_1",receiver:"yourID"}//存放二者的openid
    wx.setStorageSync('chat_user', chat_user)
/*这样做方便从这个界面把sender和receiver的openid传送到chat.js*/
    wx.navigateTo({
      url: '/pages/chat/chat',
    })
  },

 现在进入界面二,chat.wxml:

{
  const data={
    sender: "person1"   //消息的发送者openid
    receiver: "person2" //消息的接收者openid
    content: {message:"hello world",time:""}  //正文内容,存放文本内容,以及文本的发送时间
    num:id //为信息标号
    //其他信息    
  }
}

在界面二中,两个元素:发送者(sender)和接收者(receiver)的openid,我们首先需要将缓存中的chat_user取出来,这个时候不同的时,发送者(sender)将会变成用户自己,这个时候就要注意在上传chat数据时sender=yourID,在这里我们去调用数据库chat的时候只需要调用用户接受的信息,以及用户发送给目标的信息,这里我计划使用content_sender和content_receiver这两个appdata,

但是仅仅通过这种方式去显示,会发现一个问题,那就是显示出来content_sender和content_receiver的信息集中分成两坨,并没有时间顺序了,那么在这里信息标号就起到作用了,我们就要调取上述代码所提到的四个数据(sender,receiver,content,num),我们在获取了content_sender和content_receiver之后,把他们集中在一个数组中,我假设这个数组是content_show。步骤如下:

step1:从数据库chat中获取信息where({sender:yourID,receiver:openid_1})=>获取用户发送的信息,存放在content_sender

step2:从数据库chat中获取信息where({sender:openid_1,receiver:yourID})=>获取用户接收到的信息,存放在content_receiver

step3:将content_sender和content_receiver合并存入content_show

step4:在content_show里面使元素按照num的正序排列

step5:显示的收以content_show里的元素渲染,并且分出sender是否为yourID,如果是的话,那么这个部分的content显示在右边,反之,则在左边

那么下面就是代码

js:

// pages/chat/chat.js
/*|->receiver      |
  |        sender<-|*/
Page({

  /**
   * 页面的初始数据
   */
  data: {
    chat_user:{},
    content_receiver:[],
    content_sender:[],
    message:"",
    time:"",
    userInfo:{},
    content_show:[]
  },
  get_input(e){
    console.log(e.detail.value)
    this.setData({message:e.detail.value})
  },
  sendMessage() {//发送信息
    let content_sender=this.data.content_sender
    let message = this.data.message;
    let chat_user=this.data.chat_user
    var that=this
    if(message.length==0){
      wx.showToast({
        title:"文本不能为空",
        icon:"error",
        duration:1500
      })
      return 0;
    }
    this.get_time()
    let time=this.data.time
    console.log(content_sender);
    wx.cloud.database().collection('chat').get().then(res=>{
      console.log(res.data.length)
      var num=res.data.length+1
      const chat={
        num:num,
        receiver: chat_user.sender,
        sender: chat_user.receiver,
        content: {time:time,message:message},
        time: time,
        receiver_onload:false,
        show:true
      };console.log(chat)
      content_sender.push(chat)
      wx.cloud.database().collection('chat').add({data:chat})
      this.setData({content_sender:content_sender})
      this.make_message_showContent()
      this.setData({message:""})
    })
  },
  get_time(){// app.js

    // 获取当前时间
    const now = new Date();
    const year = now.getFullYear(); // 获取年份
    const month = String(now.getMonth() + 1).padStart(2, '0'); // 获取月份,并在前面补零
    const date = String(now.getDate()).padStart(2, '0'); // 获取日期,并在前面补零
    const hours = String(now.getHours()).padStart(2, '0'); // 获取小时,并在前面补零
    const minutes = String(now.getMinutes()).padStart(2, '0'); // 获取分钟,并在前面补零
    
    // 格式化时间
    const formattedTime = `${year}-${month}-${date} ${hours}:${minutes}`;
    console.log('格式化后的时间:', formattedTime);
    this.setData({time:formattedTime})
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    let chat_user = wx.getStorageSync('chat_user');
    this.setData({ chat_user: chat_user });
    this.get_message_sender();
    this.get_message_receiver();
  }
  get_message_sender() {
    let chat_user = this.data.chat_user;
    var that = this;
    wx.cloud.database().collection('chat').where({ receiver: chat_user.receiver, sender: chat_user.sender }).get().then(res => {
      var content_sender=[]
      for(var i=0;i<res.data.length;i++) content_sender.push(res.data[i])
      that.setData({ content_sender: content_sender }, () => {
        this.make_message_showContent();
      });
    });
  },
  get_message_receiver() {
    let chat_user = this.data.chat_user;
    var that = this;
    wx.cloud.database().collection('chat').where({ receiver: chat_user.sender, sender: chat_user.receiver }).get().then(res => {
      var content_receiver=[]
      for(var i=0;i<res.data.length;i++) content_receiver.push(res.data[i])
      that.setData({ content_receiver: content_receiver }, () => {
        this.make_message_showContent();
      });
    });
  },
  make_message_showContent() {
    let content_receiver = this.data.content_receiver, content_sender = this.data.content_sender;
    console.log(this.data, content_receiver);
    let content_show = content_receiver.concat(content_sender);
    content_show.sort((a, b) => a.num - b.num);
    console.log(content_show, content_receiver);
    this.setData({ content_show: content_show });
  },
  
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    console.log("onshow")
    this.make_message_showContent()
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

wxml:

<!--pages/notice/intendant/pulish_all/pulish_all.wxml-->
<!-- pages/chat/chat.wxml -->
<view class="container">
  <scroll-view class="chat-history" id="myScrollView" scroll-y="true">
    <!-- 这里显示聊天历史记录 -->
    <view wx:for="{{content_show}}" wx:key="id" class="chat-container">
      <view wx:if="{{item.sender==chat_user.sender}}" class="chat-message from-other">
        <text class="message-content">{{item.content.message}}</text>
      </view>
      <view wx:if="{{item.sender==chat_user.receiver}}" class="chat-message from-me">
        <text class="message-content">{{item.content.message}}</text>
      </view>
    </view>
  </scroll-view>
  <view class="input-box">
    <textarea class="input" placeholder="请输入消息" bindinput="get_input" value="{{message}}"></textarea>
    <button class="send-button" bindtap="sendMessage" size="mini">发送</button>
  </view>
</view>

wxss:

​
/* 在对应的样式文件中 */
.container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  padding: 5vw; /* 使用vw作为长度单位 */
}

.chat-history {
  flex: 1;
  background-color: #f2f2f2;
  padding: 5vw; /* 使用vw作为长度单位 */
  margin-bottom: 5vw; /* 使用vw作为长度单位 */
  border-radius: 2vw; /* 使用vw作为长度单位 */
  overflow-y: auto;
}

.input-box {
  display: flex;
  align-items: center;
}

.input {
  flex: 1;
  height: 10vw; /* 使用vw作为长度单位 */
  padding: 5vw; /* 使用vw作为长度单位 */
  border: 0.5vw solid #cccccc; /* 使用vw作为长度单位 */
  border-radius: 2vw; /* 使用vw作为长度单位 */
  margin-right: 5vw; /* 使用vw作为长度单位 */
  width: 60vw;
}

.send-button {
  width: 30vw; /* 使用vw作为长度单位 */
  height: 10vw; /* 使用vw作为长度单位 */
  background-color: #F44336;
  color: #ffffff;
  border: 0;
  border-radius: 2vw; /* 使用vw作为长度单位 */
}

/* chat.wxss */
.chat-container {
  padding: 20rpx;
  display: flex;
  flex-direction: column;
  align-items: flex-end; /* 将内容靠右对齐 */
}

.chat-message {
  max-width: 90%; /* 调整为更宽的宽度 */
  padding: 10rpx;
  margin-bottom: 10rpx;
  border-radius: 10rpx;
  word-wrap: break-word; /* 或者 white-space: pre-wrap; */
}

.from-other {
  background-color: #e0e0e0;
  align-self: flex-start;
}

.from-me {
  background-color: #b2edc4;
  align-self: flex-end;
}

.message-content {
  font-size: 30rpx;
  color: #333; /* 设置文字颜色 */
}

​

 目前这个聊天显示还不算成熟,也还有很多元素为加进来,之后如果有新内容必会更新

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值