feat: 添加多站点支持,引入site_id字段

- 在Comment表中添加site_id字段,用于区分不同站点的评论
- 更新前后端API以支持site_id参数传递
- 修改自动迁移脚本,添加site_id字段迁移逻辑
- 更新前端组件配置,支持设置siteId参数
This commit is contained in:
anghunk
2026-02-09 13:56:35 +08:00
parent 5948949400
commit 32603d281a
8 changed files with 86 additions and 27 deletions

View File

@@ -12,6 +12,8 @@ export const listComments = async (c: Context<{ Bindings: Bindings }>) => {
const rawDomain = c.req.query('domain') || '';
const domain = rawDomain.trim();
const rawSiteId = c.req.query('site_id') || '';
const siteId = rawSiteId.trim();
let whereSql = '';
const params: (string | number)[] = [];
@@ -21,6 +23,15 @@ export const listComments = async (c: Context<{ Bindings: Bindings }>) => {
params.push(pattern, pattern);
}
if (siteId) {
if (whereSql) {
whereSql += ' AND site_id = ?';
} else {
whereSql = 'WHERE site_id = ?';
}
params.push(siteId);
}
const totalCount = await c.env.CWD_DB.prepare(
`SELECT COUNT(*) as count FROM Comment ${whereSql}`
)
@@ -67,7 +78,8 @@ export const listComments = async (c: Context<{ Bindings: Bindings }>) => {
: 0,
ua: row.ua,
avatar: await getCravatar(row.email, row.name, avatarPrefix || undefined),
isAdmin: adminEmail && row.email === adminEmail
isAdmin: adminEmail && row.email === adminEmail,
siteId: row.site_id
}))
);

View File

@@ -9,6 +9,7 @@ export const getComments = async (c: Context<{ Bindings: Bindings }>) => {
const limit = Math.min(parseInt(c.req.query('limit') || '20'), 50)
const nested = c.req.query('nested') !== 'false'
const avatar_prefix = c.req.query('avatar_prefix')
const siteId = c.req.query('site_id')
const offset = (page - 1) * limit
if (!postSlug) return c.json({ message: "post_slug is required" }, 400)
@@ -54,15 +55,23 @@ export const getComments = async (c: Context<{ Bindings: Bindings }>) => {
whereParts.length > 0
? `status = "approved" AND (${whereParts.join(' OR ')})`
: 'status = "approved"'
let finalWhereClause = whereClause
const bindParams: unknown[] = [...equalSlugs, ...likePatterns]
if (siteId) {
finalWhereClause += ' AND site_id = ?'
bindParams.push(siteId)
}
const query = `
SELECT id, name, email, url, content_text as contentText,
content_html as contentHtml, created, parent_id as parentId,
post_slug as postSlug, post_url as postUrl, priority, COALESCE(likes, 0) as likes
FROM Comment
WHERE ${whereClause}
WHERE ${finalWhereClause}
ORDER BY priority DESC, created DESC
`
const bindParams: unknown[] = [...equalSlugs, ...likePatterns]
const [commentsResult, adminEmailRows] = await Promise.all([
c.env.CWD_DB.prepare(query).bind(...bindParams).all(),

View File

@@ -24,6 +24,7 @@ export const postComment = async (c: Context<{ Bindings: Bindings }>) => {
return c.json({ message: '无效的请求体' }, 400);
}
const { post_slug, content: rawContent, name: rawName, email, url, post_title, post_url, adminToken } = data;
const site_id = data.site_id ? String(data.site_id).trim() : "";
const parentId = (data as any).parent_id ?? (data as any).parentId ?? null;
if (!post_slug || typeof post_slug !== 'string') {
return c.json({ message: 'post_slug 必填' }, 400);
@@ -161,8 +162,8 @@ export const postComment = async (c: Context<{ Bindings: Bindings }>) => {
INSERT INTO Comment (
created, post_slug, post_url, name, email, url, ip_address,
os, browser, device, ua, content_text, content_html,
parent_id, status
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
parent_id, status, site_id
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`).bind(
Date.now(),
post_slug,
@@ -178,7 +179,8 @@ export const postComment = async (c: Context<{ Bindings: Bindings }>) => {
contentText,
contentHtml,
parentId || null,
defaultStatus
defaultStatus,
site_id
).run();
if (!result.success) throw new Error("Database insert failed");