findme-miniprogram-frontend/pages/circle/circle.js
2025-12-27 17:16:03 +08:00

1808 lines
59 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.

const config = require('../../config/config.js');
const apiClient = require('../../utils/api-client.js');
const { getListImageUrl, getPreviewImageUrl, getOriginalImageUrl } = require('../../utils/image-url-optimizer.js');
Page({
data: {
feedList: [], // 动态列表数据
userList: [], // 用户列表(从头像模块显示)
page: 1, // 当前页码
pageSize: 5, // 每页加载数量
loading: false, // 是否正在加载
noMore: false, // 是否没有更多数据
currentYear: new Date().getFullYear(), // 当前年份
// 定位相关数据
latitude: null,
longitude: null,
radius: 30,
modeFrom: '',
feedUuid: '',
pendingFeedUuid: '',
scrollIntoFeedId: '',
highlightFeedUuid: '',
lastRedirectToken: '',
// 评论弹窗相关
showCommentModal: false, // 是否显示评论弹窗
currentFeedUuid: '', // 当前评论的动态UUID
currentFeedIndex: -1, // 当前评论的动态索引
currentComments: [], // 当前显示的评论列表
commentInputValue: '', // 评论输入内容
// 回复相关
replyingCommentId: null, // 当前正在回复的评论ID
replyingCommentIndex: null, // 当前正在回复的评论索引(一级评论)
replyingToCommentId: null, // 回复的目标评论ID二级评论的父评论
replyInputValue: '', // 回复输入内容
showReplyInput: {}, // 控制每个评论的回复输入框显示状态 {commentId: true/false}
submittingReply: false // 是否正在提交回复,防止重复点击
},
onLoad(options = {}) {
this._skipNextOnShowReload = true;
this.highlightTimer = null;
const mapLatitude = parseFloat(options.latitude);
const mapLongitude = parseFloat(options.longitude);
const hasMapParams = !Number.isNaN(mapLatitude) && !Number.isNaN(mapLongitude);
if (hasMapParams) {
const parsedRadius = parseInt(options.radius, 10);
const safeRadius = Number.isNaN(parsedRadius) ? this.data.radius : Math.max(10, parsedRadius);
this._skipNextOnShowReload = true;
this.setData({
latitude: mapLatitude,
longitude: mapLongitude,
radius: safeRadius,
modeFrom: options.mode || 'map',
feedUuid: options.feedUuid || '',
pendingFeedUuid: options.feedUuid || ''
}, () => {
this.resetAndLoadFeedList();
});
return;
}
// 先获取定位,再加载数据
this.getLocation().then(() => {
this.loadFeedList();
}).catch(() => {});
this.apiClient = apiClient;
},
// 获取用户地理位置
getLocation() {
return new Promise((resolve, reject) => {
wx.getLocation({
type: 'gcj02',
success: (res) => {
this.setData({
latitude: res.latitude,
longitude: res.longitude
});
resolve(); // 定位成功,允许加载数据
},
fail: (err) => {
wx.showToast({
title: '获取位置失败,无法加载附近动态',
icon: 'none',
duration: 2000
});
reject(err);
}
});
});
},
resetAndLoadFeedList() {
if (!this.data.latitude || !this.data.longitude) {
return;
}
this.setData({ page: 1, feedList: [], noMore: false, scrollIntoFeedId: '' }, () => {
this.loadFeedList();
});
},
onShow() {
// 🔥 设置tabBar选中状态为"圈子"索引1
try {
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
this.getTabBar().setData({ selected: 1 });
}
} catch (_) {}
const appInstance = getApp();
const redirectPayload = appInstance?.globalData?.mapFeedRedirect;
if (redirectPayload && redirectPayload.token && redirectPayload.token !== this.data.lastRedirectToken) {
appInstance.globalData.mapFeedRedirect = null;
this.applyRedirectPayload(redirectPayload);
return;
}
if (this._skipNextOnShowReload) {
// 延迟清除标志,确保能捕获到预览关闭事件
setTimeout(() => {
this._skipNextOnShowReload = false;
}, 500);
return;
}
// 页面显示时刷新数据
if (this.data.latitude && this.data.longitude) {
this.resetAndLoadFeedList();
}
},
// 加载动态列表
loadFeedList() {
// 检查是否有定位信息
if (!this.data.latitude || !this.data.longitude) return;
if (this.data.loading || this.data.noMore) return;
this.setData({ loading: true });
// 通过字符串模板拼接带参数的URL
const { page, pageSize, latitude, longitude } = this.data;
// 查看所有动态
const fullRequestUrl = `${config.api.baseUrl}/api/v1/feeds?` +
`type=timeline&` +
`page=${page}&` +
`pageSize=${pageSize}&` +
`latitude=${latitude}&` +
`longitude=${longitude}&` +
`radius=30`;
// 先检查URL是否有效
if (!fullRequestUrl || !fullRequestUrl.startsWith('http')) {
console.error('无效的请求URL:', fullRequestUrl);
this.setData({ loading: false });
wx.showToast({ title: '加载失败,请重试', icon: 'none' });
return;
}
// 调用接口
wx.request({
url: fullRequestUrl,
method: 'GET',
header: {
'Authorization': `Bearer ${apiClient.getToken() || ''}`
},
success: (res) => {
if (res.data.data?.feeds && res.data.data.feeds.length > 0) {
if (res.data.data.feeds[0].media && res.data.data.feeds[0].media.length > 0) {
}
}
this.setData({ loading: false });
// 🔥 统一处理401 - 使用apiClient的统一处理
if (apiClient.is401Error(res)) {
const app = getApp();
const isLoggedIn = app?.globalData?.isLoggedIn || false;
apiClient.handle401Error(isLoggedIn);
return;
}
if (res.data.code !== 200) {
wx.showToast({
title: res.data.message || '加载失败',
icon: 'none'
});
return;
}
const newFeeds = res.data.data.feeds || [];
const processedFeeds = newFeeds.map((feed, feedIdx) => {
// 时间格式化
let formattedTime = '未知时间';
try {
formattedTime = this.formatTime(feed.createdAt || '');
} catch (error) {
console.error('时间格式化失败:', error);
}
// 用户信息
const feedUser = feed.user || {};
console.log("当前动态的用户信息", feedUser)
// 处理用户头像URL
let validAvatar = feedUser.avatar || '';
if (validAvatar && !validAvatar.startsWith('http') && validAvatar.startsWith('/')) {
try {
const baseDomain = config.api.baseUrl.replace(/\/api\/v1$/, '');
validAvatar = `${baseDomain}${validAvatar}`;
} catch (e) {
console.error(`头像路径转换失败:`, e);
}
}
if (validAvatar && validAvatar.startsWith('http://')) {
validAvatar = validAvatar.replace('http://', 'https://');
}
if (!validAvatar || (!validAvatar.startsWith('http://') && !validAvatar.startsWith('https://'))) {
console.warn(`无效的头像URL使用占位图:`, validAvatar);
validAvatar = '/images/findme-logo.png';
}
// 处理动态图片
let processedMedia = [];
if (feed.media && Array.isArray(feed.media)) {
processedMedia = feed.media.map((mediaItem, index) => {
if (!mediaItem || typeof mediaItem !== 'object') {
console.warn(`动态${feed.id || index}的图片无效:`, mediaItem);
return {
url: '/images/placeholder.svg',
thumbnailUrl: '/images/placeholder.svg',
type: 'image'
};
}
// 确保图片URL有效
let validUrl = mediaItem.url || mediaItem.src || '';
let validThumbnailUrl = mediaItem.thumbnailUrl || mediaItem.thumbnail || validUrl;
if (validUrl && !validUrl.startsWith('http') && validUrl.startsWith('/')) {
try {
const baseDomain = config.api.baseUrl.replace(/\/api\/v1$/, '');
validUrl = `${baseDomain}${validUrl}`;
} catch (e) {
console.error(`图片路径转换失败:`, e);
}
}
if (validUrl && validUrl.startsWith('http://')) {
validUrl = validUrl.replace('http://', 'https://');
}
if (!validUrl || (!validUrl.startsWith('http://') && !validUrl.startsWith('https://'))) {
console.warn(`无效的图片URL使用占位图:`, validUrl);
validUrl = '/images/placeholder.svg';
}
if (validThumbnailUrl && !validThumbnailUrl.startsWith('http') && validThumbnailUrl.startsWith('/')) {
try {
const baseDomain = config.api.baseUrl.replace(/\/api\/v1$/, '');
validThumbnailUrl = `${baseDomain}${validThumbnailUrl}`;
} catch (e) {}
}
if (validThumbnailUrl && validThumbnailUrl.startsWith('http://')) {
validThumbnailUrl = validThumbnailUrl.replace('http://', 'https://');
}
if (!validThumbnailUrl || (!validThumbnailUrl.startsWith('http://') && !validThumbnailUrl.startsWith('https://'))) {
validThumbnailUrl = validUrl;
}
// 优化图片URL提高清晰度
// 列表显示使用中等质量,预览使用高质量
const optimizedUrl = getListImageUrl(validUrl, 750);
const optimizedThumbnailUrl = getListImageUrl(validThumbnailUrl, 400);
const originalUrl = getOriginalImageUrl(validUrl); // 保存原图URL用于预览
return {
...mediaItem,
url: optimizedUrl, // 列表显示用优化后的URL
thumbnailUrl: optimizedThumbnailUrl,
originalUrl: originalUrl, // 保存原图URL
type: mediaItem.type || 'image',
loading: true // 初始状态为加载中
};
}).filter(Boolean);
} else if (feed.images && Array.isArray(feed.images)) {
processedMedia = feed.images.map(imageUrl => {
// 优化图片URL提高清晰度
const optimizedUrl = getListImageUrl(imageUrl, 750);
const originalUrl = getOriginalImageUrl(imageUrl);
return {
url: optimizedUrl,
thumbnailUrl: optimizedUrl,
originalUrl: originalUrl,
type: 'image',
loading: true // 初始状态为加载中
};
});
}
// 处理评论数据,格式化评论时间,组织嵌套结构
let processedComments = [];
if (feed.comments && Array.isArray(feed.comments) && feed.comments.length > 0) {
// 获取当前用户ID用于判断是否是自己的评论
const app = getApp();
const currentUser = app.globalData.userInfo?.user || {};
const currentUserId = currentUser.id || currentUser.userId || currentUser.customId || '';
// 分离一级评论和回复
const topLevelComments = []; // 一级评论没有replyToId的
const repliesList = []; // 所有回复有replyToId的
feed.comments.forEach((item, idx) => {
// 判断是否是当前用户的评论
const itemUserId = item.userId || item.user?.id || item.user?.userId || '';
const isOwn = currentUserId && itemUserId && currentUserId.toString() === itemUserId.toString();
// 确保user对象存在如果不存在则创建默认值
const user = item.user || {};
if (!user.nickname && item.userName) {
user.nickname = item.userName;
}
if (!user.nickname) {
user.nickname = '未知用户';
}
if (!item.replyToId) {
// 一级评论
topLevelComments.push({
...item,
id: item.id || item.uuid || `comment_${feedIdx}_${idx}`,
formattedTime: item.formattedTime || this.formatCommentTime(item.createdAt || ''),
replies: [],
visibleReplyCount: 5, // 默认显示5条回复
isOwn: isOwn,
user: user // 确保user对象被绑定
});
} else {
// 回复
repliesList.push({
...item,
id: item.id || item.uuid || `reply_${feedIdx}_${idx}`,
formattedTime: item.formattedTime || this.formatCommentTime(item.createdAt || ''),
isOwn: isOwn,
user: user // 确保user对象被绑定
});
}
});
// 将回复组织到对应的一级评论下(支持多级嵌套)
// 使用多次遍历的方式,确保所有回复都能正确找到父节点
let remainingReplies = [...repliesList];
let maxIterations = 10; // 防止无限循环
let iteration = 0;
while (remainingReplies.length > 0 && iteration < maxIterations) {
iteration++;
const newRemainingReplies = [];
remainingReplies.forEach(reply => {
// 先尝试在一级评论中查找
const parentComment = topLevelComments.find(c => c.id === reply.replyToId);
if (parentComment) {
// 回复一级评论
if (!parentComment.replies) {
parentComment.replies = [];
}
// 设置 replyToUser如果父评论有 user 对象)
if (parentComment.user) {
reply.replyToUser = parentComment.user;
}
parentComment.replies.push(reply);
} else {
// 尝试在所有已处理的回复中查找父回复
let found = false;
for (let comment of topLevelComments) {
if (comment.replies && comment.replies.length > 0) {
const targetReply = comment.replies.find(r => r.id === reply.replyToId);
if (targetReply) {
// 找到父回复,设置 replyToUser 并添加到同一评论的 replies 中
if (targetReply.user) {
reply.replyToUser = targetReply.user;
}
// 在父回复后插入
const targetIndex = comment.replies.findIndex(r => r.id === reply.replyToId);
if (targetIndex >= 0) {
comment.replies.splice(targetIndex + 1, 0, reply);
} else {
comment.replies.push(reply);
}
found = true;
break;
}
}
}
if (!found) {
// 如果找不到父节点,可能是父节点还未处理,留到下一轮
newRemainingReplies.push(reply);
}
}
});
remainingReplies = newRemainingReplies;
// 如果这一轮没有处理任何回复,说明有循环依赖或找不到父节点,跳出
if (remainingReplies.length === repliesList.length && iteration > 1) {
break;
}
}
// 如果还有剩余回复(找不到父节点),作为第一个评论的回复(兜底处理)
if (remainingReplies.length > 0 && topLevelComments.length > 0) {
if (!topLevelComments[0].replies) {
topLevelComments[0].replies = [];
}
topLevelComments[0].replies.push(...remainingReplies);
}
// 对一级评论按时间倒序排序(最新的在前),确保与本地添加评论的顺序一致
topLevelComments.sort((a, b) => {
const timeA = new Date(a.createdAt || 0).getTime();
const timeB = new Date(b.createdAt || 0).getTime();
return timeB - timeA; // 倒序:最新在前
});
// 对每个评论的回复也按时间倒序排序
topLevelComments.forEach(comment => {
if (comment.replies && comment.replies.length > 0) {
comment.replies.sort((a, b) => {
const timeA = new Date(a.createdAt || 0).getTime();
const timeB = new Date(b.createdAt || 0).getTime();
return timeB - timeA; // 倒序:最新在前
});
}
});
processedComments = topLevelComments;
}
return {
...feed,
user: {
...feedUser,
avatar: validAvatar,
nickname: feedUser.nickname || feedUser.customId || feedUser.phone || '未知用户',
},
formattedTime: formattedTime,
media: processedMedia,
comments: processedComments || [], // 确保是数组
visibleCommentCount: feed.visibleCommentCount || 20 // 默认显示20条评论如果已存在则保留
};
});
// 排序动态
const sortedFeeds = this.sortFeeds(processedFeeds);
// 去重处理
let finalFeeds = sortedFeeds;
if (this.data.page !== 1 && this.data.feedList && this.data.feedList.length > 0) {
// 获取现有动态ID的集合
const existingIds = new Set(this.data.feedList.map(item => item.id || item.uuid || item.dynamicId));
// 过滤掉已经存在的动态
finalFeeds = sortedFeeds.filter(feed => {
const feedId = feed.id || feed.uuid || feed.dynamicId;
// 如果没有ID或ID不存在于现有集合中保留动态
return !feedId || !existingIds.has(feedId);
});
}
const feedsToSet = finalFeeds.filter(feed => feed && typeof feed === 'object');
const updatedFeedList = this.data.page === 1 ? feedsToSet : [...this.data.feedList, ...feedsToSet];
const pendingFeedUuid = this.data.pendingFeedUuid;
const foundTarget = pendingFeedUuid
? updatedFeedList.some(feed => {
const feedId = feed.uuid || feed.id || feed.dynamicId;
return feedId && feedId === pendingFeedUuid;
})
: false;
// 🔥 提取唯一用户列表
const uniqueUsers = this.extractUniqueUsers(updatedFeedList);
this.setData({
feedList: updatedFeedList,
userList: uniqueUsers,
page: this.data.page + 1,
noMore: !res.data.data.hasMore,
loading: false
}, () => {
this.afterFeedListUpdate(foundTarget, !res.data.data.hasMore);
});
},
fail: (err) => {
console.error(`=== 接口请求失败(${fullRequestUrl} ===`, err);
this.setData({ loading: false });
wx.showToast({
title: '加载失败,请检查网络',
icon: 'none'
});
}
});
},
// 🔥 从动态列表中提取唯一用户
extractUniqueUsers(feedList) {
const userMap = new Map();
if (!feedList || !Array.isArray(feedList)) {
return [];
}
feedList.forEach(feed => {
if (feed.user && feed.user.customId) {
const customId = feed.user.customId;
// 如果用户不存在或者当前动态更新的用户信息更完整,则更新
if (!userMap.has(customId) ||
(!userMap.get(customId).avatar && feed.user.avatar) ||
(!userMap.get(customId).nickname && feed.user.nickname)) {
userMap.set(customId, {
customId: customId,
avatar: feed.user.avatar || '/images/default-avatar.png',
nickname: feed.user.nickname || feed.user.customId || '用户'
});
}
}
});
return Array.from(userMap.values());
},
afterFeedListUpdate(foundTarget, noMore) {
const pendingUuid = this.data.pendingFeedUuid;
if (!pendingUuid) {
return;
}
if (foundTarget) {
const targetFeed = this.data.feedList.find(feed => {
const feedId = feed.uuid || feed.id || feed.dynamicId;
return feedId && feedId === pendingUuid;
});
if (targetFeed) {
const targetId = targetFeed.uuid || targetFeed.id || targetFeed.dynamicId;
const anchorId = `feed-item-${targetId}`;
this.setData({
scrollIntoFeedId: anchorId,
highlightFeedUuid: targetId,
pendingFeedUuid: ''
});
if (this.highlightTimer) {
clearTimeout(this.highlightTimer);
}
this.highlightTimer = setTimeout(() => {
this.setData({
highlightFeedUuid: '',
scrollIntoFeedId: ''
});
}, 4000);
}
return;
}
if (!noMore) {
this.loadFeedList();
} else {
this.setData({ pendingFeedUuid: '' });
}
},
applyRedirectPayload(payload) {
const safeLatitude = parseFloat(payload.latitude);
const safeLongitude = parseFloat(payload.longitude);
if (Number.isNaN(safeLatitude) || Number.isNaN(safeLongitude)) {
return;
}
const safeRadius = Math.max(10, parseInt(payload.radius, 10) || this.data.radius);
const feedUuid = payload.feedUuid || '';
const redirectToken = payload.token || `${Date.now()}`;
this.setData({
latitude: safeLatitude,
longitude: safeLongitude,
radius: safeRadius,
modeFrom: payload.mode || 'map',
feedUuid,
pendingFeedUuid: feedUuid,
lastRedirectToken: redirectToken
}, () => {
this.resetAndLoadFeedList();
});
},
// 排序动态
sortFeeds(feeds) {
const currentUser = getApp().globalData.userInfo || {};
const currentGender = currentUser.gender !== undefined ? currentUser.gender : 0;
return [...feeds].sort((a, b) => {
// 确保用户信息存在
const aUser = a.user || {};
const bUser = b.user || {};
const isAFriend = aUser.isFriend || false;
const isBFriend = bUser.isFriend || false;
// 好友优先级高于非好友
if (isAFriend && !isBFriend) return -1;
if (!isAFriend && isBFriend) return 1;
// 好友/非好友分组内排序
const aCreateTime = new Date(a.createdAt || 0).getTime();
const bCreateTime = new Date(b.createdAt || 0).getTime();
if (isAFriend && isBFriend) {
// 好友:按发布时间倒序
return bCreateTime - aCreateTime;
} else {
// 非好友:优先异性,再按时间倒序
const aGender = aUser.gender !== undefined ? aUser.gender : currentGender;
const bGender = bUser.gender !== undefined ? bUser.gender : currentGender;
const isAOpposite = aGender !== currentGender;
const isBOpposite = bGender !== currentGender;
if (isAOpposite && !isBOpposite) return -1;
if (!isAOpposite && isBOpposite) return 1;
// 同性别:按时间倒序
return bCreateTime - aCreateTime;
}
});
},
// 格式化时间
formatTime(timeStr) {
if (!timeStr) return '未知时间';
const createTime = new Date(timeStr);
if (isNaN(createTime.getTime())) return '未知时间';
const now = new Date();
const diffMinutes = Math.floor((now - createTime) / (1000 * 60));
// 5分钟内刚刚
if (diffMinutes < 5) return '刚刚';
// 格式化日期时间
const year = createTime.getFullYear();
const month = String(createTime.getMonth() + 1).padStart(2, '0');
const day = String(createTime.getDate()).padStart(2, '0');
const hour = String(createTime.getHours()).padStart(2, '0');
const minute = String(createTime.getMinutes()).padStart(2, '0');
// 跨年份显示完整日期,同年份省略年份
return year === this.data.currentYear
? `${month}${day}${hour}:${minute}`
: `${year}${month}${day}${hour}:${minute}`;
},
// 格式化评论时间
formatCommentTime(timeStr) {
if (!timeStr) return '';
const commentTime = new Date(timeStr);
if (isNaN(commentTime.getTime())) return '';
const now = new Date();
const diffMinutes = Math.floor((now - commentTime) / (1000 * 60));
// 5分钟内显示"刚刚"
if (diffMinutes < 5) return '刚刚';
// 格式化日期时间
const year = commentTime.getFullYear();
const month = commentTime.getMonth() + 1; // 不加前导0直接显示月份
const day = commentTime.getDate();
const hour = String(commentTime.getHours()).padStart(2, '0');
const minute = String(commentTime.getMinutes()).padStart(2, '0');
// 当前年份显示不带年份的日期和时间例如8月24日 17:11
// 非当前年份显示带年份的日期和时间例如2024年 8月24日 17:11
const currentYear = now.getFullYear();
return year === currentYear
? `${month}${day}${hour}:${minute}`
: `${year}${month}${day}${hour}:${minute}`;
},
// 滚动到底部加载更多
onReachBottom() {
this.loadFeedList();
},
// 返回首页功能
navigateBackHome() {
wx.switchTab({
url: '/pages/map/map'
});
},
handlePost() {
// 跳转到发布页面
wx.navigateTo({
url: '/subpackages/media/edits/edits',
fail: (err) => {
console.error('跳转失败:', err);
wx.showToast({
title: '跳转发布页面失败',
icon: 'none'
});
}
});
},
onHide() {
if (this.highlightTimer) {
clearTimeout(this.highlightTimer);
this.highlightTimer = null;
}
},
onUnload() {
if (this.highlightTimer) {
clearTimeout(this.highlightTimer);
this.highlightTimer = null;
}
},
// 图片预览
previewImage(e) {
try {
// 获取当前点击的图片索引和动态索引
const { index, feedIndex } = e.currentTarget.dataset;
// 获取当前动态的图片列表
const feed = this.data.feedList[feedIndex];
if (!feed || !feed.media || !feed.media.length) {
console.error('没有找到媒体数据');
return;
}
// 优先使用原始图片URL或高质量图片确保预览完整清晰的图片
const imageUrls = feed.media
.filter(item => item.type === 'image' && (item.originalUrl || item.url))
.map(item => {
// 如果有原图URL使用原图否则使用高质量优化URL
if (item.originalUrl) {
return getPreviewImageUrl(item.originalUrl);
}
return getPreviewImageUrl(item.url);
});
if (!imageUrls.length) {
console.error('没有有效的图片URL');
return;
}
// 🔥 设置标志,防止预览关闭后触发页面刷新
this._skipNextOnShowReload = true;
// 调用微信小程序的图片预览API
wx.previewImage({
current: imageUrls[index], // 当前显示图片的URL
urls: imageUrls, // 需要预览的图片URL列表
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'
});
}
},
// 图片加载成功
onImageLoad(e) {
const { index, feedIndex } = e.currentTarget.dataset;
const feedList = this.data.feedList;
if (feedList[feedIndex] && feedList[feedIndex].media && feedList[feedIndex].media[index]) {
// 更新对应图片的加载状态
const updatePath = `feedList[${feedIndex}].media[${index}].loading`;
this.setData({
[updatePath]: false
});
}
},
// 图片加载失败
onImageError(e) {
const { index, feedIndex } = e.currentTarget.dataset;
const feedList = this.data.feedList;
if (feedList[feedIndex] && feedList[feedIndex].media && feedList[feedIndex].media[index]) {
// 加载失败也隐藏 loading
const updatePath = `feedList[${feedIndex}].media[${index}].loading`;
this.setData({
[updatePath]: false
});
}
},
// 点击头像进入个人资料
navigateToUserProfile(e) {
const customId = e.currentTarget.dataset.customId;
if (!customId) return;
// 获取当前用户信息
const currentUser = getApp().globalData.userInfo || {};
const currentUserId = currentUser.user.customId || '';
// 检查是否是当前用户自己
if (customId === currentUserId) {
this.navigateToSelfProfile(customId);
return;
}
// 使用friendAPI判断是否是好友关系
this.checkFriendRelation(customId);
},
// 跳转到个人主页
navigateToSelfProfile(customId) {
const targetUrl = `/subpackages/profile/profile/profile?customId=${customId}`;
wx.navigateTo({
url: targetUrl,
fail: (err) => {
console.error('跳转个人主页失败:', err);
wx.showToast({
title: '跳转失败,请重试',
icon: 'none'
});
}
});
},
// 检查好友关系
async checkFriendRelation(customId) {
try {
const friendAPI = require('../../utils/friend-api.js');
// 显示加载提示
wx.showLoading({
title: '加载中...',
mask: true
});
// 获取好友详情
const friendDetailResponse = await friendAPI.getFriendDetail(customId);
wx.hideLoading();
if (friendDetailResponse && friendDetailResponse.code === 0 && friendDetailResponse.data){
// 成功获取好友详情,说明是好友关系
this.navigateToFriendProfile(customId);
return;
}
// 跳转到陌生人主页
this.navigateToStrangerProfile(customId);
} catch (error) {
wx.hideLoading();
console.error('检查好友关系失败:', error);
// 跳转到陌生人主页
this.navigateToStrangerProfile(customId);
}
},
// 跳转到好友主页
navigateToFriendProfile(customId) {
const targetUrl = `/subpackages/social/friend-detail/friend-detail?customId=${customId}`;
wx.navigateTo({
url: targetUrl,
fail: (err) => {
console.error('跳转好友主页失败:', err);
wx.showToast({
title: '跳转失败,请重试',
icon: 'none'
});
}
});
},
// 跳转到陌生人主页
navigateToStrangerProfile(customId) {
const targetUrl = `/subpackages/social/user-preview/user-preview?customId=${customId}`;
wx.navigateTo({
url: targetUrl,
fail: (err) => {
console.error('跳转陌生人主页失败:', err);
wx.showToast({
title: '跳转失败,请重试',
icon: 'none'
});
}
});
},
// 处理点赞
async handleLike(e) {
const feedUuid = e.currentTarget.dataset.feedUuid;
const isLiked = e.currentTarget.dataset.isliked;
const feedIndex = e.currentTarget.dataset.feedIndex; // 获取当前动态索引
if (!feedUuid) {
wx.showToast({
title: '动态ID不存在',
icon: 'none'
});
return;
}
// 检查登录状态
const app = getApp();
if (!app.globalData.isLoggedIn) {
wx.showToast({
title: '请先登录',
icon: 'none'
});
setTimeout(() => {
wx.navigateTo({
url: '/pages/login/login'
});
}, 1500);
return;
}
// TODO: 调用点赞API
console.log('点赞动态:', feedUuid);
if(!isLiked){
const response = await this.apiClient.addLikeDynamic(feedUuid);
if(response){
if(response.code==200){
wx.showToast({
title: response.data.message,
icon: 'success',
duration: 1000
});
}else{
wx.showToast({
title: response.message,
icon: 'none',
duration: 1000
});
}
}
// 更新点赞状态和数量
this.updateLikeStatus(feedIndex, true);
}else{
const responseDelete= await this.apiClient.deleteLikeDynamic(feedUuid);
if(responseDelete){
if(responseDelete.code==200){
wx.showToast({
title: responseDelete.data.message,
icon: 'success',
duration: 1000
});
}else{
wx.showToast({
title: responseDelete.message,
icon: 'none',
duration: 1000
});
}
}
// 更新点赞状态和数量
this.updateLikeStatus(feedIndex, false);
}
},
// 新增更新点赞状态的方法
updateLikeStatus(feedIndex, isLiked) {
// 复制当前的动态列表
const feedList = [...this.data.feedList];
// 检查当前动态是否存在
if (feedList[feedIndex]) {
// 初始化interactions对象防止undefined错误
if (!feedList[feedIndex].interactions) {
feedList[feedIndex].interactions = {
likeCount: 0
};
}
// 更新点赞状态
feedList[feedIndex].isLiked = isLiked;
// 更新点赞数量(点赞+1取消点赞-1
feedList[feedIndex].interactions.likeCount =
(feedList[feedIndex].interactions.likeCount || 0) + (isLiked ? 1 : -1);
// 确保数量不会小于0
if (feedList[feedIndex].interactions.likeCount < 0) {
feedList[feedIndex].interactions.likeCount = 0;
}
// 更新数据
this.setData({
feedList: feedList
});
}
},
// 处理评论 - 显示评论弹窗
async handleComment(e) {
const feedUuid = e.currentTarget.dataset.feedUuid;
const feedIndex = e.currentTarget.dataset.feedIndex;
if (!feedUuid) {
wx.showToast({
title: '动态ID不存在',
icon: 'none'
});
return;
}
// 检查登录状态
const app = getApp();
if (!app.globalData.isLoggedIn) {
wx.showToast({
title: '请先登录',
icon: 'none'
});
setTimeout(() => {
wx.navigateTo({
url: '/pages/login/login'
});
}, 1500);
return;
}
// 显示弹窗并加载评论
this.setData({
showCommentModal: true,
currentFeedUuid: feedUuid,
currentFeedIndex: feedIndex,
commentInputValue: ''
});
// 加载评论列表
await this.loadComments(feedUuid, feedIndex);
},
// 加载评论列表
async loadComments(feedUuid, feedIndex) {
try {
// 先尝试从feed数据中获取评论
const feed = this.data.feedList[feedIndex];
let comments = feed?.comments || [];
// 如果有评论数据,格式化时间
if (comments && comments.length > 0) {
comments = comments.map(comment => {
return {
...comment,
formattedTime: comment.formattedTime || this.formatCommentTime(comment.createdAt || '')
};
});
}
// 如果没有评论数据尝试从API获取如果有获取评论的API
// TODO: 如果需要从API获取评论列表在这里添加
this.setData({
currentComments: comments
});
} catch (error) {
console.error('加载评论失败:', error);
this.setData({
currentComments: []
});
}
},
// 关闭评论弹窗
closeCommentModal() {
this.setData({
showCommentModal: false,
currentFeedUuid: '',
currentFeedIndex: -1,
currentComments: [],
commentInputValue: ''
});
},
// 防止点击内容区域关闭弹窗
preventClose() {
// 空函数,阻止事件冒泡
},
// 评论输入
onCommentInput(e) {
this.setData({
commentInputValue: e.detail.value
});
},
// 提交评论
async submitComment() {
const { currentFeedUuid, currentFeedIndex, commentInputValue } = this.data;
if (!commentInputValue || !commentInputValue.trim()) {
wx.showToast({
title: '请输入评论内容',
icon: 'none',
duration: 1500
});
return;
}
// 获取当前用户信息
const app = getApp();
const currentUser = app.globalData.userInfo?.user || {};
const nickname = currentUser.nickname || currentUser.customId || '未知用户';
try {
const response = await this.apiClient.addCommentDynamic(currentFeedUuid, commentInputValue.trim(), null, nickname);
if (response && response.code === 200) {
wx.showToast({
title: '评论成功',
icon: 'success',
duration: 1000
});
// 创建新评论对象(新发布的评论默认是自己的)
const newComment = {
id: response.data?.id || `comment_${Date.now()}`,
content: commentInputValue.trim(),
createdAt: response.data?.createdAt || new Date().toISOString(),
user: {
nickname: currentUser.nickname || currentUser.customId || '未知用户',
avatar: currentUser.avatar || '/images/findme-logo.png',
customId: currentUser.customId || ''
},
formattedTime: this.formatCommentTime(response.data?.createdAt || new Date().toISOString()),
replies: [],
isOwn: true // 新发布的评论默认是自己的
};
// 清空输入框
this.setData({
commentInputValue: ''
});
// 更新动态的评论列表和数量 - 使用路径更新方式避免渲染错误
const feed = this.data.feedList[currentFeedIndex];
if (feed) {
// 初始化 comments 数组(如果不存在)
const currentComments = feed.comments || [];
const updatedComments = [newComment, ...currentComments];
// 更新评论数量
const currentCommentCount = feed.interactions?.commentCount || 0;
const visibleCommentCount = feed.visibleCommentCount || 5;
// 使用路径更新方式,确保小程序能正确检测数据变化
const updatePath = {};
updatePath[`feedList[${currentFeedIndex}].comments`] = updatedComments;
updatePath[`feedList[${currentFeedIndex}].interactions.commentCount`] = currentCommentCount + 1;
// 确保 visibleCommentCount 存在且至少为20
if (!feed.visibleCommentCount || feed.visibleCommentCount < 20) {
updatePath[`feedList[${currentFeedIndex}].visibleCommentCount`] = 20;
}
this.setData(updatePath);
}
// 更新弹窗中的评论列表
await this.loadComments(currentFeedUuid, currentFeedIndex);
// 延迟关闭评论弹窗,让用户看到成功提示
setTimeout(() => {
this.closeCommentModal();
}, 800);
} else {
wx.showToast({
title: response?.message || '评论失败',
icon: 'none',
duration: 1500
});
}
} catch (error) {
console.error('提交评论失败:', error);
wx.showToast({
title: '评论失败,请重试',
icon: 'none',
duration: 1500
});
}
},
// 删除评论
async deleteComment(e) {
const feedUuid = e.currentTarget.dataset.feedUuid;
const commentId = e.currentTarget.dataset.feedCommentId;
if (!feedUuid) {
wx.showToast({
title: '动态ID不存在',
icon: 'none'
});
return;
}
// 检查登录状态
const app = getApp();
if (!app.globalData.isLoggedIn) {
wx.showToast({
title: '请先登录',
icon: 'none'
});
setTimeout(() => {
wx.navigateTo({
url: '/pages/login/login'
});
}, 1500);
return;
}
const response = await this.apiClient.deleteCommentDynamic(feedUuid,commentId);
if(response){
if(response.code==200){
wx.showToast({
title: "删除成功",
icon: 'success',
duration: 1000
});
}else{
wx.showToast({
title: "删除失败",
icon: 'none',
duration: 1000
});
}
}
},
// 展开更多评论每次增加20条懒加载模式
expandComments(e) {
const feedIndex = e.currentTarget.dataset.feedIndex;
this.loadMoreComments(feedIndex);
},
// 加载更多评论懒加载每次加载20条
loadMoreComments(feedIndex) {
const feed = this.data.feedList[feedIndex];
if (feed && feed.comments) {
const currentCount = feed.visibleCommentCount || 20; // 当前显示的评论数量
const totalCount = feed.comments.length; // 评论总数
// 如果已经显示全部,不继续加载
if (currentCount >= totalCount) {
return;
}
// 每次增加20条但不超过总数
// 例如初始20条 -> 滚动后40条 -> 再滚动60条 -> 以此类推
const newCount = Math.min(currentCount + 20, totalCount);
if (newCount > currentCount) {
// 使用路径更新方式
this.setData({
[`feedList[${feedIndex}].visibleCommentCount`]: newCount
});
}
}
},
// 评论区域滚动到底部时触发(懒加载评论和回复)
onCommentScrollToLower(e) {
const feedIndex = e.currentTarget.dataset.feedIndex;
if (feedIndex !== undefined && feedIndex !== null) {
const feed = this.data.feedList[feedIndex];
// 先尝试加载更多回复(优先处理回复)
if (feed && feed.comments) {
let hasMoreReplies = false;
feed.comments.forEach((comment, commentIndex) => {
if (comment.replies && comment.replies.length > 0) {
const currentCount = comment.visibleReplyCount || 5;
const totalCount = comment.replies.length;
// 如果有未显示的回复,自动加载更多
if (currentCount < totalCount) {
const newCount = Math.min(currentCount + 20, totalCount);
if (newCount > currentCount) {
this.setData({
[`feedList[${feedIndex}].comments[${commentIndex}].visibleReplyCount`]: newCount
});
hasMoreReplies = true;
}
}
}
});
// 如果有加载了回复,不继续加载评论(避免一次性加载太多)
if (hasMoreReplies) {
return;
}
}
// 如果没有更多回复需要加载,则加载更多评论
this.loadMoreComments(feedIndex);
}
},
// 展开更多回复每次增加20条
expandReplies(e) {
const feedIndex = e.currentTarget.dataset.feedIndex;
const commentIndex = e.currentTarget.dataset.commentIndex;
const feed = this.data.feedList[feedIndex];
if (feed && feed.comments && feed.comments[commentIndex]) {
const comment = feed.comments[commentIndex];
const currentCount = comment.visibleReplyCount || 5; // 当前显示的回复数量默认5条
const totalCount = comment.replies ? comment.replies.length : 0; // 回复总数
// 每次增加20条但不超过总数
// 例如初始5条 -> 点击后25条 -> 再点击45条 -> 以此类推
const newCount = Math.min(currentCount + 20, totalCount);
if (newCount > currentCount) {
// 使用路径更新方式
this.setData({
[`feedList[${feedIndex}].comments[${commentIndex}].visibleReplyCount`]: newCount
});
}
}
},
// 点击回复按钮
handleReplyClick(e) {
const feedIndex = e.currentTarget.dataset.feedIndex;
const commentId = e.currentTarget.dataset.commentId;
const commentIndex = e.currentTarget.dataset.commentIndex;
const replyId = e.currentTarget.dataset.replyId; // 如果是回复二级评论这是被回复的二级评论ID
const replyToUserName = e.currentTarget.dataset.replyToUser || '';
// 生成唯一key如果有replyId说明是回复二级回复key应该包含replyId
const replyKey = replyId
? `feed_${feedIndex}_comment_${commentId}_reply_${replyId}`
: `feed_${feedIndex}_comment_${commentId}`;
// 切换回复输入框显示状态
const showReplyInput = { ...this.data.showReplyInput };
// 如果当前输入框已显示,则关闭;否则打开
if (showReplyInput[replyKey]) {
showReplyInput[replyKey] = false;
this.setData({
showReplyInput: showReplyInput,
replyInputValue: '',
replyingCommentId: null,
replyingCommentIndex: null,
replyingToCommentId: null
});
} else {
// 关闭其他所有输入框
Object.keys(showReplyInput).forEach(key => {
showReplyInput[key] = false;
});
// 打开当前输入框
showReplyInput[replyKey] = true;
// 获取feedUuid
const feed = this.data.feedList[feedIndex];
const feedUuid = feed ? (feed.uuid || feed.id || feed.dynamicId) : '';
// 如果有replyId说明是回复二级评论需要设置replyToId
this.setData({
showReplyInput: showReplyInput,
replyInputValue: replyToUserName ? `@${replyToUserName} ` : '',
replyingCommentId: commentId,
replyingCommentIndex: commentIndex,
replyingToCommentId: replyId || null,
currentFeedIndex: feedIndex,
currentFeedUuid: feedUuid
});
}
},
// 回复输入
onReplyInput(e) {
this.setData({
replyInputValue: e.detail.value
});
},
// 提交回复
async submitReply(e) {
// 防止重复点击
if (this.data.submittingReply) {
return;
}
const feedIndex = e.currentTarget.dataset.feedIndex;
const commentId = e.currentTarget.dataset.commentId;
const commentIndex = e.currentTarget.dataset.commentIndex;
const { replyInputValue, replyingToCommentId } = this.data;
// 移除 @用户名 前缀后,检查剩余内容是否为空
const contentWithoutMention = replyInputValue ? replyInputValue.trim().replace(/^@[\S]+\s+/, '') : '';
if (!replyInputValue || !replyInputValue.trim() || !contentWithoutMention) {
wx.showToast({
title: '请输入回复内容',
icon: 'none',
duration: 1500
});
return;
}
// 设置提交状态
this.setData({
submittingReply: true
});
// 获取feedUuid
const feed = this.data.feedList[feedIndex];
if (!feed) {
wx.showToast({
title: '动态不存在',
icon: 'none'
});
return;
}
const feedUuid = feed.uuid || feed.id || feed.dynamicId;
if (!feedUuid) {
wx.showToast({
title: '动态ID不存在',
icon: 'none'
});
return;
}
// 检查登录状态并获取当前用户信息
const app = getApp();
if (!app.globalData.isLoggedIn) {
wx.showToast({
title: '请先登录',
icon: 'none'
});
setTimeout(() => {
wx.navigateTo({
url: '/pages/login/login'
});
}, 1500);
return;
}
// 获取当前用户信息
const currentUser = app.globalData.userInfo?.user || {};
const nickname = currentUser.nickname || currentUser.customId || '未知用户';
try {
// 调用API提交回复如果replyingToCommentId存在说明是回复二级评论
const replyToId = replyingToCommentId || commentId;
const response = await this.apiClient.addCommentDynamic(feedUuid, replyInputValue.trim(), replyToId, nickname);
if (response && response.code === 200) {
wx.showToast({
title: '回复成功',
icon: 'success',
duration: 1000
});
// 创建新回复对象(新发布的回复默认是自己的)
const newReply = {
id: response.data?.id || `reply_${Date.now()}`,
content: replyInputValue.trim().replace(/^@[\S]+\s+/, ''), // 移除@用户名前缀
createdAt: response.data?.createdAt || new Date().toISOString(),
user: {
nickname: currentUser.nickname || currentUser.customId || '未知用户',
avatar: currentUser.avatar || '/images/findme-logo.png',
customId: currentUser.customId || ''
},
formattedTime: this.formatCommentTime(response.data?.createdAt || new Date().toISOString()),
replyToId: replyToId,
replyToUser: replyingToCommentId ? this.findReplyUser(this.data.feedList[feedIndex], commentId, replyingToCommentId) : null,
isOwn: true // 新发布的回复默认是自己的
};
// 更新动态的评论列表 - 使用路径更新方式
const feed = this.data.feedList[feedIndex];
if (feed && feed.comments && feed.comments[commentIndex]) {
const comment = feed.comments[commentIndex];
// 初始化 replies 数组(如果不存在)
const currentReplies = comment.replies || [];
const updatedReplies = [newReply, ...currentReplies];
// 更新评论数量
const currentCommentCount = feed.interactions?.commentCount || 0;
// 使用路径更新方式,确保小程序能正确检测数据变化
const updatePath = {};
updatePath[`feedList[${feedIndex}].comments[${commentIndex}].replies`] = updatedReplies;
updatePath[`feedList[${feedIndex}].interactions.commentCount`] = currentCommentCount + 1;
// 如果当前显示的回复数少于5条增加到5条以确保能看到新回复
const currentVisibleReplyCount = comment.visibleReplyCount || 5;
if (currentVisibleReplyCount < 5) {
updatePath[`feedList[${feedIndex}].comments[${commentIndex}].visibleReplyCount`] = 5;
}
// 清空回复输入框和状态
// 根据是否有replyingToCommentId来生成正确的key
const currentReplyingToCommentId = this.data.replyingToCommentId;
const replyKey = currentReplyingToCommentId
? `feed_${feedIndex}_comment_${commentId}_reply_${currentReplyingToCommentId}`
: `feed_${feedIndex}_comment_${commentId}`;
const showReplyInput = { ...this.data.showReplyInput };
showReplyInput[replyKey] = false;
updatePath.showReplyInput = showReplyInput;
updatePath.replyInputValue = '';
updatePath.replyingCommentId = null;
updatePath.replyingCommentIndex = null;
updatePath.replyingToCommentId = null;
updatePath.submittingReply = false;
this.setData(updatePath);
} else {
// 如果找不到对应数据,只更新状态
this.setData({
submittingReply: false
});
}
} else {
this.setData({
submittingReply: false // 恢复提交状态
});
wx.showToast({
title: response?.message || '回复失败',
icon: 'none',
duration: 1500
});
}
} catch (error) {
console.error('提交回复失败:', error);
this.setData({
submittingReply: false // 恢复提交状态
});
wx.showToast({
title: '回复失败,请重试',
icon: 'none',
duration: 1500
});
}
},
// 查找被回复的用户信息
findReplyUser(feed, commentId, replyId) {
if (!feed || !feed.comments) return null;
const comment = feed.comments.find(c => c.id === commentId);
if (!comment || !comment.replies) return null;
const reply = comment.replies.find(r => r.id === replyId);
return reply ? reply.user : null;
},
// 删除评论
async deleteComment(e) {
const { feedIndex, commentId, commentIndex } = e.currentTarget.dataset;
// 检查参数feedIndex可能是0所以不能用!feedIndex判断
if (feedIndex === undefined || feedIndex === null || commentId === undefined || commentId === null || commentIndex === undefined || commentIndex === null) {
console.error('删除评论参数错误:', { feedIndex, commentId, commentIndex, dataset: e.currentTarget.dataset });
wx.showToast({
title: '参数错误',
icon: 'none'
});
return;
}
console.log('删除评论,参数:', { feedIndex, commentId, commentIndex });
// 确认删除
wx.showModal({
title: '删除评论',
content: '确定要删除这条评论吗?',
confirmText: '删除',
confirmColor: '#ff4757',
success: async (res) => {
if (!res.confirm) return;
const feed = this.data.feedList[feedIndex];
if (!feed) {
wx.showToast({
title: '动态不存在',
icon: 'none'
});
return;
}
const feedUuid = feed.uuid || feed.id || feed.dynamicId;
if (!feedUuid) {
wx.showToast({
title: '动态ID不存在',
icon: 'none'
});
return;
}
try {
wx.showLoading({
title: '删除中...',
mask: true
});
const response = await this.apiClient.deleteCommentDynamic(feedUuid, commentId);
if (response && response.code === 200) {
wx.hideLoading();
wx.showToast({
title: '删除成功',
icon: 'success',
duration: 1000
});
// 从本地列表中删除评论通过ID匹配更安全
const currentComments = this.data.feedList[feedIndex].comments || [];
const updatedComments = currentComments.filter((c) => c.id !== commentId);
const currentCommentCount = (this.data.feedList[feedIndex].interactions.commentCount || 0) - 1;
// 使用路径更新方式
const updatePath = {};
updatePath[`feedList[${feedIndex}].comments`] = updatedComments;
updatePath[`feedList[${feedIndex}].interactions.commentCount`] = Math.max(0, currentCommentCount);
this.setData(updatePath);
} else {
wx.hideLoading();
wx.showToast({
title: response?.message || '删除失败',
icon: 'none',
duration: 1500
});
}
} catch (error) {
console.error('删除评论失败:', error);
wx.hideLoading();
wx.showToast({
title: '删除失败,请重试',
icon: 'none',
duration: 1500
});
}
}
});
},
// 删除回复
async deleteReply(e) {
const { feedIndex, commentId, commentIndex, replyId, replyIndex } = e.currentTarget.dataset;
// 检查参数feedIndex可能是0所以不能用!feedIndex判断
if (feedIndex === undefined || feedIndex === null || commentId === undefined || commentId === null || commentIndex === undefined || commentIndex === null || replyId === undefined || replyId === null || replyIndex === undefined || replyIndex === null) {
console.error('删除回复参数错误:', { feedIndex, commentId, commentIndex, replyId, replyIndex, dataset: e.currentTarget.dataset });
wx.showToast({
title: '参数错误',
icon: 'none'
});
return;
}
console.log('删除回复,参数:', { feedIndex, commentId, commentIndex, replyId, replyIndex });
// 确认删除
wx.showModal({
title: '删除回复',
content: '确定要删除这条回复吗?',
confirmText: '删除',
confirmColor: '#ff4757',
success: async (res) => {
if (!res.confirm) return;
const feed = this.data.feedList[feedIndex];
if (!feed) {
wx.showToast({
title: '动态不存在',
icon: 'none'
});
return;
}
const feedUuid = feed.uuid || feed.id || feed.dynamicId;
if (!feedUuid) {
wx.showToast({
title: '动态ID不存在',
icon: 'none'
});
return;
}
try {
wx.showLoading({
title: '删除中...',
mask: true
});
const response = await this.apiClient.deleteCommentDynamic(feedUuid, replyId);
if (response && response.code === 200) {
wx.hideLoading();
wx.showToast({
title: '删除成功',
icon: 'success',
duration: 1000
});
// 从本地列表中删除回复通过ID匹配更安全
const currentComments = this.data.feedList[feedIndex].comments || [];
// 通过commentId查找评论而不是使用commentIndex更安全
const targetCommentIndex = currentComments.findIndex(c => c.id === commentId);
if (targetCommentIndex >= 0) {
const targetComment = currentComments[targetCommentIndex];
if (targetComment && targetComment.replies) {
const updatedReplies = targetComment.replies.filter((r) => r.id !== replyId);
const currentCommentCount = (this.data.feedList[feedIndex].interactions.commentCount || 0) - 1;
// 使用路径更新方式
const updatePath = {};
updatePath[`feedList[${feedIndex}].comments[${targetCommentIndex}].replies`] = updatedReplies;
updatePath[`feedList[${feedIndex}].interactions.commentCount`] = Math.max(0, currentCommentCount);
this.setData(updatePath);
}
}
} else {
wx.hideLoading();
wx.showToast({
title: response?.message || '删除失败',
icon: 'none',
duration: 1500
});
}
} catch (error) {
console.error('删除回复失败:', error);
wx.hideLoading();
wx.showToast({
title: '删除失败,请重试',
icon: 'none',
duration: 1500
});
}
}
});
},
});