0


uniapp使用腾讯im 无ui集成方案写法

页面显示
在这里插入图片描述
在这里插入图片描述

1.无ui集成方案

1.1 首先下来依赖
//初始化
npm init
// IM Web SDK
// 从v2.11.2起,SDK 支持了 WebSocket,推荐接入;v2.10.2及以下版本,使用 HTTP
npm install tim-js-sdk --save
// 发送图片、文件等消息需要腾讯云即时通信 IM 上传插件
npm install tim-upload-plugin --save
// 拦截或替换敏感词需要本地审核插件
npm install tim-profanity-filter-plugin --save
1.2 创建tim.js
import TIM from 'tim-js-sdk/tim-js-friendship.js'
import TIMUploadPlugin from 'tim-upload-plugin';
import TIMProfanityFilterPlugin from 'tim-profanity-filter-plugin';

// import COS from "cos-js-sdk-v5";


​ const options = {
​ SDKAppID: 1600024346
​ // 接入时需要将0替换为您的即时通信应用的 SDKAppID
​ };
​ // 创建 SDK 实例,TIM.create() 方法对于同一个 SDKAppID 只会返回同一份实例
​ const tim = TIM.create(options); // SDK 实例通常用 tim 表示
​ // tim.setLogLevel(0);
​ const TIMData = TIM
​ // 注册腾讯云即时通信 IM 上传插件
​ tim.registerPlugin({
​ ‘tim-upload-plugin’: TIMUploadPlugin
​ });

// 注册腾讯云即时通信 IM 本地审核插件
tim.registerPlugin({
    'tim-profanity-filter-plugin': TIMProfanityFilterPlugin
});

// 注册 COS SDK 插件
// tim.registerPlugin({'cos-js-sdk': COS});



​ /* eslint-disable require-jsdoc */
​ function genTestUserSig(userID) {
​ const SDKAPPID = 1600024346;
​ const EXPIRETIME = 604800;
​ const SECRETKEY = ‘a03e633a7f9e49784a8f1b1d87ebc4d930be70544e13822bdd8f9a0af40acc1’;

const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME);
const userSig = generator.genTestUserSig(userID);

    return {
        sdkAppId: SDKAPPID,
        userSig: userSig
    };
}

export default {
    tim,
    TIMData,
    genTestUserSig
}
1.3 在main.js导入
import tim from './utils/tim.js'
import TIM from 'tim-js-sdk/tim-js-friendship.js'

Vue.prototype.tim = tim.tim //tim sdk 引入后生成的tim服务
Vue.prototype.$TIM = TIM //tim 的状态/事件 常量
2.1 在登录接口存储用户信息
//用户信息
        user() {
            this.$helper.apiPost(this.$api.tab.user).then(ret => {
                if (ret.data.code == 200) {
                    this.info = ret.data.data
                    //根据返回的userID 以及 userSig 登录tim
                    uni.setStorageSync('uid', ret.data.data.username)
                    //这里我叫后端返回了一个userSing
                    uni.setStorageSync('uid_sig', ret.data.data.user_sig)
                    console.log(this.info, '122332211');
                    this.tim.login({
                        userID: this.info.username,
                        userSig: this.info.user_sig
                    }).then((imResponse) => {
                        this.$helper.showToast('登录成功')
                        setTimeout(() => {
                            uni.switchTab({
                                url: '/pages/tab/home'
                            })
                        }, 500)
                    })
                }
            })
        },
2.2 进入首页
 data() {
        return {
            userID: uni.getStorageSync('uid'),
            userSig: uni.getStorageSync('uid_sig'),
        };
    },
 onLoad() {
        this.cosImLogin()
    },
 methods: {
     cosImLogin() {
        console.log(this.userID, 'this.userID');
        console.log(this.userSig, 'this.userSig');
        if (!this.userID.length || !this.userSig.length) return
            this.tim.login({
                userID: this.userID,
                userSig: this.userSig
            }).then((res) => {
                this.loginTUICallKit()
            }).catch((err) => {
                console.log("报错", err)
            })
        },
     loginTUICallKit() {
            const options = {
                SDKAppID: 1600024346, // 请替换为步骤一取到的 SDKAppID
                userID: this.userID, // 请替换为您的 UserID
                userSig: this.userSig, // 您可以在控制台中计算一个 UserSig 并填在这个位置
            };
            this.$TUICallKit.login(options, (res) => {
                if (res.code === 0) {
                    console.log('login success');
                    this.$TUICallKit.enableFloatWindow(true); // 开启小浮窗
                } else {
                    console.log(`login failed, error message = ${res.msg}`);
                  }
                });
            },
        }
2.3 我的好友列表
export default {
    data() {
        return {
            friends: []
        };
    },

    onLoad() {
        this.friendList();
    },
    methods: {
        openConversation(name, userID) {
        // userID:电话号码  username:昵称 
        //跳转到聊天页面(聊天页面自定义头部所以要携带昵称)
        this.$helper.toPage('/pages/active/chat?name=' + name + '&userID=' + userID);
     },
        //我的好友
        async friendList() {
            let res = await this.$helper.apiPost(this.$api.user.friend_list);
            this.friends = res.data.data;
            console.log(this.friends);
        }
    }
};
3.1 聊天页面

3.1.1 对话内容

3.1.1 对话内容
<view class="msg-content-list">
   <mescroll-uni ref="mescrollRef" :fixed="false" :down="downOption" @init="mescrollInit" @down="downCallback"    @up="upCallback">
     <view>
        <view class="msg-content-item" v-for="(item, index) in msgList">
          <view class="time-slot" v-if="item.isShowTime || index == 0">
            {{getShowTimePipe(item.time) || ''}}
          </view>
  <!-- 个人开始 -->
          <view>
        <view class="content-from msg" v-if="item.flow == 'in'">
        <image class="msg-image left-head" :src="item.avatar" />
  <!-- 每条消息内容 -- left -->
        <view class="content-my-left-box">
  <!-- 展示文本 -->
        <view class="content-my-left-text" v-if="item.type == 'TIMTextElem'">
           <rich-text :nodes="nodesFliter(item.payload.text)"></rich-text>
        </view>
  <!-- 展示图片 -->
    <image class="content-my-left-img" :style="`height:${item.payload.imageInfoArray[1].height}px; width: ${item.payload.imageInfoArray[1].width}px;`" :src="item.payload.imageInfoArray[1].imageUrl" mode="widthFix" v-else-if="item.type == 'TIMImageElem'" @click="onPreviewImg(item.payload.imageInfoArray[1].imageUrl)"></image>
  <!-- 展示视频 -->
    <MyVideo class="content-my-video" v-else-if="item.type == 'TIMVideoFileElem'" :videoUrl="item.payload.remoteVideoUrl" />
    </view>
<!-- 每条消息内容 -- left -->
    </view>
    <view class="content-my msg" v-else-if="item.flow == 'out'">
<!-- 每条消息内容 -- right -->
    <view class="content-my-right-box">
<!-- 展示文本 -->
    <view class="content-my-right-text" v-if="item.type == 'TIMTextElem'">
        rich-text :nodes="nodesFliter(item.payload.text)"></rich-text>
    </view>
<!-- 展示图片 -->
<image class="content-my-right-img"    :style="`height: ${item.payload.imageInfoArray[1].height*2}rpx; width: ${item.payload.imageInfoArray[1].width*2}rpx;`":src="item.payload.imageInfoArray[1].imageUrl" mode="widthFix" v-else-if="item.type == 'TIMImageElem'" @click="onPreviewImg(item.payload.imageInfoArray[1].imageUrl)"></image>
<!-- 展示视频 -->
<MyVideo class="content-my-video" v-else-if="item.type == 'TIMVideoFileElem'" :videoUrl="item.payload.remoteVideoUrl" />
</view>
<!-- 每条消息内容 -- right -->
          <image class="msg-image right-head" :src="item.avatar " />
        </view>
      </view>
<!-- 个人结束 -->
                    </view>
                </view>
            </mescroll-uni>
        </view>
3.2 底部输入框
3.2 底部输入框

<view class="bottom fixed" @click="getBottomHeight()" :style="{bottom: changeBottomVal}">
    <view class="flex-center-between">
        <image @click="imgBtn" src="/static/images/home/1086.png" mode=""></image>
        // @keyboardheightchange 监听键盘高度
            <input :adjust-position="false" @keyboardheightchange="keyboardheightchange" class="save-inp" v-model="msgText" :focus="focus" type="text" @confirm="sendBtn">
        <view class="send" @click="sendBtn">发送</view>
     </view>
    </view>

3.1.2 js代码

3.1.2 js代码

    data() {
            return {
                top: uni.getStorageSync('safeArea').top,
                name: '',
                bottomImg: false,
                username: '',
                changeBottomVal: '',//键盘高度
                bottomHeight: '', //底部高度
                msgList: [], // 会话消息列表        
                msgText: '', // 文字消息
                message: {}, // 发送消息对象
                timUserInfo: {}, // 会话对象用户信息
                msgUserData: {}, // 会话对象信息
                focus: false,
                downOption: {
                    auto: false,
                    textInOffset: '拉取历史记录',
                    textOutOffset: '',
                    textLoading: '拉取中...'
                },
            };
        },
        onShow() {
            this.getTimeSlot()
            // 获取会话数据
            this.getListMsg()

        },
        onLoad(e) {

            this.tim.on(this.$TIM.EVENT.MESSAGE_RECEIVED, (event) => {

                if (event.data[0].type == "TIMSoundElem") {
                    this.getListMsg()
                    this.getTimeSlot()
                } else {
                    let arr = event.data.filter((res) => res.conversationID == (this.isGroup ? `GROUP${this.msgData.groupID}` :
                        `C2C${this.msgUserData.userID}`))
                    this.msgList.push(...arr)
                    this.getTimeSlot()
                    // 获取底部高度
                    this.getBottomHeight(false)
                }
            })

            this.name = e.name;
            this.username = e.username;
            this.msgUserData = e

            // 已读会话
            this.inRead()
            // 获取底部高度
            this.getBottomHeight(false)
        },
        methods: {
        //键盘高度
            keyboardheightchange(e) {
                this.changeBottomVal = e.detail.height + 'px'
            },
            getBottomHeight() {
                this.$nextTick(() => {
                    const query = uni.createSelectorQuery().in(this);
                    query.select('.bottom').boundingClientRect(data => {
                        this.bottomHeight = data.height

                        console.log(data.height, 'data.height');
                    }).exec();
                    this.$nextTick(() => {
                        uni.pageScrollTo({
                            scrollTop: 9999,
                            duration: 100
                        })
                    })
                })
            },

            // 预览图片
            onPreviewImg(image) {
                uni.previewImage({
                    urls: [image],
                    fail: function(err) {}
                })
            },
            imgBtn() {
                this.bottomImg = !this.bottomImg
            },
            // 发送拍摄或者上传视频
            sendMsgVideo() {
                uni.chooseVideo({
                    success: (res) => {
                        this.message = this.tim.createVideoMessage({
                            to: this.msgUserData.userID,
                            conversationType: 'C2C',
                            payload: {
                                file: res
                            },
                            onProgress: (event) => {}
                        });
                        this.tim.sendMessage(this.message).then((res) => {
                            this.msgList.push(res.data.message)
                            // 获取底部高度
                            this.getBottomHeight(false)
                        })
                    }
                })
            },
            // 发送拍摄或者上传图片
            sendMsgImage() {
                uni.chooseImage({
                    count: 1,
                    mediaType: ['image'], // 图片
                    sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
                    success: (res) => {
                        this.message = this.tim.createImageMessage({
                            to: this.msgUserData.userID,
                            conversationType: 'C2C',
                            payload: {
                                file: res
                            },
                            onProgress: function(event) {}
                        });
                        this.tim.sendMessage(this.message).then((res) => {
                            this.msgList.push(res.data.message)
                            // 获取底部高度
                            this.getBottomHeight(false)
                        })
                    }
                });
            },
            // 判断是否有十分钟的时间间隔
            getTimeSlot() {
                setTimeout(() => {
                    this.msgList.forEach((res, index) => {
                        let i = this.msgList.length - (index + 2) <= 0 ? 0 : this.msgList.length - (index + 2)
                        let j = this.msgList.length - (index + 1) <= 0 ? 0 : this.msgList.length - (index + 1)
                        let time1 = this.$time.getNowDate(this.msgList[i].time * 1000)
                        let time2 = this.$time.getNowDate(this.msgList[j].time * 1000)
                        if (this.$time.GetDateDiff(time2, time1, 'minute') <= -5) {
                            this.$set(this.msgList[j], 'isShowTime', true)
                        }
                    })
                }, 300)
            },
            // 获取会话列表
            getListMsg(isDown = false) {
                // 用于拉取历史聊天数据
                let parmas = {
                    conversationID: `C2C${this.msgUserData.userID}`,
                    nextReqMessageID: this.nextReqMessageID
                }
                // 用于拉取目前聊天数据
                let data = {
                    conversationID: `C2C${this.msgUserData.userID}`,
                }
                this.tim.getMessageList(isDown ? parmas : data).then((res) => {

                    this.nextReqMessageID = res.data.nextReqMessageID
                    console.log(res, '11122111221');
                    if (!this.nextReqMessageID.length || this.nextReqMessageID == '-1') this.mescroll.lockDownScroll(true)
                    if (isDown) {
                        this.msgList = res.data.messageList.concat(this.msgList)
                        this.mescroll.endDownScroll()
                    } else {
                        this.msgList = res.data.messageList
                    }

                });
                this.timeOut = setTimeout(() => {
                    uni.hideLoading()
                    if (!isDown) {
                        uni.pageScrollTo({
                            scrollTop: 9999,
                            duration: 100
                        })
                    }
                    this.$forceUpdate()
                }, 800)
            },
            inRead() {
                // 将某会话下所有未读消息已读上报
                this.tim.setMessageRead({
                    conversationID: `C2C${this.msgUserData.userID}`
                })
            },
            //聊天的节点加上外层的div
            nodesFliter(str) {
                let nodeStr = '<div style="display: flex; align-items: center;word-wrap:break-word; width: auto;">' + str +
                    '</div>'
                return nodeStr
            },
            getShowTimePipe(time) {
                return this.$time.showTimePipe(time * 1000)
            },
            // 发送文本
            sendMsgText() {
                this.msgText = this.msgText.trim()
                console.log(this.msgText, '111111');
                if (this.msgText.length == '') {
                    uni.showToast({
                        title: "发送消息不能为空",
                        icon: "none"
                    })
                    return
                }
                // 1. 创建消息实例,接口返回的实例可以上屏
                this.message = this.tim.createTextMessage({
                    to: this.msgUserData.userID,
                    conversationType: 'C2C',
                    payload: {
                        text: this.msgText
                    },
                });
                this.tim.sendMessage(this.message).then((res) => {
                    this.msgList.push(res.data.message)
                    this.focus = true
                    this.msgText = ""
                    // 获取底部高度
                    this.getBottomHeight(false)
                })
            },
            sendBtn() {
                this.sendMsgText()
            }
        }
4.1 消息列表
4.1.1 html
<view>
    <view v-for="(item, index) in list" :key="index" @click="goToMessage(item.userProfile.nick,item.userProfile.userID,index)">
                <view class="pop flex-center-between">
                    <view class="name flex">
                        <image :src="item.userProfile.avatar" mode=""></image>
                        <view class="tian">
                            <view>{{item.userProfile.nick}}</view>
                            <span>
                                <rich-text :nodes="nodesFliter(item.lastMessage.messageForShow)"></rich-text>
                            </span>
                        </view>
                    </view>
                    //未读消息
                <view class="red" v-if="item.unreadCount">{{item.unreadCount}}</view>
            </view>
        <view class="line"></view>
    </view>
</view>
4.2.2 js
export default {
        data() {
            return {
                top: uni.getStorageSync('safeArea').top,
                list: [],
                isTips: true
            };

        },
        onLoad() {
            this.getList()
        },
        onShow() {
            this.getList()
        },
        methods: {
            //聊天的节点加上外层的div
            nodesFliter(str) {
                let nodeStr = '<div style="align-items: center;word-wrap:break-word;">' + str + '</div>'
                return nodeStr
            },
            goToMessage(name, userID, index) {
                this.$helper.toPage('/pages/active/chat?name=' + name + '&userID=' + userID );
                // this.list[index].unreadCount = 0
            },
            getList() {
                // 获取全量的会话列表
                this.tim.getConversationList().then((res) => {

                    this.list = res.data.conversationList
                    // console.log(this.list, '1111');
                    console.log(this.list, '1111');
                    this.list = this.list.filter((res) => res.type != "@TIM#SYSTEM")

                    this.getFriend()
                })
            },
            getFriend() {
                this.tim.getFriendApplicationList().then(res => {
                    this.friendNum = res.data.unreadCount
                })
            },
        }
    };
标签: uni-app ui javascript

本文转载自: https://blog.csdn.net/weixin_73854956/article/details/136302828
版权归原作者 次贝。 所有, 如有侵权,请联系我们删除。

“uniapp使用腾讯im 无ui集成方案写法”的评论:

还没有评论