findme-miniprogram-frontend/pages/circle/circle.js

1809 lines
59 KiB
JavaScript
Raw Permalink Normal View History

2025-12-27 17:16:03 +08:00
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
});
}
}
});
},
});