uniapp 集成腾讯云 IM 消息搜索功能

发布于:2025-06-07 ⋅ 阅读:(17) ⋅ 点赞:(0)

UniApp 集成腾讯云 IM 消息搜索功能实战指南

一、功能实现原理

腾讯云 IM 通过 消息漫游 + 服务端搜索接口 实现消息检索,核心机制如下:

  1. 数据存储:消息默认存储7天(可扩展至30天)
  2. 索引构建:基于消息内容自动建立倒排索引
  3. 检索接口:提供关键词匹配、时间范围、发送者等多维度查询
  4. 结果排序:按消息时间戳倒序排列

二、核心实现步骤

1. 初始化搜索模块

// services/search.js
import { initIM } from './im'

const tim = initIM()

// 配置搜索参数
const SEARCH_CONFIG = {
  MAX_KEYWORD_LENGTH: 30,    // 最大关键词长度
  DEFAULT_PAGE_SIZE: 20,     // 默认分页大小
  MAX_HISTORY_DAYS: 7        // 最大历史查询天数
}

// 创建搜索实例
export function createSearchEngine(options) {
  return {
    conversationID: options.conversationID,
    keyword: '',
    timeRange: {
      startTime: Date.now() - 7 * 24 * 3600 * 1000,
      endTime: Date.now()
    },
    page: 1,
    pageSize: SEARCH_CONFIG.DEFAULT_PAGE_SIZE
  }
}

2. 执行消息搜索

export async function executeSearch(engine) {
  const tim = initIM()
  
  try {
    const res = await tim.getMessageList({
      conversationID: engine.conversationID,
      keyword: engine.keyword,
      nextSeq: engine.page === 1 ? 0 : engine.nextSeq,
      count: engine.pageSize
    })

    return {
      messages: res.data.messageList || [],
      hasNext: res.data.isCompleted === 0,
      nextSeq: res.data.nextSeq
    }
  } catch (error) {
    console.error('搜索失败:', error)
    throw new Error('消息搜索失败,请检查网络')
  }
}

3. 搜索结果渲染

<template>
  <view class="search-results">
    <scroll-view 
      scroll-y
      @scrolltolower="loadMore"
    >
      <view 
        v-for="(msg, index) in results"
        :key="msg.clientMsgID"
        class="search-item"
      >
        <view class="highlight-text">
          {{ msg.payload.text.replace(
            new RegExp(engine.keyword, 'gi'), 
            (match) => `<mark>${match}</mark>`
          ) }}
        </view>
        <view class="meta-info">
          {{ formatTime(msg.time) }} - {{ msg.from }}
        </view>
      </view>
      
      <view v-if="loading" class="loading-tip">
        加载中...
      </view>
      
      <view v-if="!hasNext" class="end-tip">
        没有更多结果了
      </view>
    </scroll-view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      engine: createSearchEngine({
        conversationID: 'current_conv_id'
      }),
      results: [],
      loading: false,
      hasNext: true
    }
  },
  methods: {
    async loadMore() {
      if (this.loading || !this.hasNext) return
      
      this.loading = true
      const res = await executeSearch(this.engine)
      this.results = [...this.results, ...res.messages]
      this.hasNext = res.hasNext
      this.loading = false
    }
  }
}
</script>

三、关键问题处理

1. 性能优化策略

// 防抖搜索(输入框场景)
let searchDebounce = null

export function debouncedSearch(engine, callback) {
  clearTimeout(searchDebounce)
  
  searchDebounce = setTimeout(async () => {
    engine.page = 1
    const res = await executeSearch(engine)
    callback(res.messages, res.hasNext)
  }, 300) // 300ms防抖
}

2. 复杂查询构建

// 高级查询构造器
export function buildAdvancedQuery(options) {
  const tim = initIM()
  
  return {
    conversationID: options.convID,
    keyword: options.keyword || '',
    filter: {
      fromAccount: options.from || [],
      timeRange: options.timeRange || {
        startTime: Date.now() - 7 * 24 * 3600 * 1000,
        endTime: Date.now()
      }
    },
    pageIndex: options.page || 1,
    pageSize: options.pageSize || 20
  }
}

// 使用示例
const query = buildAdvancedQuery({
  convID: 'group123',
  from: 'userA',
  timeRange: {
    startTime: new Date(2023, 0, 1).getTime(),
    endTime: new Date(2023, 1, 1).getTime()
  }
})

3. 敏感词过滤

// 集成腾讯云内容安全
export async function checkSensitiveWords(text) {
  const res = await axios.post('https://cms.tencentcloudapi.com/', {
    Action: 'TextModeration',
    Content: text,
    // 其他必要参数...
  })

  return res.data.Suggestion === 'Pass'
}

// 搜索前校验
export async function validateSearchKeyword(keyword) {
  if (await checkSensitiveWords(keyword)) {
    return keyword
  }
  throw new Error('包含敏感词汇')
}

四、高级功能扩展

1. 语音消息转文本搜索

// 集成语音识别服务
export async function transcribeAudioMessage(fileKey) {
  const res = await axios.post('https://asr.tencentcloudapi.com/', {
    Action: 'SentenceRecognition',
    ProjectId: 0,
    SubServiceType: 2,
    EngSerViceType: '16k_zh',
    SourceType: 1,
    Url: fileKey
  })

  return res.data.Result
}

// 修改搜索逻辑
async function searchAudioMessages(engine) {
  const { messages } = await executeSearch(engine)
  
  const transcriptions = await Promise.all(
    messages.filter(msg => msg.type === 'TIMAudioElem')
      .map(async msg => ({
        ...msg,
        transcription: await transcribeAudioMessage(msg.payload.fileKey)
      }))
  )
  
  return transcriptions
}

2. 搜索结果聚合

// 按发送者聚合结果
function groupBySender(messages) {
  return messages.reduce((acc, msg) => {
    if (!acc[msg.from]) acc[msg.from] = []
    acc[msg.from].push(msg)
    return acc
  }, {})
}

// 按日期聚合
function groupByDate(messages) {
  return messages.reduce((acc, msg) => {
    const dateKey = dayjs(msg.time).format('YYYY-MM-DD')
    if (!acc[dateKey]) acc[dateKey] = []
    acc[dateKey].push(msg)
    return acc
  }, {})
}

3. 搜索历史管理

// 本地存储搜索历史
export function saveSearchHistory(keyword) {
  const history = uni.getStorageSync('search_history') || []
  const newHistory = [...new Set([keyword, ...history.slice(0, 49)])]
  uni.setStorageSync('search_history', newHistory)
}

// 清除历史记录
export function clearSearchHistory() {
  uni.removeStorageSync('search_history')
}

五、常见问题排查

  1. Q: 搜索结果不完整
    A: 检查时间范围设置,确保endTime > startTime,且在有效期内(默认7天)

  2. Q: 特殊字符搜索异常
    A: 对关键词进行URL编码处理:encodeURIComponent(keyword)

  3. Q: 群聊消息搜索失败
    A: 确认群类型是否为Private(私有群),Public群需群主操作

  4. Q: 消息内容高亮失效
    A: 确保使用v-html指令渲染,并做好XSS防护:v-html="highlightedText"

六、性能优化建议

  1. 对超过1000条的会话禁用全局搜索
  2. 实现搜索结果虚拟滚动(仅渲染可视区域)
  3. 对高频关键词建立本地缓存(使用uni.setStorage
  4. 使用Web Worker处理复杂文本分析
  5. 限制最大并发搜索数为3

网站公告

今日签到

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