uniapp 对接腾讯云IM群公告功能

发布于:2025-06-08 ⋅ 阅读:(23) ⋅ 点赞:(0)

UniApp 实战:腾讯云IM群公告功能

一、前言

在即时通讯场景中,群公告是信息同步的重要渠道。本文将基于uniapp框架,结合腾讯云IM SDK,详细讲解如何实现群公告的发布、修改、历史记录查询等核心功能。

  • 群公告的数据结构设计
  • 权限校验的三种实现方式
  • 消息通知的实时推送方案
  • 富文本公告的渲染技巧

二、开发准备

2.1 腾讯云控制台配置

  1. 登录腾讯云通信控制台
  2. 在「应用配置」-「功能配置」中开启「群组资料存储」
  3. 记录SDKAppID并生成密钥对(生产环境建议后端生成UserSig)

2.2 项目初始化

# 创建UniApp项目(若已创建可跳过)
vue create -p dcloudio/uni-preset-vue im-group-notice

# 安装依赖
npm install tim-wx-sdk dayjs --save

2.3 初始化配置优化

// utils/tim.js
import TIM from 'tim-wx-sdk'

export const createTIM = () => {
  const options = {
    SDKAppID: xxxxxxxxxxx, // 替换为实际ID
    group: {
      // 开启群组资料变更监听
      onGetGroupInfo: true,
      onUpdateGroupInfo: true
    }
  }

  #ifdef H5
  options.useUploadPlugin = true
  #endif

  const tim = TIM.create(options)
  
  // 监听群资料变更
  tim.on(TIM.EVENT.GROUP_ATTRIBUTES_UPDATE, handleGroupUpdate)

  return tim
}

三、核心功能实现

3.1 数据结构设计

// 群公告数据结构规范
const NOTICE_SCHEMA = {
  content: '',    // 公告内容(支持Markdown)
  publisher: '',  // 发布者ID
  publishTime: 0, // 发布时间戳
  version: 1      // 版本号(用于冲突检测)
}

3.2 发布/修改公告

// api/group.js
export const updateGroupNotice = async (groupID, newContent) => {
  try {
    // 1. 获取当前群资料
    const { data: currentProfile } = await tim.getGroupProfile({ groupID })
    
    // 2. 构造新公告数据
    const newNotice = {
      ...NOTICE_SCHEMA,
      content: newContent,
      publisher: tim.userID,
      publishTime: Date.now(),
      version: (currentProfile.group.notification?.version || 0) + 1
    }

    // 3. 更新群资料
    const promise = tim.setGroupProfile({
      groupID,
      notification: JSON.stringify(newNotice)
    })

    // 4. 发送系统通知
    await sendNoticeUpdateNotification(groupID, newNotice)

    return await promise
  } catch (error) {
    handleTIMError(error, '更新公告')
  }
}

3.3 权限校验

// utils/permission.js
export const checkNoticePermission = async (groupID) => {
  // 获取群组资料
  const { data: groupProfile } = await tim.getGroupProfile({ groupID })
  
  // 校验规则
  const rules = [
    {
      check: () => groupProfile.group.ownerID === tim.userID,
      error: '仅群主可操作'
    },
    {
      check: () => groupProfile.group.type === 'Public',
      error: '私有群暂不支持'
    }
  ]

  for (const rule of rules) {
    if (!rule.check()) {
      uni.showToast({ title: rule.error, icon: 'none' })
      return false
    }
  }

  return true
}

3.4 公告监听与渲染

// 监听群资料变更
const handleGroupUpdate = (event) => {
  if (event.data.groupID !== currentGroupID) return
  
  try {
    const newNotice = JSON.parse(event.data.notification)
    renderNotice(newNotice)
  } catch (error) {
    console.error('公告解析失败', error)
  }
}

// 富文本渲染
const renderNotice = (notice) => {
  const htmlContent = marked.parse(notice.content)
  // H5使用v-html,小程序使用rich-text组件
  #ifdef H5
  noticeRef.value.innerHTML = htmlContent
  #endif
  #ifdef MP-WEIXIN
  WxParse.wxParse('notice', 'html', htmlContent, that, 5)
  #endif
}

四、消息通知实现

4.1 系统通知发送

export const sendNoticeUpdateNotification = async (groupID, notice) => {
  const message = tim.createCustomMessage({
    to: groupID,
    conversationType: TIM.TYPES.CONV_GROUP,
    payload: {
      data: JSON.stringify({
        type: 'GROUP_NOTICE_UPDATE',
        content: notice.content,
        publisher: notice.publisher,
        time: notice.publishTime
      })
    }
  })

  return tim.sendMessage(message)
}

4.2 客户端消息处理

// 注册消息监听
tim.on(TIM.EVENT.MESSAGE_RECEIVED, (event) => {
  event.data.forEach(message => {
    if (message.type === 'TIMCustomMessage') {
      try {
        const data = JSON.parse(message.payload.data)
        if (data.type === 'GROUP_NOTICE_UPDATE') {
          handleNoticeUpdate(data)
        }
      } catch (error) {
        console.error('消息解析失败', error)
      }
    }
  })
})

const handleNoticeUpdate = (data) => {
  uni.showToast({
    title: `新公告:${data.content.slice(0, 10)}...`,
    icon: 'none'
  })
  // 更新本地公告缓存
  updateLocalNoticeCache(data)
}

五、扩展功能实现

5.1 公告历史版本

export const getNoticeHistory = async (groupID) => {
  // 实际开发需对接后端接口
  // 示例返回模拟数据
  return [
    { version: 1, content: '初始公告', time: 1620000000000 },
    { version: 2, content: '更新说明', time: 1620003600000 }
  ]
}

5.2 定时发布功能

// 使用dayjs处理时间
import dayjs from 'dayjs'

export const scheduleNotice = (groupID, content, publishTime) => {
  const timer = setTimeout(async () => {
    await updateGroupNotice(groupID, content)
    uni.showToast({ title: '公告已发布' })
  }, dayjs(publishTime).diff(dayjs()))

  return () => clearTimeout(timer) // 返回取消函数
}

六、注意事项

  1. 安全建议

    • 公告内容需做XSS过滤
    • 重要操作记录审计日志
    • 发布频率限制(如1次/5分钟)
  2. 性能优化

    • 公告内容本地缓存(使用uni.setStorageSync
    • 差异更新检测(比较version字段)
    • 长公告分页加载
  3. 异常处理

    const handleTIMError = (error, action) => {
      const errMap = {
        10025: '无操作权限',
        20003: '群不存在',
        20013: '参数错误',
        20020: '版本冲突'
      }
      const msg = errMap[error.code] || error.message
      uni.showToast({ title: `${action}失败:${msg}`, icon: 'none' })
    }
    

七、总结

通过本文实现,你可以获得:

  1. 完整的群公告生命周期管理
  2. 三端兼容的富文本渲染方案
  3. 实时消息通知机制
  4. 健壮的权限控制系统

实际开发中建议:

  1. 结合腾讯云群组管理文档持续优化
  2. 对敏感操作增加二次确认
  3. 实现公告阅读状态统计(需配合自定义消息)

网站公告

今日签到

点亮在社区的每一天
去签到