findme-miniprogram-frontend/subpackages/search/global-search/global-search.js
2025-12-27 17:16:03 +08:00

475 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 🔍 全局搜索页面逻辑
// ⚠️ 注意:此文件依赖已删除的 message-search-manager需要重构为使用 NIM SDK 的搜索功能
// TODO: 集成 NIM SDK 的消息搜索 API
// const messageSearchManager = require('../../../utils/message-search-manager.js');
const app = getApp();
Page({
data: {
// 系统信息
statusBarHeight: 44,
// 搜索状态
searchKeyword: '',
searchFocus: true,
isSearching: false,
isLoadingMore: false,
// 会话搜索
conversationId: null,
conversationName: '',
isConversationSearch: false,
// 搜索结果
searchResults: [],
searchTotal: 0,
currentPage: 1,
hasMoreResults: false,
searchStatusText: '',
// 搜索历史和建议
searchHistory: [],
// 防抖定时器
searchTimer: null
},
onLoad(options) {
// 获取系统信息
this.getSystemInfo();
// 初始化搜索管理器
this.initSearchManager();
// 加载搜索历史
this.loadSearchHistory();
// 处理会话内搜索
if (options.conversationId) {
this.setData({
conversationId: options.conversationId,
conversationName: decodeURIComponent(options.conversationName || '聊天'),
isConversationSearch: true
});
// 更新页面标题
wx.setNavigationBarTitle({
title: `在"${this.data.conversationName}"中搜索`
});
}
// 处理传入的搜索关键词
if (options.keyword) {
this.setData({
searchKeyword: options.keyword,
searchFocus: false
});
this.performSearch();
}
},
onShow() {
// 刷新搜索历史
this.loadSearchHistory();
},
onUnload() {
// 清理定时器
if (this.data.searchTimer) {
clearTimeout(this.data.searchTimer);
}
},
// 获取系统信息
getSystemInfo() {
try {
const windowInfo = wx.getWindowInfo();
this.setData({
statusBarHeight: windowInfo.statusBarHeight || 44
});
} catch (error) {
console.error('获取系统信息失败:', error);
this.setData({
statusBarHeight: 44
});
}
},
// 初始化搜索管理器
async initSearchManager() {
try {
// TODO: 集成 NIM SDK 的搜索初始化
// await messageSearchManager.init();
console.warn('⚠️ 搜索功能需要重构为使用 NIM SDK');
} catch (error) {
console.error('❌ 搜索管理器初始化失败:', error);
}
},
// 加载搜索历史
loadSearchHistory() {
// TODO: 集成 NIM SDK 的搜索历史
// const history = messageSearchManager.getSearchHistory();
this.setData({
searchHistory: [] // 暂时返回空数组
});
},
// 🔍 ===== 搜索输入处理 =====
// 搜索输入
onSearchInput(e) {
const keyword = e.detail.value;
this.setData({
searchKeyword: keyword
});
// 防抖搜索
this.searchWithDebounce(keyword);
},
// 搜索确认
onSearchConfirm(e) {
const keyword = e.detail.value.trim();
if (keyword) {
this.performSearch();
}
},
// 防抖搜索
searchWithDebounce(keyword) {
// 清除之前的定时器
if (this.data.searchTimer) {
clearTimeout(this.data.searchTimer);
}
// 如果关键词为空,清除结果
if (!keyword.trim()) {
this.setData({
searchResults: [],
searchTotal: 0,
hasMoreResults: false
});
return;
}
// 设置新的定时器
const timer = setTimeout(() => {
this.performSearch();
}, 500);
this.setData({
searchTimer: timer
});
},
// 清除搜索
clearSearch() {
this.setData({
searchKeyword: '',
searchResults: [],
searchTotal: 0,
hasMoreResults: false,
searchFocus: true
});
},
// 🔍 ===== 搜索执行 =====
// 执行搜索
async performSearch() {
const keyword = this.data.searchKeyword.trim();
if (!keyword) {
return;
}
// 关键词长度与字符校验(限制过长或异常字符,允许中英文、数字、常见符号)
if (keyword.length > 120) {
wx.showToast({ title: '关键词过长', icon: 'none' });
return;
}
const allowedPattern = /^[\u4e00-\u9fa5\w\s\-_.!@#¥$?:;,,。、“”"'()/\\]{1,120}$/;
if (!allowedPattern.test(keyword)) {
wx.showToast({ title: '含非法字符', icon: 'none' });
return;
}
try {
this.setData({
isSearching: true,
currentPage: 1,
searchResults: [],
searchStatusText: '正在搜索...'
});
// 调用搜索管理器
const searchOptions = {
page: 1
};
// 如果是会话内搜索添加会话ID
if (this.data.isConversationSearch && this.data.conversationId) {
searchOptions.conversationId = this.data.conversationId;
}
// TODO: 集成 NIM SDK 的消息搜索
// const result = await messageSearchManager.searchMessages(keyword, searchOptions);
// 暂时返回空结果
const result = { success: false, message: '搜索功能正在重构中' };
if (result.success) {
// 处理搜索结果(按会话聚合)
const processedResults = this.processConversationResults(result.data.conversations || []);
// 更新搜索状态文本
const statusText = this.data.isConversationSearch
? `在"${this.data.conversationName}"中找到 ${result.data.total} 条结果`
: `找到 ${result.data.total} 条相关结果`;
this.setData({
searchResults: processedResults,
searchTotal: result.data.total,
hasMoreResults: result.data.hasMore,
currentPage: 1,
searchStatusText: statusText
});
} else {
console.error('❌ 搜索失败:', result.error, result.status);
let toastMsg = result.error || '搜索失败';
if (result.status === 400) toastMsg = '参数错误';
else if (result.status === 404) toastMsg = '未找到相关结果';
else if (result.status === 500) toastMsg = '服务器开小差';
else if (!result.status && /网络|timeout|超时|Network/i.test(result.error || '')) toastMsg = '网络异常';
wx.showToast({ title: toastMsg, icon: 'none' });
this.setData({ searchStatusText: toastMsg });
}
} catch (error) {
console.error('❌ 搜索异常:', error);
wx.showToast({
title: '搜索出错',
icon: 'none'
});
} finally {
this.setData({
isSearching: false
});
}
},
// 加载更多结果
async loadMoreResults() {
if (!this.data.hasMoreResults || this.data.isLoadingMore) {
return;
}
try {
this.setData({
isLoadingMore: true
});
const nextPage = this.data.currentPage + 1;
const searchOptions = {
page: nextPage
};
// 如果是会话内搜索添加会话ID
if (this.data.isConversationSearch && this.data.conversationId) {
searchOptions.conversationId = this.data.conversationId;
}
// TODO: 集成 NIM SDK 的消息搜索
// const result = await messageSearchManager.searchMessages(this.data.searchKeyword, searchOptions);
// 暂时返回空结果
const result = { success: false };
if (result.success) {
const processedResults = this.processConversationResults(result.data.conversations || []);
const allResults = [...this.data.searchResults, ...processedResults];
this.setData({
searchResults: allResults,
hasMoreResults: result.data.hasMore,
currentPage: nextPage
});
}
} catch (error) {
console.error('❌ 加载更多失败:', error);
wx.showToast({
title: '加载失败',
icon: 'none'
});
} finally {
this.setData({
isLoadingMore: false
});
}
},
// 处理搜索结果(会话聚合)
processConversationResults(conversations) {
try {
const metaMap = wx.getStorageSync('activeConversationMap') || {};
return (conversations || []).map(raw => {
const conv = { ...raw };
const cid = String(conv.conversationId || conv.id || '');
// 兜底补齐名称/头像
const meta = cid && metaMap[cid] ? metaMap[cid] : null;
if (!conv.conversationName && meta && meta.conversationName) {
conv.conversationName = meta.conversationName;
}
if (!conv.conversationAvatar && meta && meta.conversationAvatar) {
conv.conversationAvatar = meta.conversationAvatar;
}
// 与 message 页对齐:提供通用字段 name/avatar
const name = conv.conversationName || (meta && meta.conversationName) || '';
const avatar = conv.conversationAvatar || (meta && meta.conversationAvatar) || '';
const ts = conv.topMatch && conv.topMatch.timestamp ? conv.topMatch.timestamp : null;
const formattedTime = ts ? this.formatMessageTime(ts) : '';
const conversationInitial = this.getConversationInitial(name);
return {
...conv,
name,
avatar,
formattedTime,
conversationInitial
};
});
} catch (e) {
// 兜底:不因异常影响渲染
return (conversations || []).map(conv => {
const ts = conv.topMatch && conv.topMatch.timestamp ? conv.topMatch.timestamp : null;
const formattedTime = ts ? this.formatMessageTime(ts) : '';
const name = conv.conversationName || '';
const avatar = conv.conversationAvatar || '';
const conversationInitial = this.getConversationInitial(name);
return { ...conv, name, avatar, formattedTime, conversationInitial };
});
}
},
// 格式化消息时间
formatMessageTime(timestamp) {
const now = new Date();
const messageTime = new Date(timestamp);
const diffMs = now.getTime() - messageTime.getTime();
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
if (diffDays === 0) {
// 今天
return messageTime.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit'
});
} else if (diffDays === 1) {
// 昨天
return '昨天 ' + messageTime.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit'
});
} else if (diffDays < 7) {
// 一周内
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
return `${weekdays[messageTime.getDay()]}`;
} else {
// 更早
return messageTime.toLocaleDateString('zh-CN', {
month: '2-digit',
day: '2-digit'
});
}
},
// 获取会话名称
getConversationName(message) {
// 这里可以根据conversationId获取会话名称
// 暂时返回默认值
if (message.conversationId) {
return message.conversationName || '群聊';
}
return '私聊';
},
// 获取会话头像首字
getConversationInitial(name) {
if (!name || typeof name !== 'string') return '聊';
const trimmed = name.trim();
if (!trimmed) return '聊';
// 取首个字符(兼容 emoji/代理空格时的情况)
return trimmed.charAt(0);
},
// (已移除)搜索类型切换相关逻辑
// 🔍 ===== 搜索历史管理 =====
// 选择历史搜索项
selectHistoryItem(e) {
const keyword = e.currentTarget.dataset.keyword;
this.setData({
searchKeyword: keyword,
searchFocus: false
});
this.performSearch();
},
// 删除历史搜索项
removeHistoryItem(e) {
const keyword = e.currentTarget.dataset.keyword;
// TODO: 集成 NIM SDK 的搜索历史管理
// messageSearchManager.removeSearchHistoryItem(keyword);
this.loadSearchHistory();
},
// 清除搜索历史
clearSearchHistory() {
wx.showModal({
title: '清除搜索历史',
content: '确定要清除所有搜索历史吗?',
success: (res) => {
if (res.confirm) {
// TODO: 集成 NIM SDK 的搜索历史管理
// messageSearchManager.clearSearchHistory();
this.loadSearchHistory();
}
}
});
},
// (已移除)热门搜索相关逻辑
// 🔍 ===== 搜索结果操作 =====
// 打开会话
openConversation(e) {
const item = e.currentTarget.dataset.conversation;
if (!item) return;
const convId = item.conversationId;
const name = encodeURIComponent(item.conversationName || '聊天');
const chatType = typeof item.chatType === 'number' ? item.chatType : 0;
const targetId = item.targetId || '';
// 跳转到聊天页面(遵循消息页约定路径)
wx.navigateTo({
url: `/pages/message/chat/chat?conversationId=${convId}&targetId=${targetId}&name=${name}&chatType=${chatType}`
});
},
// 🔍 ===== 页面导航 =====
// 返回上一页
goBack() {
wx.navigateBack();
}
});