zhaoxiaohai 3 years ago
parent
commit
7b96efdf54

+ 37 - 1
app.js

@@ -33,7 +33,7 @@ App({
         "siteid": "BWJ",
         "fclienttype": "MOBILE"
       }
-    }).then(res => {
+    }, false).then(res => {
       if (res.msg != '成功') {
         this.globalData.count = this.globalData.count + 1;
         if (this.globalData.count > 3) this.getBanner();
@@ -42,10 +42,46 @@ App({
       wx.setStorageSync('bannerDataList', res.data)
     })
   },
+  initSocket() {
+    console.log('websocket:', 'ws://www.buwanjia.com:80/bwj/webSocket/' + wx.getStorageSync('userData').token)
+    let that = this;
+    this.globalData.SocketTask = wx.connectSocket({
+      url: 'ws://www.buwanjia.com:80/bwj/webSocket/' + wx.getStorageSync('userData').token,
+      complete: (res) => {
+        console.log(res)
+      }
+    })
+    this.globalData.SocketTask.onOpen(function (res) {
+      console.log('WebSocket连接已打开!readyState=' + that.globalData.SocketTask.readyState);
+      that.globalData.socketEstablish = true;
+      /* var openid = wx.getStorageSync('openid')
+      wx.sendSocketMessage({
+        data: openid
+      }); */
+    })
+    this.globalData.SocketTask.onMessage(function (res) {
+      that.globalData.callback(res)
+    })
+    this.globalData.SocketTask.onError(function (res) {
+      console.log('readyState=' + that.globalData.SocketTask.readyState)
+      that.initSocket()
+    })
+    this.globalData.SocketTask.onClose(function (res) {
+      console.log('WebSocket连接已关闭!readyState=' + that.globalData.SocketTask.readyState)
+      if (that.globalData.socketEstablish == false) {
+        that.initSocket()
+      } else {
+        that.globalData.socketEstablish = false;
+      }
+    })
+  },
   globalData: {
     myNavBorHeight: 0, //自定义头部导航高度
     safeAreaBottom: 0, //底部安全距离
     msgFcount: "", //徽标数量
     count: 0, //banner 请求次数
+    socketEstablish: false, //是否已经建立socket
+    SocketTask: '',
+    callback: function () {},
   }
 })

+ 0 - 9
components/My_VerticalBox/index.js

@@ -15,15 +15,6 @@ Component({
             value: 'home'
         }
     },
-    lifetimes: {
-        attached: function () {
-            // 在组件实例进入页面节点树时执行
-            console.log(this.data.list)
-        },
-        detached: function () {
-            // 在组件实例被从页面节点树移除时执行
-        },
-    },
 
     /**
      * 组件的初始数据

+ 1 - 1
pages/annunciate/index.wxss

@@ -56,7 +56,7 @@
     height: 54rpx;
     font-size: 24rpx;
     color: #333333;
-    line-height: 27rpx;
+    line-height: 30rpx;
     opacity: .7;
     margin-top: 10rpx;
     white-space: pre-line;

+ 12 - 3
pages/chatRoom/MsgBubble/index.js

@@ -5,11 +5,11 @@ Component({
      */
     properties: {
         role: {
-            type: String, //角色 my 我的 you 别人
+            type: String, //角色 my 我的 you 别人 file 附件
         },
         type: {
             type: String,
-            value: "text" //消息类型
+            value: "text" //消息类型 file
         },
         content: {
             type: String //消息内容
@@ -19,6 +19,9 @@ Component({
         },
         time: {
             type: String //时间
+        },
+        fobsurl: {
+            type: String
         }
     },
 
@@ -33,6 +36,12 @@ Component({
      * 组件的方法列表
      */
     methods: {
-
+        viewImage() {
+            let urls = [];
+            urls.push(this.data.fobsurl)
+            wx.previewImage({
+                urls:urls
+            })
+        }
     }
 })

+ 12 - 2
pages/chatRoom/MsgBubble/index.wxml

@@ -2,13 +2,23 @@
 <view wx:if="{{role=='you'}}" class='opposite-side'>
     <image wx:if="{{userImg}}" class="userImg" src="{{userImg}}"></image>
     <image wx:else class="userImg" src="/static/tacitly-approve/MRproduct.png"></image>
-    <view class="content">{{content}}
+    <view class="content" style="background: {{type=='text'?'':'#fff'}}; padding: {{type=='text'?'':'20rpx 0 0 0'}};">
+        <block wx:if="{{type=='text'}}">
+            {{content}}</block>
+        <block wx:else>
+            <image style="width: 320rpx;" mode="widthFix" src="{{fobsurl}}" catchtap="viewImage"></image>
+        </block>
         <view class="msg-time">{{time}}</view>
     </view>
 </view>
 <!-- 自己 -->
 <view wx:if="{{role=='my'}}" class='my-msg'>
-    <view class="content">{{content}}
+    <view class="content" style="background: {{type=='text'?'':'#fff'}}; padding: {{type=='text'?'':'0rpx'}};">
+        <block wx:if="{{type=='text'}}">
+            {{content}}</block>
+        <block wx:else>
+            <image style="width: 320rpx;" mode="widthFix" src="{{fobsurl}}" catchtap="viewImage"></image>
+        </block>
         <view class="msg-time">{{time}}</view>
     </view>
     <image wx:if="{{userImg}}" class="userImg" src="{{userImg}}"></image>

+ 8 - 0
pages/chatRoom/MsgBubble/index.wxss

@@ -23,10 +23,12 @@
     padding: 20rpx 26rpx 20rpx 30rpx;
     background-color: #F6F7F8;
     border-radius: 10rpx;
+    word-break:break-all;
 }
 
 .msg-time {
     position: absolute;
+    width: 240rpx;
     height: 34rpx;
     font-size: 24rpx;
     color: rgba(0, 0, 0, 0.39);
@@ -35,6 +37,11 @@
     right: 20rpx;
 }
 
+.opposite-side .msg-time {
+    left: 20rpx;
+    right: 0;
+}
+
 /* 自己 */
 .my-msg {
     display: flex;
@@ -61,4 +68,5 @@
     padding: 20rpx 26rpx 20rpx 30rpx;
     background-color: #F6F7F8;
     border-radius: 10rpx;
+    word-break: break-all;
 }

+ 336 - 4
pages/chatRoom/dialogbox.js

@@ -1,23 +1,326 @@
-// pages/chatRoom/dialogbox.js
+const app = getApp();
+import {
+    ApiModel
+} from "../../utils/api";
+const _Http = new ApiModel();
 Page({
 
     /**
      * 页面的初始数据
      */
     data: {
-        iosX: false
+        iosX: false,
+        sendText: "", //输入框内容
+        headerTitle: "对话框",
+        socketMsgQueue: [],
+        lineCount: 1, //输入框行数
+        toView: 'item0',
+        keyboardHeight: 0, //键盘高度
+        functionToChoose: "", //功能选项
+        memePopup: false, //表情弹出
+        pageNumber: 1,
+        pageTotal: 1,
+        triggered: false, //下拉状态
+        unreadCount: 0, //对方发送未读信息
     },
 
     /**
      * 生命周期函数--监听页面加载
      */
     onLoad: function (options) {
+        app.initSocket(); //链接websocket 用于测试
+        const that = this;
+        this.setData({
+            timdialogid: options.id,
+            userid: wx.getStorageSync('userData').userid
+        });
+        //详情
+        _Http.basic({
+            "accesstoken": wx.getStorageSync('userData').token,
+            "classname": "system.im.imdialog.imdialog",
+            "method": "query_imdialogMain",
+            "content": {
+                "timdialogid": options.id
+            }
+        }).then(res => {
+            console.log("详情", res)
+            let title = res.data[0].fimdialogname.split('-');
+            this.setData({
+                headerTitle: title[0]
+            })
+        })
+        //群历史信息
+        this.query_imdialogMessage();
         let iosX = (getApp().globalData.safeAreaBottom == 0) ? false : true;
         this.setData({
             iosX
         })
+        //获取表情包
+        this.getMeme()
     },
+    //历史信息查询
+    query_imdialogMessage() {
+        _Http.basic({
+            "accesstoken": wx.getStorageSync('userData').token,
+            "classname": "system.im.imdialog.imdialog",
+            "method": "query_imdialogMessage",
+            "content": {
+                "pageNumber": this.data.pageNumber,
+                "pageSize": 20,
+                "timdialogid": this.data.timdialogid
+            }
+        }, false).then(res => {
+            if (res.msg != '成功') return wx.showToast({
+                title: res.data,
+                icon: "none"
+            })
+            console.log(res)
+            if (res.pageNumber != 1) {
+                let list = res.data;
+                list = list.concat(this.data.socketMsgQueue);
+                this.setData({
+                    socketMsgQueue: list,
+                    toView: `item${res.data.length - 1}`,
+                    triggered: false
+                })
+            } else {
+                this.setData({
+                    socketMsgQueue: res.data,
+                    toView: `item${res.data.length - 1}`,
+                    pageTotal: res.pageTotal
+                })
+            }
 
+        })
+    },
+    scrolltoupper() {
+        if (this.data.pageNumber < this.data.pageTotal) {
+            this.setData({
+                pageNumber: this.data.pageNumber + 1,
+                triggered: true
+            })
+            this.query_imdialogMessage();
+        }
+    },
+    //键盘弹出高度
+    keyboardheightchange(e) {
+        let {
+            height
+        } = e.detail;
+        if (this.data.iosX && height > 150) height = height - 17;
+        this.setData({
+            keyboardHeight: height
+        })
+    },
+    /* 输入框数据绑定 */
+    sendInput(e) {
+        this.setData({
+            sendText: e.detail.value
+        })
+    },
+    /* 发送信息 */
+    sendMsg(type, data) {
+        const content = this.data.sendText.trim(),
+            that = this;
+        if (type === 'file') {
+            console.log("发送", data)
+            app.globalData.SocketTask.send({
+                data: JSON.stringify({
+                    "classname": "message.message",
+                    "method": "sendFileMessage",
+                    "content": {
+                        "timdialogid": this.data.timdialogid,
+                        "tattachmentid": data[0].tattachmentid
+                    }
+                }),
+                success(res) {}
+            })
+        } else {
+            if (content == '') return;
+            app.globalData.SocketTask.send({
+                data: JSON.stringify({
+                    "classname": "message.message",
+                    "method": "sendTextMessage",
+                    "content": {
+                        "timdialogid": that.data.timdialogid,
+                        "fmessage": content
+                    }
+                }),
+                success(res) {
+                    that.setData({
+                        sendText: ''
+                    })
+                }
+            })
+        }
+    },
+    sendMeme(e) {
+        const {
+            item
+        } = e.currentTarget.dataset;
+        let data = [];
+        data.push(item);
+        this.sendMsg('file', data)
+    },
+    //功能选择
+    selectionFunction(e) {
+        const {
+            name
+        } = e.target.dataset,
+            that = this;
+        if (name == undefined || name == "") return;
+        console.log(name)
+        if (name == '表情') {
+            let keyboardHeight = (this.data.iosX == true) ? 220 : 200;
+            this.setData({
+                keyboardHeight,
+                memePopup: true
+            })
+            that.toBotton()
+            let time1 = setInterval(() => {
+                this.setData({
+                    keyboardHeight
+                })
+                if (this.data.keyboardHeight == keyboardHeight && this.data.memePopup) clearInterval(time1);
+            }, 100);
+        } else if (name == '图片') {
+            this.endMemePopup()
+            wx.chooseMedia({
+                count: 1,
+                mediaType: ['image'],
+                sourceType: ['album', 'camera'],
+                maxDuration: 30,
+                camera: 'back',
+                success(res) {
+                    let data = {
+                        file: res.tempFiles[0].tempFilePath
+                    };
+                    that.afterRead(data)
+                }
+            })
+        }
+    },
+    textareaFocus() {
+        this.setData({
+            memePopup: false, //表情弹出
+        })
+        this.toBotton()
+    },
+    //关闭表情
+    endMemePopup(e) {
+        this.setData({
+            keyboardHeight: 0, //键盘高度
+            memePopup: false, //表情弹出
+        })
+    },
+    /* 文本域行数变化 */
+    linechange(e) {
+        const {
+            lineCount
+        } = e.detail;
+        this.setData({
+            lineCount
+        })
+    },
+    //获取表情包
+    getMeme() {
+        _Http.basic({
+            "accesstoken": wx.getStorageSync('userData').token,
+            "classname": "system.system.docManage",
+            "method": "queryDoc",
+            "content": {
+                "getdatafromdbanyway": true,
+                "ownertable": "system",
+                "ownerid": 0
+            }
+        }, false).then(res => {
+            if (res.msg != '成功') return setTimeout(() => {
+                this.getMeme();
+            }, 3000);
+            this.setData({
+                memeList: res.data
+            })
+        })
+    },
+    afterRead({
+        file
+    }) {
+        var that = this
+        var index = file.lastIndexOf(".");
+        var ext = file.substr(index + 1);
+        var timestamp = Date.parse(new Date());
+        wx.getFileSystemManager().readFile({
+            filePath: file,
+            // encoding:'utf-8',
+            success: result => {
+                //返回临时文件路径
+                const fileData = result.data
+                wx.request({
+                    url: 'https://www.buwanjia.com/bwj/rest/webclientrest/', //仅为示例,并非真实的接口地址
+                    data: {
+                        "accesstoken": wx.getStorageSync('userData').token,
+                        "classname": "system.system.docManage",
+                        "method": "getFileName",
+                        "content": {
+                            "filename": 'wx' + timestamp,
+                            "filetype": ext,
+                            "ownertable": "timdialog",
+                            "ownerid": that.data.timdialogid,
+                            "ftype": "default",
+                            "HttpMethod": 'put'
+                        }
+                    },
+                    method: 'post',
+                    header: {
+                        'content-type': 'application/json' // 默认值
+                    },
+                    success(res) {
+                        console.log(res)
+                        that.uploadFile(res, fileData)
+                    }
+                })
+            },
+            fail: console.error
+        })
+    },
+    uploadFile(res, data) {
+        var that = this
+        wx.request({
+            url: res.data.data.obsuploadurl,
+            method: "PUT",
+            data: data,
+            header: {
+                'content-type': 'application/octet-stream' // 默认值
+            },
+            success() {
+                wx.request({
+                    url: 'https://www.buwanjia.com/bwj/rest/webclientrest/', //仅为示例,并非真实的接口地址
+                    data: {
+                        "accesstoken": wx.getStorageSync('userData').token,
+                        "classname": "system.system.docManage",
+                        "method": "uploadSuccess",
+                        "content": {
+                            "obsfilename": res.data.data.obsfilename
+                        }
+                    },
+                    method: 'post',
+                    header: {
+                        'content-type': 'application/json' // 默认值
+                    },
+                    success(res) {
+                        let file = res.data.data;
+                        console.log(res)
+                        that.sendMsg('file', file)
+                    }
+                })
+            }
+        })
+    },
+    toBotton() {
+        this.setData({
+            toView: 'bottom'
+        })
+    },
     /**
      * 生命周期函数--监听页面初次渲染完成
      */
@@ -29,7 +332,26 @@ Page({
      * 生命周期函数--监听页面显示
      */
     onShow: function () {
-
+        var that = this
+        app.globalData.callback = function (res) {
+            //res  接收websocket onMessage事件返回的数据
+            let objs = JSON.parse(res.data),
+                unreadCount = that.data.unreadCount; /* triggered */
+            that.data.socketMsgQueue.push(objs)
+            console.log("发送消息", objs)
+            that.setData({
+                socketMsgQueue: that.data.socketMsgQueue
+            })
+            that.toBotton()
+            /* if (wx.getStorageSync('userData').userid == objs.message.sendfrom.userid) {
+            } else {
+                that.setData({
+                    socketMsgQueue: that.data.socketMsgQueue
+                })
+            } */
+            /* ,
+                toView: `item${that.data.socketMsgQueue.length - 1}` */
+        }
     },
 
     /**
@@ -43,7 +365,17 @@ Page({
      * 生命周期函数--监听页面卸载
      */
     onUnload: function () {
-
+        //重置未读信息
+        _Http.basic({
+            "accesstoken": wx.getStorageSync('userData').token,
+            "classname": "system.im.imdialog.imdialog",
+            "method": "restUnReadMsgCount",
+            "content": {
+                "timdialogid": this.data.timdialogid
+            }
+        }).then(res => {
+            console.log(res)
+        })
     },
 
     /**

+ 28 - 11
pages/chatRoom/dialogbox.wxml

@@ -1,22 +1,39 @@
 <!-- 头部 -->
 <view class="header">
-    <view class="header_title">王梅</view>
+    <view class="header_title">{{headerTitle}}</view>
     <view class="header_botton">
         <van-button custom-class='head-bot-class head-bot-l'>暂不合作</van-button>
         <van-button custom-class='head-bot-class head-bot-r'>确认合作</van-button>
     </view>
 </view>
-<MsgBubble role='my' userImg='/static/icon-02.png' content='这是消息内容' time='8.30' />
-<MsgBubble role='you' userImg='/static/icon-05.png' content='好多文字好多文字好多文字好多文字好多文字好多文字好多文字好多文字好多文字好多文字' time='8.30' />
+<!-- 聊天   bindscrolltoupper='scrolltoupper' -->
+<scroll-view class="chatFrame" refresher-default-style='none' refresher-enabled bindrefresherrefresh='scrolltoupper' refresher-triggered='{{triggered}}' scroll-y scroll-into-view="{{toView}}">
+    <view style="height: 110rpx;"></view>
+    <MsgBubble wx:for="{{socketMsgQueue}}" id="item{{index}}" type='{{item.message.ftype}}' fobsurl='{{item.message.data[0].fobsurl}}' role="{{userid==item.message.sendfrom.userid?'my':'you'}}" userImg='{{item.message.sendfrom.headpic}}' content='{{item.message.data.fcontent}}' time='{{item.message.fdatetime}}' />
+    <view style="height: {{keyboardHeight}}px;"></view>
+    <view id="bottom" style="height: {{iosX?'102':'85'}}px;"></view>
+</scroll-view>
 <!-- 底部输入 -->
-<view class="input-box">
-    <input class="input-text" type="text" />
-    <view class="functionalZone">
-        <image mode="heightFix" src="/static/chatRoom/icon-01.png" />
-        <image mode="heightFix" src="/static/chatRoom/icon-02.png" />
-        <image mode="heightFix" src="/static/chatRoom/icon-03.png" />
+<view class="input-box" style="bottom:{{keyboardHeight}}px;">
+    <textarea class="input-text {{lineCount==1?'':'multi-row'}}" bindfocus="textareaFocus" adjust-position='{{false}}' bindconfirm='sendMsg' bindblur="sendMsg" show-confirm-bar='{{false}}' confirm-type='send' confirm-hold='true' cursor-spacing='45' bindinput='sendInput' value='{{sendText}}' maxlength='-1' fixed='true' type="text" bindlinechange='linechange' bindkeyboardheightchange='keyboardheightchange'></textarea>
+    <view class="functionalZone" catchtap="selectionFunction">
+        <image data-name='表情' mode="heightFix" src="/static/chatRoom/icon-01.png" />
+        <image data-name='图片' mode="heightFix" src="/static/chatRoom/icon-02.png" />
+        <image data-name='历史' mode="heightFix" src="/static/chatRoom/icon-03.png" />
     </view>
+    <!-- 安全距离 -->
     <view style="height: {{iosX?'34':'0'}}rpx;"></view>
 </view>
-<!-- 底部占位 -->
-<view style="height: {{iosX?'102':'85'}}rpx;"></view>
+<!-- 表情-->
+<van-popup show="{{ memePopup }}" overlay='{{false}}' position='bottom' safe-area-inset-bottom='{{false}}'>
+    <view class="popup-class">
+        <scroll-view scroll-y class="meme-box">
+            <view class="meme-item" wx:for="{{memeList}}" data-item="{{item}}" catchtap="sendMeme">
+                <image src="{{item.fobsurl}}" mode="aspectFill"></image>
+            </view>
+        </scroll-view>
+        <view style="height: {{iosX?'34':'0'}}rpx;"></view>
+    </view>
+</van-popup>
+
+<view wx:if="{{ memePopup }}" bindtap="endMemePopup" class="mask-layer"></view>

+ 52 - 7
pages/chatRoom/dialogbox.wxss

@@ -1,6 +1,6 @@
 page {
     background-color: #ffffff;
-    padding-top: 112rpx;
+    padding: 0;
 }
 
 .header {
@@ -13,7 +13,7 @@ page {
     width: 100vw;
     height: 92rpx;
     background-color: #FCFCFD;
-    z-index: 9999999;
+    z-index: 99;
 }
 
 .header_title {
@@ -50,7 +50,11 @@ page {
     border: 0 !important;
 }
 
-
+/* 聊天可视区 */
+.chatFrame {
+    width: 100vw;
+    max-height: 100vh;
+}
 
 /* 粘底输入框 */
 .input-box {
@@ -59,16 +63,17 @@ page {
     background-color: #F6F7F8;
     left: 0;
     bottom: 0;
-    z-index: 999999999999;
+    z-index: 99;
 }
 
 .input-text {
     width: 710rpx;
     height: 64rpx;
+    line-height: 64rpx;
     background-color: #ffffff;
     border-radius: 32rpx;
-    margin: 20rpx auto 74rpx;
-    padding: 0 25rpx;
+    margin: 20rpx auto !important;
+    padding: 0 25rpx 0;
     box-sizing: border-box;
 }
 
@@ -78,10 +83,50 @@ page {
     justify-content: space-around;
     height: 40rpx;
     width: 80vw;
-    margin: -54rpx auto 0;
+    margin: 0 auto;
     padding-bottom: 26rpx;
 }
 
 .functionalZone image {
     height: 100%;
+}
+
+.multi-row {
+    line-height: 44rpx;
+}
+
+.meme-box {
+    width: 90vw;
+    height: 385rpx;
+    margin: 0 auto;
+    padding-bottom: 15rpx;
+}
+
+.meme-item {
+    float: left;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 12.5%;
+    height: 80rpx;
+}
+
+.meme-item image {
+    width: 50rpx;
+    height: 50rpx;
+}
+
+.popup-class {
+    width: 100vw;
+    background-color: #F6F7F8;
+}
+
+/* 遮罩层 */
+.mask-layer {
+    position: fixed;
+    width: 100vw;
+    height: 100vh;
+    top: 0;
+    left: 0;
+    z-index: 9;
 }

+ 39 - 2
pages/chatRoom/index.js

@@ -1,4 +1,7 @@
-// pages/chatRoom/index.js
+import {
+    ApiModel
+} from "../../utils/api";
+const _Http = new ApiModel();
 Page({
 
     /**
@@ -7,17 +10,51 @@ Page({
     data: {
         iosX: false, //判断是否具有安全距离
         optionItem: 0, //底部选中
+        reltionList: [], //沟通列表
     },
 
     /**
      * 生命周期函数--监听页面加载
      */
     onLoad: function (options) {
+        //是否为带有底部安全距离机型
         let iosX = (getApp().globalData.safeAreaBottom == 0) ? false : true;
         this.setData({
             iosX
         })
     },
+    /* 进入对话 */
+    enterTheDialogue(e) {
+        const {
+            item
+        } = e.currentTarget.dataset;
+        wx.navigateTo({
+          url: "./dialogbox?id=" + item.timdialogid
+        })
+    },
+    /* 获取聊天列表 */
+    queryImdialogList(condition = "") {
+        _Http.basic({
+            "accesstoken": wx.getStorageSync('userData').token,
+            "classname": "system.im.imdialog.imdialog",
+            "method": "query_imdialogList",
+            "content": {
+                "getdatafromdbanyway": true,
+                "where": {
+                    "condition": condition
+                }
+            }
+        }).then(res => {
+            console.log("获取聊天记录", res)
+            if (res.msg != '成功') return wx.showToast({
+                title: res.data,
+                icon: "none"
+            });
+            this.setData({
+                relationList: res.data
+            })
+        })
+    },
     /* 底部选中 */
     footerOption(e) {
         const {
@@ -39,7 +76,7 @@ Page({
      * 生命周期函数--监听页面显示
      */
     onShow: function () {
-
+        this.queryImdialogList()
     },
 
     /**

+ 8 - 7
pages/chatRoom/index.wxml

@@ -13,25 +13,26 @@
 <!-- 个人聊天 -->
 <view style="margin-top: 30rpx;">
     <view class="msg-box">
-        <navigator url="#" wx:for="{{15}}">
+        <navigator url="#" wx:for="{{relationList}}" data-item="{{item}}" bindtap="enterTheDialogue">
             <view class="msgImg">
-                <image src="/static/tacitly-approve/MRproduct.png"></image>
+                <image wx:if="{{item.latestnews[0].message.sendfrom.headpic}}" src="{{item.latestnews[0].message.sendfrom.headpic}}"></image>
+                <image wx:else src="/static/tacitly-approve/MRproduct.png"></image>
             </view>
             <view class="borTop">
                 <view class="msgText">
-                    <view class="title u-line-1">王梅</view>
-                    <view class="msg u-line-1">你好你好你好你好你好你好</view>
+                    <view class="title u-line-1">{{item.latestnews[0].fname}}</view>
+                    <view class="msg u-line-1">{{item.latestnews[0].message.ftype=='file'?'[图片]':item.latestnews[0].message.data.fcontent}}</view>
                 </view>
                 <view class="msgCount">
-                    <view class="time u-line-1">上午 9:34</view>
+                    <view class="time u-line-1">{{item.fjoindate}}</view>
                     <view class="count u-line-1">
-                        <view>32</view>
+                        <view wx:if="{{item.funreadmsgcount>0}}">{{item.funreadmsgcount}}</view>
                     </view>
                 </view>
             </view>
         </navigator>
     </view>
-    <!-- <My_pageReachBottom dummyStatus="{{msgList.length>0}}" loadMore='{{pageNumber>=pageTotal}}'></My_pageReachBottom> -->
+    <My_pageReachBottom dummyStatus="{{relationList.length>0}}" loadMore='{{5>=0}}'></My_pageReachBottom>
 </view>
 <!-- 底部 -->
 <view class="footer">

+ 6 - 0
pages/login/index.js

@@ -99,6 +99,12 @@ Page({
         };
         /* 储存 */
         wx.setStorageSync('userData', data);
+        if (getApp().globalData.socketEstablish) getApp().globalData.SocketTask.close(function (res) {
+            console.log('WebSocket连接已关闭!readyState=' + that.globalData.SocketTask.readyState)
+            that.globalData.socketEstablish = false;
+        });
+        //建立链接
+        getApp().initSocket();
     },
     /* 登录页面提交数据 */
     loginSubmit() {

+ 7 - 0
pages/tabbar-pages/home/index.js

@@ -23,6 +23,9 @@ Page({
         }, {
             text: '通告',
             icon: 'https://bwj.obs.cn-east-2.myhuaweicloud.com/resources/WeChat/home-grid/icon-01.png'
+        }, {
+            text: '即时沟通',
+            icon: 'https://bwj.obs.cn-east-2.myhuaweicloud.com/resources/WeChat/home-grid/icon-01.png'
         }],
         /* 圆角按钮tabs列表 */
         roundedList: ["兴趣爱好", "关注板块", "最新发布"],
@@ -52,6 +55,10 @@ Page({
             wx.navigateTo({
                 url: '/pages/annunciate/index',
             })
+        } else if (name == '即时沟通') {
+            wx.navigateTo({
+                url: '/pages/chatRoom/index',
+            })
         } else {
             wx.showToast({
                 title: '功能开发中',

+ 1 - 1
pages/tabbar-pages/home/index.wxml

@@ -4,7 +4,7 @@
 <My_BannerSwiper swiperBannerList="{{swiperBannerList}}"></My_BannerSwiper>
 <!-- 宫格区域 -->
 <view class="grid_box">
-    <van-grid border="{{false}}" column-num="3" icon-size='40' bindtap="gridJumpPage">
+    <van-grid border="{{false}}" column-num="4" icon-size='40' bindtap="gridJumpPage">
         <van-grid-item wx:for="{{gridList}}" data-name="{{item.text}}" icon="{{item.icon}}" text="{{item.text}}" text-class="grid-text-class" />
     </van-grid>
 </view>

+ 1 - 1
project.config.json

@@ -4,7 +4,7 @@
         "ignore": []
     },
     "setting": {
-        "urlCheck": true,
+        "urlCheck": false,
         "es6": true,
         "enhance": true,
         "postcss": true,

+ 4 - 4
project.private.config.json

@@ -195,15 +195,15 @@
                     "scene": null
                 },
                 {
-                    "name": "",
-                    "pathName": "pages/chatRoom/index",
+                    "name": "对话框",
+                    "pathName": "pages/chatRoom/dialogbox",
                     "query": "",
                     "launchMode": "default",
                     "scene": null
                 },
                 {
-                    "name": "对话框",
-                    "pathName": "pages/chatRoom/dialogbox",
+                    "name": "即时沟通",
+                    "pathName": "pages/chatRoom/index",
                     "query": "",
                     "scene": null,
                     "launchMode": "default"

+ 195 - 0
utils/socket.js

@@ -0,0 +1,195 @@
+export default class Websocket {
+  constructor({
+      heartCheck,
+      isReconnection
+  }) {
+      // 是否连接
+      this._isLogin = false;
+      // 当前网络状态
+      this._netWork = true;
+      // 是否人为退出
+      this._isClosed = false;
+      // 心跳检测频率
+      this._timeout = 3000;
+      this._timeoutObj = null;
+      // 当前重连次数
+      this._connectNum = 0;
+      // 心跳检测和断线重连开关,true为启用,false为关闭
+      this._heartCheck = heartCheck;
+      this._isReconnection = isReconnection;
+      this._onSocketOpened();
+      this.wsUrl = ""
+  }
+  // 心跳重置
+  _reset() {
+      clearTimeout(this._timeoutObj);
+      return this;
+  }
+  // 心跳开始
+  _start() {
+      let _this = this;
+      this._timeoutObj = setInterval(() => {
+          wx.sendSocketMessage({
+              // 心跳发送的信息应由前后端商量后决定
+              data: JSON.stringify({
+                  "key": 'value'
+              }),
+              success(res) {
+                  // console.log(res)
+                  // console.log("发送心跳成功");
+              },
+              fail(err) {
+                  console.log(err)
+                  _this._reset()
+              }
+          });
+      }, this._timeout);
+  }
+  // 监听websocket连接关闭
+  onSocketClosed(options) {
+      wx.onSocketClose(err => {
+          console.log('当前websocket连接已关闭,错误信息为:' + JSON.stringify(err));
+          // 停止心跳连接
+          if (this._heartCheck) {
+              this._reset();
+          }
+          // 关闭已登录开关
+          this._isLogin = false;
+          // 检测是否是用户自己退出小程序
+          if (!this._isClosed) {
+              // 进行重连
+              if (this._isReconnection) {
+                  this._reConnect(options)
+              }
+          }
+
+      })
+  }
+  // 检测网络变化
+  onNetworkChange(options) {
+      wx.onNetworkStatusChange(res => {
+          console.log('当前网络状态:' + res.isConnected);
+          if (!this._netWork) {
+              this._isLogin = false;
+              // 进行重连
+              if (this._isReconnection) {
+                  this._reConnect(options)
+              }
+          }
+      })
+  }
+  _onSocketOpened(callBack) {
+      wx.onSocketOpen(res => {
+          console.log('websocket已打开');
+          // 打开已登录开关
+          this._isLogin = true;
+          // 发送心跳
+          if (this._heartCheck) {
+              this._reset()._start();
+          }
+          // 发送登录信息
+          wx.sendSocketMessage({
+              // 这里是第一次建立连接所发送的信息,应由前后端商量后决定
+              data: JSON.stringify({
+                  "key": 'value'
+              })
+          })
+          // 打开网络开关
+          this._netWork = true;
+          if (typeof callBack == "function") {
+              callBack(res)
+          } else {
+              console.log('参数的类型必须为函数')
+          }
+      })
+  }
+  // 接收服务器返回的消息
+  onReceivedMsg(callBack) {
+      wx.onSocketMessage(msg => {
+          if (typeof callBack == "function") {
+              callBack(msg)
+          } else {
+              console.log('参数的类型必须为函数')
+          }
+      })
+  }
+  // 建立websocket连接
+  initWebSocket(options) {
+      let _this = this;
+      this.wsUrl = options.url ? options.url : this.wsUrl
+      if (this._isLogin) {
+          console.log("您已经登录了");
+      } else {
+          // 检查网络
+          wx.getNetworkType({
+              success(result) {
+                  if (result.networkType != 'none') {
+                      // 开始建立连接
+                      wx.connectSocket({
+                          url: _this.wsUrl,
+                          success(res) {
+                              if (typeof options.success == "function") {
+                                  options.success(res)
+                              } else {
+                                  console.log('参数的类型必须为函数')
+                              }
+                          },
+                          fail(err) {
+                              if (typeof options.fail == "function") {
+                                  options.fail(err)
+                              } else {
+                                  console.log('参数的类型必须为函数')
+                              }
+                          }
+                      })
+                  } else {
+                      console.log('网络已断开');
+                      _this._netWork = false;
+                  }
+              }
+          })
+      }
+  }
+  // 发送websocket消息
+  sendWebSocketMsg(options) {
+      // console.log("send参数:", options)
+      wx.sendSocketMessage({
+          data: options.data,
+          success(res) {
+              if (options.success && typeof options.success == "function") {
+                  options.success(res)
+              }
+          },
+          fail(err) {
+              if (options.fail && typeof options.fail == "function") {
+                  options.fail(err)
+              }
+          }
+      })
+  }
+  // 重连方法,会根据时间频率越来越慢
+  _reConnect(options) {
+      let timer, _this = this;
+      if (this._connectNum < 3) {
+          timer = setTimeout(() => {
+              this.initWebSocket(options)
+          }, 3000)
+          this._connectNum += 1;
+      } else if (this._connectNum < 10) {
+          timer = setTimeout(() => {
+              this.initWebSocket(options)
+          }, 10000)
+          this._connectNum += 1;
+      } else {
+          timer = setTimeout(() => {
+              this.initWebSocket(options)
+          }, 450000)
+          this._connectNum += 1;
+      }
+  }
+  // 关闭websocket连接
+  closeWebSocket() {
+      wx.closeSocket();
+      this._isClosed = true;
+  }
+}