feat(评论系统): 新增评论审核功能及界面优化

实现新评论需审核后显示的功能,包括后台设置开关、API支持、前端状态提示
优化管理后台界面样式和分页组件
添加成功消息提示组件及样式
更新相关文档说明
This commit is contained in:
anghunk
2026-01-20 22:02:46 +08:00
parent 2456adcfbb
commit 6a9d5c1167
13 changed files with 161 additions and 27 deletions

View File

@@ -157,6 +157,9 @@ export class CWDComments {
if (serverConfig.adminEnabled && serverConfig.adminBadge) {
this.config.adminBadge = serverConfig.adminBadge;
}
if (typeof serverConfig.requireReview === 'boolean') {
this.config.requireReview = serverConfig.requireReview;
}
const api = createApiClient(this.config);
this.api = api;
@@ -256,6 +259,29 @@ export class CWDComments {
existingError.remove();
}
const existingSuccess = this.mountPoint.querySelector('.cwd-success-inline');
if (state.successMessage) {
if (!existingSuccess) {
const successEl = document.createElement('div');
successEl.className = 'cwd-success-inline';
successEl.innerHTML = `
<span>${state.successMessage}</span>
<button type="button" class="cwd-error-close" data-action="clear-success">✕</button>
`;
successEl.querySelector('[data-action="clear-success"]').addEventListener('click', () => {
this.store.clearSuccess();
});
this.mountPoint.insertBefore(successEl, this.mountPoint.firstChild);
} else {
const span = existingSuccess.querySelector('span');
if (span) {
span.textContent = state.successMessage;
}
}
} else if (existingSuccess) {
existingSuccess.remove();
}
// 创建头部统计
let header = this.mountPoint.querySelector('.cwd-comments-header');
if (!header) {
@@ -352,6 +378,29 @@ export class CWDComments {
existingError.remove();
}
const existingSuccess = this.mountPoint?.querySelector('.cwd-success-inline');
if (state.successMessage) {
if (!existingSuccess) {
const successEl = document.createElement('div');
successEl.className = 'cwd-success-inline';
successEl.innerHTML = `
<span>${state.successMessage}</span>
<button type="button" class="cwd-error-close" data-action="clear-success">✕</button>
`;
successEl.querySelector('[data-action="clear-success"]').addEventListener('click', () => {
this.store.clearSuccess();
});
this.mountPoint?.insertBefore(successEl, this.mountPoint.firstChild);
} else {
const span = existingSuccess.querySelector('span');
if (span) {
span.textContent = state.successMessage;
}
}
} else if (existingSuccess) {
existingSuccess.remove();
}
// 更新头部统计
const header = this.mountPoint?.querySelector('.cwd-comments-header');
const countEl = header?.querySelector('.cwd-comments-count-number');

View File

@@ -102,6 +102,7 @@ export function createCommentStore(config, fetchComments, submitComment) {
comments: [],
loading: true,
error: null,
successMessage: '',
// 分页
pagination: {
@@ -186,6 +187,7 @@ export function createCommentStore(config, fetchComments, submitComment) {
formErrors: {},
submitting: true,
error: null,
successMessage: '',
});
try {
@@ -197,10 +199,14 @@ export function createCommentStore(config, fetchComments, submitComment) {
adminToken: auth.getToken() // Add token if exists
});
// 清空评论内容
const successMessage = config.requireReview
? '已提交评论,待管理员审核后显示'
: '评论已提交';
store.setState({
form: { ...form, content: '' },
submitting: false,
successMessage,
});
// 重新加载评论
@@ -210,6 +216,7 @@ export function createCommentStore(config, fetchComments, submitComment) {
store.setState({
error: e instanceof Error ? e.message : '提交评论失败',
submitting: false,
successMessage: '',
});
return false;
}
@@ -335,6 +342,12 @@ export function createCommentStore(config, fetchComments, submitComment) {
});
}
function clearSuccess() {
store.setState({
successMessage: '',
});
}
/**
* 切换页码
* @param {number} page - 页码
@@ -366,6 +379,7 @@ export function createCommentStore(config, fetchComments, submitComment) {
updateReplyContent,
clearReplyError,
clearError,
clearSuccess,
goToPage,
};
}

View File

@@ -298,7 +298,6 @@
width: 40px;
height: 40px;
border-radius: 5px;
border: 1px solid var(--cwd-border, #d0d7de);
overflow: hidden;
background: var(--cwd-bg-avatar, #f6f8fa)
}
@@ -660,6 +659,19 @@
background: rgba(0, 0, 0, 0.1);
}
.cwd-success-inline {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
margin-bottom: 16px;
font-size: 14px;
color: #1a7f37;
background: #dafbe1;
border: 1px solid #54ae65;
border-radius: var(--cwd-radius, 6px);
}
/* ========== 其他 ========== */
.cwd-load-more {
display: block;
@@ -824,4 +836,4 @@
.cwd-btn-text:hover {
color: var(--cwd-primary);
}
}