403 lines
11 KiB
JavaScript
403 lines
11 KiB
JavaScript
|
|
// 好友详情页面
|
|||
|
|
const app = getApp();
|
|||
|
|
const friendAPI = require('../../../utils/friend-api.js');
|
|||
|
|
|
|||
|
|
Page({
|
|||
|
|
data: {
|
|||
|
|
// 好友信息
|
|||
|
|
friendInfo: null,
|
|||
|
|
loading: true,
|
|||
|
|
|
|||
|
|
// 操作状态
|
|||
|
|
isDeleting: false,
|
|||
|
|
|
|||
|
|
// UI 预计算字段
|
|||
|
|
friendInitial: '?'
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onLoad(options) {
|
|||
|
|
// 获取好友ID
|
|||
|
|
const customId = options.customId;
|
|||
|
|
if (customId) {
|
|||
|
|
this.loadFriendDetail(customId);
|
|||
|
|
} else {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '参数错误',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
setTimeout(() => {
|
|||
|
|
wx.navigateBack();
|
|||
|
|
}, 1500);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加载好友详情
|
|||
|
|
async loadFriendDetail(customId) {
|
|||
|
|
try {
|
|||
|
|
this.setData({ loading: true });
|
|||
|
|
|
|||
|
|
const response = await friendAPI.getFriendDetail(customId);
|
|||
|
|
if (response && (response.code === 0 || response.code === 200 || response.code === '0' || response.code === '200')) {
|
|||
|
|
const friendInfo = response.data;
|
|||
|
|
const initial = this._computeInitial(friendInfo);
|
|||
|
|
|
|||
|
|
// 计算年龄(根据生日)
|
|||
|
|
const calculatedAge = this.calculateAge(friendInfo?.birthday);
|
|||
|
|
|
|||
|
|
// 将家乡数组转换为字符串
|
|||
|
|
let hometownText = '';
|
|||
|
|
if (friendInfo?.hometown) {
|
|||
|
|
if (Array.isArray(friendInfo.hometown)) {
|
|||
|
|
hometownText = friendInfo.hometown.filter(item => item).join(' ');
|
|||
|
|
} else if (typeof friendInfo.hometown === 'string') {
|
|||
|
|
hometownText = friendInfo.hometown;
|
|||
|
|
}
|
|||
|
|
}else if(friendInfo.locationInfo){
|
|||
|
|
hometownText = friendInfo.locationInfo.district + friendInfo.locationInfo.city
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
friendInfo: friendInfo,
|
|||
|
|
loading: false,
|
|||
|
|
friendInitial: initial,
|
|||
|
|
calculatedAge: calculatedAge,
|
|||
|
|
hometownText: hometownText
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
throw new Error(response?.message || '获取好友详情失败');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 加载好友详情失败:', error);
|
|||
|
|
this.setData({ loading: false });
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: error.message || '加载失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 延迟返回上一页
|
|||
|
|
setTimeout(() => {
|
|||
|
|
wx.navigateBack();
|
|||
|
|
}, 1500);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 根据生日计算年龄
|
|||
|
|
calculateAge(birthday) {
|
|||
|
|
if (!birthday) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// 处理 YYYY-MM-DD 格式的日期
|
|||
|
|
let birthDate;
|
|||
|
|
if (typeof birthday === 'string' && birthday.includes('-')) {
|
|||
|
|
const dateParts = birthday.split('-');
|
|||
|
|
if (dateParts.length === 3) {
|
|||
|
|
birthDate = new Date(parseInt(dateParts[0]), parseInt(dateParts[1]) - 1, parseInt(dateParts[2]));
|
|||
|
|
} else {
|
|||
|
|
birthDate = new Date(birthday);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
birthDate = new Date(birthday);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (isNaN(birthDate.getTime())) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const today = new Date();
|
|||
|
|
let age = today.getFullYear() - birthDate.getFullYear();
|
|||
|
|
const monthDiff = today.getMonth() - birthDate.getMonth();
|
|||
|
|
|
|||
|
|
// 如果还没过生日,年龄减1
|
|||
|
|
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
|||
|
|
age--;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 年龄应该大于等于0
|
|||
|
|
return age >= 0 ? age : null;
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('计算年龄失败:', error, birthday);
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 发送消息
|
|||
|
|
sendMessage() {
|
|||
|
|
const { friendInfo } = this.data;
|
|||
|
|
if (!friendInfo) return;
|
|||
|
|
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: `/pages/message/chat/chat?targetId=${friendInfo.customId}&name=${encodeURIComponent(friendInfo.nickname)}&chatType=0`
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
previewImage(e) {
|
|||
|
|
try {
|
|||
|
|
// 获取当前点击的图片索引和动态索引
|
|||
|
|
const avatar = e.currentTarget.dataset.avatar;
|
|||
|
|
// 🔥 设置标志,防止预览关闭后触发页面刷新
|
|||
|
|
this._skipNextOnShowReload = true;
|
|||
|
|
const imageUrls=[avatar];
|
|||
|
|
// 调用微信小程序的图片预览API
|
|||
|
|
wx.previewImage({
|
|||
|
|
current: avatar,
|
|||
|
|
urls: imageUrls,
|
|||
|
|
success: () => {
|
|||
|
|
// 预览打开成功,标志已设置,关闭时会触发 onShow
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
console.error('图片预览失败:', err);
|
|||
|
|
// 预览失败,清除标志
|
|||
|
|
this._skipNextOnShowReload = false;
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '预览图片失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('图片预览过程中出错:', error);
|
|||
|
|
// 出错时清除标志
|
|||
|
|
this._skipNextOnShowReload = false;
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '预览图片失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 视频通话
|
|||
|
|
videoCall() {
|
|||
|
|
const { friendInfo } = this.data;
|
|||
|
|
if (!friendInfo) return;
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '视频通话功能开发中',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 设置备注
|
|||
|
|
setRemark() {
|
|||
|
|
const { friendInfo } = this.data;
|
|||
|
|
if (!friendInfo) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '好友信息不存在',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('🔍 准备跳转到备注页面,好友信息:', friendInfo);
|
|||
|
|
|
|||
|
|
const nickname = friendInfo.nickname || friendInfo.remark || '好友';
|
|||
|
|
const customId = friendInfo.customId || '';
|
|||
|
|
const friendId = friendInfo.id || friendInfo.friendId || customId;
|
|||
|
|
const remark = friendInfo.remark || '';
|
|||
|
|
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: `/subpackages/social-remark/friend-remark?friendId=${encodeURIComponent(friendId)}&customId=${encodeURIComponent(customId)}&remark=${encodeURIComponent(remark)}&nickname=${encodeURIComponent(nickname)}`,
|
|||
|
|
success: () => {
|
|||
|
|
console.log('✅ 跳转成功');
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
console.error('❌ 跳转失败:', err);
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '跳转失败: ' + (err.errMsg || '未知错误'),
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 删除好友
|
|||
|
|
deleteFriend() {
|
|||
|
|
const { friendInfo } = this.data;
|
|||
|
|
if (!friendInfo) return;
|
|||
|
|
|
|||
|
|
wx.showModal({
|
|||
|
|
title: '删除好友',
|
|||
|
|
content: `确定要删除好友"${friendInfo.nickname}"吗?删除后将同时清理聊天记录。`,
|
|||
|
|
confirmText: '删除',
|
|||
|
|
confirmColor: '#ff4757',
|
|||
|
|
success: async (res) => {
|
|||
|
|
if (res.confirm) {
|
|||
|
|
try {
|
|||
|
|
this.setData({ isDeleting: true });
|
|||
|
|
wx.showLoading({ title: '正在删除...' });
|
|||
|
|
|
|||
|
|
// 后端删除好友关系
|
|||
|
|
await friendAPI.deleteFriend(friendInfo.customId);
|
|||
|
|
|
|||
|
|
// 🔥 删除对应的会话记录
|
|||
|
|
try {
|
|||
|
|
const nimConversationManager = require('../../../utils/nim-conversation-manager.js');
|
|||
|
|
const app = getApp();
|
|||
|
|
|
|||
|
|
// 获取当前用户的 NIM accountId
|
|||
|
|
const userInfo = app.globalData.userInfo;
|
|||
|
|
const myAccountId = userInfo?.neteaseIMAccid || userInfo?.user?.neteaseIMAccid;
|
|||
|
|
|
|||
|
|
console.log('删除会话 - 用户信息:', {
|
|||
|
|
myAccountId,
|
|||
|
|
friendId: friendInfo.customId
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (myAccountId && friendInfo.customId) {
|
|||
|
|
const conversationId = `${myAccountId}|1|${friendInfo.customId}`;
|
|||
|
|
console.log('🗑️ 准备删除会话:', conversationId);
|
|||
|
|
|
|||
|
|
await nimConversationManager.deleteConversation(conversationId);
|
|||
|
|
console.log('✅ 已删除好友会话:', conversationId);
|
|||
|
|
} else {
|
|||
|
|
console.warn('⚠️ 缺少必要信息,无法删除会话', {
|
|||
|
|
hasMyAccountId: !!myAccountId,
|
|||
|
|
hasFriendId: !!friendInfo.customId
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
} catch (convError) {
|
|||
|
|
console.error('⚠️ 删除会话失败(不影响主流程):', convError);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
wx.hideLoading();
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '已删除好友',
|
|||
|
|
icon: 'success'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 延迟返回并刷新好友列表
|
|||
|
|
setTimeout(() => {
|
|||
|
|
// 通知好友页面刷新
|
|||
|
|
const pages = getCurrentPages();
|
|||
|
|
const friendsPage = pages.find(page => page.route === 'pages/social/friends/friends');
|
|||
|
|
if (friendsPage && friendsPage.loadFriends) {
|
|||
|
|
friendsPage.loadFriends();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
wx.navigateBack();
|
|||
|
|
}, 1000);
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 删除好友失败:', error);
|
|||
|
|
wx.hideLoading();
|
|||
|
|
this.setData({ isDeleting: false });
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: error.message || '删除失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 查看位置
|
|||
|
|
viewLocation() {
|
|||
|
|
const { friendInfo } = this.data;
|
|||
|
|
if (!friendInfo || !friendInfo.locationInfo) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '暂无位置信息',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const { locationInfo } = friendInfo;
|
|||
|
|
wx.openLocation({
|
|||
|
|
latitude: locationInfo.latitude,
|
|||
|
|
longitude: locationInfo.longitude,
|
|||
|
|
name: friendInfo.nickname,
|
|||
|
|
address: locationInfo.address || '未知位置'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ===== 置顶/免打扰开关 =====
|
|||
|
|
async onTogglePin(e) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '请使用消息页面管理会话',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
async onToggleMute(e) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '请使用消息页面管理会话',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 计算头像首字母
|
|||
|
|
_computeInitial(friendInfo) {
|
|||
|
|
try {
|
|||
|
|
const name = String(friendInfo?.remark || friendInfo?.nickname || '').trim();
|
|||
|
|
if (!name) return '?';
|
|||
|
|
return name.charAt(0);
|
|||
|
|
} catch (_) {
|
|||
|
|
return '?';
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 复制ID
|
|||
|
|
copyId() {
|
|||
|
|
const { friendInfo } = this.data;
|
|||
|
|
const id = friendInfo?.customId || (friendInfo?.id ? 'findme_' + friendInfo.id : '未设置');
|
|||
|
|
if (!id || id === '未设置') {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: 'ID不存在',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
wx.setClipboardData({
|
|||
|
|
data: id,
|
|||
|
|
success: () => {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '复制成功',
|
|||
|
|
icon: 'success',
|
|||
|
|
duration: 2000
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
fail: () => {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '复制失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 查看二维码
|
|||
|
|
viewQRCode() {
|
|||
|
|
const { friendInfo } = this.data;
|
|||
|
|
if (!friendInfo || !friendInfo.customId) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '好友信息不存在',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 传递好友的 customId 参数,用于生成好友的二维码
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: `/subpackages/qr/qr-code/qr-code?customId=${friendInfo.customId}`,
|
|||
|
|
success: (res) => {
|
|||
|
|
console.log('跳转二维码页面成功', res);
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
console.error('跳转二维码页面失败', err);
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '跳转失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
});
|