refactor(comment): 统一字段命名并改用时间戳存储创建时间

将 author 字段重命名为 name,pub_date 改为 created 并使用时间戳存储
更新相关 API、数据库 schema 和前端组件以适配新字段
同时将 user_agent 简化为 ua 并改进日期处理逻辑
This commit is contained in:
anghunk
2026-01-20 13:50:08 +08:00
parent 520cfcc447
commit eb0a7a32aa
15 changed files with 112 additions and 99 deletions

View File

@@ -25,7 +25,7 @@ export class CommentForm extends Component {
const { formErrors, submitting } = this.props;
const { localForm } = this.state;
const canSubmit = localForm.author.trim() && localForm.email.trim() && localForm.content.trim();
const canSubmit = localForm.name.trim() && localForm.email.trim() && localForm.content.trim();
const root = this.createElement('form', {
className: 'cwd-comment-form',
@@ -46,7 +46,7 @@ export class CommentForm extends Component {
className: 'cwd-form-row',
children: [
// 昵称
this.createFormField('昵称 *', 'text', 'author', localForm.author, formErrors.author),
this.createFormField('昵称 *', 'text', 'name', localForm.name, formErrors.name),
// 邮箱
this.createFormField('邮箱 *', 'email', 'email', localForm.email, formErrors.email),
// 网址
@@ -103,13 +103,13 @@ export class CommentForm extends Component {
// 只在非提交状态时同步表单数据(避免覆盖用户正在输入的内容)
if (!this.props.submitting && this.props.form !== prevProps.form) {
// 保留当前正在输入的内容
const currentAuthor = this.state.localForm.author || '';
const currentName = this.state.localForm.name || '';
const currentEmail = this.state.localForm.email || '';
const currentUrl = this.state.localForm.url || '';
const currentContent = this.state.localForm.content || '';
this.state.localForm = {
author: this.props.form.author || currentAuthor,
name: this.props.form.name || currentName,
email: this.props.form.email || currentEmail,
url: this.props.form.url || currentUrl,
content: this.props.form.content !== undefined ? this.props.form.content : currentContent,
@@ -134,7 +134,7 @@ export class CommentForm extends Component {
const { formErrors, submitting } = this.props;
const { localForm } = this.state;
const canSubmit = localForm.author.trim() && localForm.email.trim() && localForm.content.trim();
const canSubmit = localForm.name.trim() && localForm.email.trim() && localForm.content.trim();
// 更新提交按钮状态
const submitBtn = this.elements.root.querySelector('button[type="submit"]');
@@ -159,8 +159,8 @@ export class CommentForm extends Component {
updateErrors(formErrors) {
if (!this.elements.root) return;
const authorInput = this.elements.root.querySelector('input[name="author"]');
this.updateFieldError(authorInput, formErrors?.author);
const nameInput = this.elements.root.querySelector('input[name="name"]');
this.updateFieldError(nameInput, formErrors?.name);
const emailInput = this.elements.root.querySelector('input[name="email"]');
this.updateFieldError(emailInput, formErrors?.email);
@@ -227,12 +227,12 @@ export class CommentForm extends Component {
* 设置输入框的值
*/
setInputValues(root, form) {
const authorInput = root.querySelector('input[name="author"]');
const nameInput = root.querySelector('input[name="name"]');
const emailInput = root.querySelector('input[name="email"]');
const urlInput = root.querySelector('input[name="url"]');
const contentTextarea = root.querySelector('textarea');
if (authorInput) authorInput.value = form.author || '';
if (nameInput) nameInput.value = form.name || '';
if (emailInput) emailInput.value = form.email || '';
if (urlInput) urlInput.value = form.url || '';
if (contentTextarea) contentTextarea.value = form.content || '';

View File

@@ -45,7 +45,7 @@ export class CommentItem extends Component {
this.createElement('img', {
attributes: {
src: comment.avatar,
alt: comment.author,
alt: comment.name,
loading: 'lazy'
}
})
@@ -74,11 +74,11 @@ export class CommentItem extends Component {
target: '_blank',
rel: 'noopener noreferrer'
},
text: comment.author
text: comment.name
})
]
})
: this.createTextElement('span', comment.author, 'cwd-author-name'),
: this.createTextElement('span', comment.name, 'cwd-author-name'),
// 博主标识
...(isAdmin ? [
this.createTextElement('span', `${adminBadge}`, 'cwd-admin-badge')
@@ -102,7 +102,7 @@ export class CommentItem extends Component {
},
text: '回复'
}),
this.createTextElement('span', formatRelativeTime(comment.pubDate), 'cwd-comment-time')
this.createTextElement('span', formatRelativeTime(comment.created), 'cwd-comment-time')
]
})
]
@@ -140,7 +140,7 @@ export class CommentItem extends Component {
const replyContainer = root.querySelector('.cwd-reply-editor-container');
if (replyContainer) {
this.replyEditor = new ReplyEditor(replyContainer, {
replyToAuthor: comment.author,
replyToAuthor: comment.name,
content: this.props.replyContent,
error: this.props.replyError,
submitting: this.props.submitting,
@@ -212,7 +212,7 @@ export class CommentItem extends Component {
if (isReplying && replyContainer) {
// 显示回复编辑器
this.replyEditor = new ReplyEditor(replyContainer, {
replyToAuthor: comment.author,
replyToAuthor: comment.name,
content: this.props.replyContent,
error: this.props.replyError,
submitting: this.props.submitting,

View File

@@ -39,7 +39,7 @@ export function createApiClient(config) {
/**
* 提交评论
* @param {Object} data - 评论数据
* @param {string} data.author - 昵称
* @param {string} data.name - 昵称
* @param {string} data.email - 邮箱
* @param {string} data.url - 网址(可选)
* @param {string} data.content - 评论内容
@@ -56,7 +56,7 @@ export function createApiClient(config) {
post_slug: config.postSlug,
post_title: config.postTitle,
post_url: config.postUrl,
author: data.author,
name: data.name,
email: data.email,
url: data.url || undefined,
content: data.content,

View File

@@ -15,7 +15,7 @@ function loadUserInfo() {
if (data) {
const parsed = JSON.parse(data);
return {
author: parsed.author || '',
name: parsed.name || '',
email: parsed.email || '',
url: parsed.url || ''
};
@@ -23,18 +23,18 @@ function loadUserInfo() {
} catch (e) {
console.error('读取用户信息失败:', e);
}
return { author: '', email: '', url: '' };
return { name: '', email: '', url: '' };
}
/**
* 保存用户信息到 localStorage
* @param {string} author - 昵称
* @param {string} name - 昵称
* @param {string} email - 邮箱
* @param {string} url - 网址
*/
function saveUserInfo(author, email, url) {
function saveUserInfo(name, email, url) {
try {
const data = { author, email, url };
const data = { name, email, url };
localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
} catch (e) {
console.error('保存用户信息失败:', e);
@@ -115,7 +115,7 @@ export function createCommentStore(config, fetchComments, submitComment) {
// 表单数据
form: {
author: savedInfo.author || '',
name: savedInfo.name || '',
email: savedInfo.email || '',
url: savedInfo.url || '',
content: ''
@@ -131,8 +131,8 @@ export function createCommentStore(config, fetchComments, submitComment) {
// 监听用户信息变化,自动保存到 localStorage
store.subscribe((state) => {
if (state.form.author || state.form.email || state.form.url) {
saveUserInfo(state.form.author, state.form.email, state.form.url);
if (state.form.name || state.form.email || state.form.url) {
saveUserInfo(state.form.name, state.form.email, state.form.url);
}
});
@@ -194,7 +194,7 @@ export function createCommentStore(config, fetchComments, submitComment) {
try {
await submitComment({
author: form.author,
name: form.name,
email: form.email,
url: form.url,
content: form.content
@@ -249,7 +249,7 @@ export function createCommentStore(config, fetchComments, submitComment) {
try {
await submitComment({
author: state.form.author,
name: state.form.name,
email: state.form.email,
url: state.form.url,
content: state.replyContent,

View File

@@ -4,11 +4,11 @@
/**
* 格式化时间3天内显示相对时间超过3天显示完整日期
* @param {string} dateStr - 日期字符串
* @param {string|number} dateValue - 日期字符串或时间戳
* @returns {string}
*/
export function formatRelativeTime(dateStr) {
const date = new Date(dateStr);
export function formatRelativeTime(dateValue) {
const date = new Date(dateValue);
const now = new Date();
const diff = now.getTime() - date.getTime();
@@ -32,16 +32,16 @@ export function formatRelativeTime(dateStr) {
}
// 超过3天显示完整日期
return formatDateTime(dateStr);
return formatDateTime(dateValue);
}
/**
* 格式化日期时间
* @param {string} dateStr - 日期字符串
* @param {string|number} dateValue - 日期字符串或时间戳
* @returns {string}
*/
export function formatDateTime(dateStr) {
const date = new Date(dateStr);
export function formatDateTime(dateValue) {
const date = new Date(dateValue);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
@@ -53,11 +53,11 @@ export function formatDateTime(dateStr) {
/**
* 格式化日期
* @param {string} dateStr - 日期字符串
* @param {string|number} dateValue - 日期字符串或时间戳
* @returns {string}
*/
export function formatDate(dateStr) {
const date = new Date(dateStr);
export function formatDate(dateValue) {
const date = new Date(dateValue);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
@@ -66,11 +66,11 @@ export function formatDate(dateStr) {
/**
* 格式化时间
* @param {string} dateStr - 日期字符串
* @param {string|number} dateValue - 日期字符串或时间戳
* @returns {string}
*/
export function formatTime(dateStr) {
const date = new Date(dateStr);
export function formatTime(dateValue) {
const date = new Date(dateValue);
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');

View File

@@ -45,7 +45,7 @@ export function validateCommentContent(content) {
/**
* 验证评论表单
* @param {Object} data - 表单数据
* @param {string} data.author - 昵称
* @param {string} data.name - 昵称
* @param {string} data.email - 邮箱
* @param {string} data.url - 网址
* @param {string} data.content - 评论内容
@@ -55,10 +55,10 @@ export function validateCommentForm(data) {
const errors = {};
// 验证昵称
if (!data.author || data.author.trim().length === 0) {
errors.author = '请输入昵称';
} else if (data.author.length > 50) {
errors.author = '昵称不能超过 50 字';
if (!data.name || data.name.trim().length === 0) {
errors.name = '请输入昵称';
} else if (data.name.length > 50) {
errors.name = '昵称不能超过 50 字';
}
// 验证邮箱
@@ -88,7 +88,7 @@ export function validateCommentForm(data) {
/**
* 验证回复所需的用户信息
* @param {Object} data - 用户信息
* @param {string} data.author - 昵称
* @param {string} data.name - 昵称
* @param {string} data.email - 邮箱
* @param {string} data.url - 网址
* @returns {{valid: boolean, errors: Object<string, string>}}
@@ -97,10 +97,10 @@ export function validateReplyUserInfo(data) {
const errors = {};
// 验证昵称
if (!data.author || data.author.trim().length === 0) {
errors.author = '请输入昵称';
} else if (data.author.length > 50) {
errors.author = '昵称不能超过 50 字';
if (!data.name || data.name.trim().length === 0) {
errors.name = '请输入昵称';
} else if (data.name.length > 50) {
errors.name = '昵称不能超过 50 字';
}
// 验证邮箱