小程序实现对话框回复
This commit is contained in:
@@ -25,9 +25,14 @@ Component({
|
||||
error: null as string | null,
|
||||
totalCommentsCount: 0, // *** 新增:存储所有评论的总数 (包括回复) ***
|
||||
cardReviewData: null as any | null,
|
||||
showReplyInput: false,
|
||||
currentReplyId: '',
|
||||
replyContent: '',
|
||||
|
||||
|
||||
|
||||
showReplyInput: false, // 控制输入框是否显示
|
||||
currentReplyId: '', // 当前正在回复的评论ID
|
||||
currentReplyUsername: '', // 当前正在回复的用户名(用于 placeholder)
|
||||
replyContent: '', // 输入框中的内容
|
||||
isSubmitDisabled: true,
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +55,165 @@ Component({
|
||||
},
|
||||
|
||||
methods: {
|
||||
closeInput() {
|
||||
if (this.data.showReplyInput) {
|
||||
this.setData({
|
||||
showReplyInput: false,
|
||||
currentReplyId: null,
|
||||
currentReplyUsername: '',
|
||||
replyContent: '',
|
||||
isSubmitDisabled: true,
|
||||
keyboardHeight: 0
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面滚动时,调用关闭函数
|
||||
*/
|
||||
onPageScroll() {
|
||||
this.closeInput();
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击“空白”区域(现在是整个 scroll-view)时,调用关闭函数
|
||||
*/
|
||||
handleBlankTap() {
|
||||
console.log("scroll-view 区域被点击,准备关闭输入框");
|
||||
this.closeInput();
|
||||
},
|
||||
|
||||
/**
|
||||
* ✅ 核心修改:处理点击评论项的逻辑
|
||||
*/
|
||||
handleCommentTap(e: WechatMiniprogram.TouchEvent) {
|
||||
const wasShowing = this.data.showReplyInput;
|
||||
const tappedCommentId = e.currentTarget.dataset.item?.id;
|
||||
|
||||
// 步骤 1: 立刻关闭当前可能已打开的输入框
|
||||
this.closeInput();
|
||||
|
||||
// 步骤 2: 使用延时来重新打开输入框
|
||||
// 这是一个技巧,确保关闭操作完成后再执行打开操作,避免冲突
|
||||
setTimeout(() => {
|
||||
const commentData = e.currentTarget.dataset.item;
|
||||
if (commentData) {
|
||||
// 如果刚刚输入框是开着的,并且点的是同一个评论,那么我们其实是想关闭它,而不是重新打开
|
||||
if (wasShowing && this.data.currentReplyId === tappedCommentId) {
|
||||
return;
|
||||
}
|
||||
this.setData({
|
||||
showReplyInput: true,
|
||||
currentReplyId: commentData.id,
|
||||
currentReplyUsername: commentData.username || '匿名用户',
|
||||
replyContent: '',
|
||||
isSubmitDisabled: true,
|
||||
});
|
||||
}
|
||||
}, 50); // 50毫秒的延时足够
|
||||
},
|
||||
|
||||
/**
|
||||
* ✅ 核心修改:处理点击主评论入口的逻辑
|
||||
*/
|
||||
handleTapPrimaryCommentInput() {
|
||||
// 同样,先关闭
|
||||
this.closeInput();
|
||||
|
||||
// 延时后打开
|
||||
setTimeout(() => {
|
||||
this.setData({
|
||||
showReplyInput: true,
|
||||
currentReplyId: null,
|
||||
currentReplyUsername: '',
|
||||
});
|
||||
}, 50);
|
||||
},
|
||||
|
||||
/**
|
||||
* ✅ 修改:提交时智能判断是“回复”还是“新评论”
|
||||
*/
|
||||
handleReplySubmit() {
|
||||
if (this.data.isSubmitDisabled) return;
|
||||
|
||||
const { replyContent, currentReplyId, cardReviewData } = this.data;
|
||||
const articleId = cardReviewData.article_id;
|
||||
|
||||
// 根据 currentReplyId 是否有值来判断
|
||||
if (currentReplyId) {
|
||||
// --- 这是回复 ---
|
||||
console.log(`[提交回复] 内容: "${replyContent}" | 回复目标ID: ${currentReplyId} | 文章ID: ${articleId}`);
|
||||
// 在此处对接您的【回复】API
|
||||
// wx.request({ url: ..., data: { content: replyContent, parent_id: currentReplyId, article_id: articleId } })
|
||||
} else {
|
||||
// --- 这是新的一级评论 ---
|
||||
console.log(`[提交新评论] 内容: "${replyContent}" | 文章ID: ${articleId}`);
|
||||
// 在此处对接您的【发表新评论】API
|
||||
// wx.request({ url: ..., data: { content: replyContent, article_id: articleId } })
|
||||
}
|
||||
|
||||
wx.showToast({ title: '评论成功(模拟)', icon: 'success' });
|
||||
|
||||
// 提交后清空并隐藏输入框
|
||||
this.setData({
|
||||
showReplyInput: false,
|
||||
currentReplyId: null,
|
||||
currentReplyUsername: '',
|
||||
replyContent: '',
|
||||
isSubmitDisabled: true
|
||||
});
|
||||
|
||||
// (可选) 成功后可以延时刷新评论列表
|
||||
// setTimeout(() => {
|
||||
// this.getCardDetail(this.properties.id);
|
||||
// }, 1000);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 实时同步输入框内容
|
||||
*/
|
||||
|
||||
noop() {
|
||||
return;
|
||||
},
|
||||
|
||||
/**
|
||||
* 输入框失去焦点
|
||||
*/
|
||||
handleInputBlur() {
|
||||
// 目前主要靠 handleBlankTap 和 handleReplySubmit 隐藏,此函数可留空
|
||||
},
|
||||
|
||||
/**
|
||||
* 提交回复
|
||||
*/
|
||||
handleReplySubmit() {
|
||||
const { replyContent, currentReplyId } = this.data;
|
||||
if (!replyContent.trim()) {
|
||||
wx.showToast({ title: '回复内容不能为空', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[准备发送] 回复内容: "${replyContent}" | 回复目标评论ID: ${currentReplyId}`);
|
||||
|
||||
// --- 在此处对接您的后端API,发送回复请求 ---
|
||||
// wx.request({ ... });
|
||||
|
||||
wx.showToast({ title: '回复成功(模拟)', icon: 'success' });
|
||||
|
||||
this.setData({
|
||||
showReplyInput: false,
|
||||
currentReplyId: '',
|
||||
currentReplyUsername: '',
|
||||
replyContent: ''
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
onShareAppMessage: function (res) {
|
||||
// 1. 获取文评数据,添加容错(避免数据为空导致报错)
|
||||
const { cardReviewData = {} } = this.data;
|
||||
@@ -104,7 +268,6 @@ Component({
|
||||
getCardDetail(id: string) {
|
||||
console.log("正在加载文章ID:", id);
|
||||
|
||||
// 1. 验证和转换 ID
|
||||
const articleId = parseInt(id, 10);
|
||||
if (isNaN(articleId) || articleId <= 0) {
|
||||
this.setData({
|
||||
@@ -114,29 +277,32 @@ Component({
|
||||
return;
|
||||
}
|
||||
|
||||
// 开始加载,重置状态
|
||||
this.setData({ loading: true, error: null });
|
||||
|
||||
// 2. 调用获取评论的方法
|
||||
|
||||
this.getComments(articleId)
|
||||
.then(commentsData => {
|
||||
console.log("获取到commentsData:",commentsData)
|
||||
// --- ✅ 核心修复逻辑在这里 ---
|
||||
// 无论 commentsData 是有内容的数组还是空数组,都是成功状态
|
||||
|
||||
console.log("获取到 commentsData:", commentsData);
|
||||
|
||||
// *** 核心修改:计算总评论数 ***
|
||||
const totalCount = this.calculateTotalComments(commentsData);
|
||||
|
||||
console.log(`文章ID ${articleId} 评论获取成功,总评论数: ${totalCount}`);
|
||||
|
||||
this.setData({
|
||||
comments: commentsData, // 存储树形结构的数据
|
||||
totalCommentsCount: totalCount, // 存储总数
|
||||
comments: commentsData || [], // 确保 comments 是一个数组
|
||||
totalCommentsCount: totalCount,
|
||||
loading: false,
|
||||
error: null // 确保成功时,error 状态被清空
|
||||
});
|
||||
console.log(this.data.comments[0])
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(`获取评论失败: ${error.message}`);
|
||||
// 只有当 getComments promise被 reject (即网络或服务器真出错了) 才会进入这里
|
||||
console.error(`获取评论失败123: ${error.message}`);
|
||||
this.setData({
|
||||
loading: false,
|
||||
// 这里只显示真实的错误信息
|
||||
error: error.message || "获取评论失败,请检查网络"
|
||||
});
|
||||
});
|
||||
@@ -151,15 +317,25 @@ Component({
|
||||
articleId: articleId
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('[getComments] 收到服务器原始响应:', res.data);
|
||||
const response = res.data as CommentResponse;
|
||||
|
||||
if (response.success && Array.isArray(response.data)) {
|
||||
resolve(response.data as Comment[]);
|
||||
// ✅ 核心修复 1: 同时接受 data 为数组 或 data 为 null 的情况
|
||||
if (response.success && (Array.isArray(response.data) || response.data === null)) {
|
||||
console.log('[getComments] 数据校验成功, resolve 数据');
|
||||
|
||||
// ✅ 核心修复 2: 如果 data 是 null,我们将其视为空数组 [] 返回
|
||||
// 这样可以保证后续的 .then 代码接收到的永远是一个数组
|
||||
resolve(response.data || []);
|
||||
|
||||
} else {
|
||||
reject(new Error(response.message || "服务器返回数据异常"));
|
||||
// 只有当服务器明确告知失败, 或数据格式不对时, 才 reject
|
||||
console.error('[getComments] 服务器返回数据异常, reject 错误');
|
||||
reject(new Error(response.message || "服务器返回数据格式不正确"));
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('[getComments] 网络请求失败, reject 错误:', err);
|
||||
reject(new Error("网络请求失败,请检查连接"));
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user