feat(community): 评论改为独立二级页面 + 评论内容安全审核 + 评论数按实发实时纠正
前端: - 新增 pages/comments 独立评论页(列表 + 底部输入条 + 回复),社区卡片点评论改为 navigateTo - 输入条用普通流式布局 + 原生 adjust-position 做键盘避让,聚焦期间不 setData 碰输入框 - 评论只能配 1 张图;底部常驻「审核后公开」提示;发送按钮在途「审核中…」防连点 - 发布结果按状态区分:过审即时展示,其余提示「已提交,审核通过后展示」 - 评论页把已发布评论数回传社区列表,卡片数字实时更新 后端: - CreateComment 文本判为违规时直接拒收(ErrContentRejected),不入库 - 社区列表/用户帖子列表用「已发布评论实时条数」覆盖 comment_count, 修正异步过审/删待审/后台改状态导致的计数漂移 - IDCard 手机号返回完整号码(上一批遗留) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -82,6 +82,7 @@ Component({
|
||||
replyTo: {},
|
||||
cmFocus: false,
|
||||
composing: false, // 评论输入面板是否展开(收起时只是一条细条)
|
||||
sendingComment: false, // 发送+审核在途,防连点
|
||||
kbHeight: 0,
|
||||
total: 0,
|
||||
},
|
||||
@@ -120,6 +121,7 @@ Component({
|
||||
patch.replyTo = {};
|
||||
patch.cmFocus = false;
|
||||
patch.composing = false;
|
||||
patch.sendingComment = false;
|
||||
patch.kbHeight = 0;
|
||||
patch.saving = false;
|
||||
}
|
||||
@@ -655,32 +657,49 @@ Component({
|
||||
|
||||
// 评论
|
||||
async onSendComment() {
|
||||
if (this.data.sendingComment) return; // 防连点:审核请求在途时忽略后续点击
|
||||
const text = (this.data.commentText || '').trim();
|
||||
// 原来空评论会直接把弹层关掉,看起来像发成功了。改成明确提示
|
||||
if (!text) return wx.showToast({ title: '写点什么再发', icon: 'none' });
|
||||
if (!this.data.postId) return this.close();
|
||||
this.setData({ sendingComment: true });
|
||||
wx.showLoading({ title: '审核中…', mask: true });
|
||||
try {
|
||||
await api.createComment(
|
||||
const res = await api.createComment(
|
||||
this.data.postId,
|
||||
text,
|
||||
this.data.commentImages.map((i) => i.url),
|
||||
this.data.replyTo.id || '',
|
||||
);
|
||||
this.setData({ commentText: '', commentImages: [], replyTo: {}, composing: false, cmFocus: false });
|
||||
this.loadComments();
|
||||
this.triggerEvent('commented');
|
||||
wx.hideLoading();
|
||||
this.setData({
|
||||
commentText: '', commentImages: [], replyTo: {},
|
||||
composing: false, cmFocus: false, kbHeight: 0, sendingComment: false,
|
||||
});
|
||||
// 过审即时展示;否则挂在人工/异步图片审核,通过后才出现
|
||||
if (res && res.status === 'published') {
|
||||
this.loadComments();
|
||||
this.triggerEvent('commented');
|
||||
wx.showToast({ title: '评论成功', icon: 'success' });
|
||||
} else {
|
||||
wx.showToast({ title: '已提交,审核通过后展示', icon: 'none' });
|
||||
}
|
||||
} catch (e) {
|
||||
wx.showToast({ title: e.message || '评论失败', icon: 'none' });
|
||||
wx.hideLoading();
|
||||
this.setData({ sendingComment: false });
|
||||
// 违规内容后端直接拒收,这里把原因透出来
|
||||
wx.showToast({ title: (e && e.message) || '评论失败', icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
// 评论配图,最多 3 张
|
||||
// 评论配图:只允许 1 张
|
||||
onPickCommentImages() {
|
||||
const left = 3 - this.data.commentImages.length;
|
||||
if (left <= 0) return wx.showToast({ title: '最多 3 张', icon: 'none' });
|
||||
if (this.data.commentImages.length >= 1) {
|
||||
return wx.showToast({ title: '评论只能配 1 张图', icon: 'none' });
|
||||
}
|
||||
upload
|
||||
.chooseAndUploadImages(left)
|
||||
.then((files) => this.setData({ commentImages: this.data.commentImages.concat(files) }))
|
||||
.chooseAndUploadImages(1)
|
||||
.then((files) => this.setData({ commentImages: (files || []).slice(0, 1) }))
|
||||
.catch((e) => {
|
||||
if (e && e.canceled) return;
|
||||
wx.showToast({ title: (e && e.message) || '上传失败', icon: 'none' });
|
||||
@@ -692,27 +711,21 @@ Component({
|
||||
onReplyTo(e) {
|
||||
const { id, name } = e.currentTarget.dataset;
|
||||
if (!id) return;
|
||||
// 点任意评论直接展开面板并预填回复对象
|
||||
this.setData({ replyTo: { id, name }, composing: true, cmFocus: true });
|
||||
// 输入框常驻、属性不变,直接置 focus 拉键盘即可;只填「回复对象」这一个横幅
|
||||
this.setData({ replyTo: { id, name }, cmFocus: true });
|
||||
},
|
||||
// 点细条:展开大输入面板并聚焦(拉起键盘)
|
||||
onStartCompose() {
|
||||
this.setData({ composing: true, cmFocus: true });
|
||||
onCommentFocus() {
|
||||
// 只复位一次性 focus 开关。键盘高度交给 onKbChange,用 transform 平移弹层来避让
|
||||
this.setData({ cmFocus: false });
|
||||
},
|
||||
// 收起面板,草稿(文字/图片)留着,下次点开接着写
|
||||
onCloseCompose() {
|
||||
this.setData({ composing: false, cmFocus: false, kbHeight: 0 });
|
||||
},
|
||||
onCommentFocus(e) {
|
||||
// adjust-position=false,键盘高度自己接管:弹层是 fixed 定位,
|
||||
// 交给系统顶会把整块推出屏幕
|
||||
// 键盘高度变化(真机可靠来源)。把高度写进 data,
|
||||
// wxml 里只用它算 transform 平移量 —— 纯合成层操作,不 reflow、不抖焦点
|
||||
onKbChange(e) {
|
||||
this.setData({ kbHeight: (e.detail && e.detail.height) || 0 });
|
||||
},
|
||||
onCommentBlur() {
|
||||
// 失焦先放下键盘。有草稿就保持展开(否则点「发送」会因面板收起而丢掉这一下点击);
|
||||
// 空内容才收回细条
|
||||
const empty = !(this.data.commentText || '').trim() && !this.data.commentImages.length;
|
||||
this.setData({ kbHeight: 0, cmFocus: false, composing: empty ? false : this.data.composing });
|
||||
// 失焦不主动清 kbHeight:键盘真正收起时 onKbChange 会回调 0,避免和收键盘动画抢
|
||||
this.setData({ cmFocus: false });
|
||||
},
|
||||
onCancelReply() {
|
||||
this.setData({ replyTo: {} });
|
||||
|
||||
Reference in New Issue
Block a user