From e37a3e79e4ab3d943060302303108e49b6a3ee31 Mon Sep 17 00:00:00 2001 From: anghunk Date: Mon, 9 Feb 2026 12:22:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E8=84=9A=E6=9C=AC=E5=B9=B6=E5=88=86=E7=A6=BB?= =?UTF-8?q?=E8=AF=84=E8=AE=BA=E7=9A=84slug=E5=92=8CURL=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增自动数据库迁移脚本,在部署前检查并更新schema - 将post_slug字段拆分为post_slug(仅路径)和post_url(完整URL) - 更新前端widget以仅使用路径作为post_slug - 修改部署脚本以在部署前自动运行迁移 --- cwd-api/package.json | 2 +- cwd-api/scripts/auto_migrate.js | 93 +++++++++++++++++++++++++++ cwd-api/src/api/public/postComment.ts | 5 +- docs/widget/src/core/CWDComments.js | 4 +- 4 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 cwd-api/scripts/auto_migrate.js diff --git a/cwd-api/package.json b/cwd-api/package.json index 23ac5df..050a5a4 100644 --- a/cwd-api/package.json +++ b/cwd-api/package.json @@ -2,7 +2,7 @@ "name": "cwd-api", "version": "0.0.18", "scripts": { - "deploy": "wrangler deploy", + "deploy": "node scripts/auto_migrate.js && wrangler deploy", "dev": "wrangler dev", "start": "wrangler dev", "test": "vitest", diff --git a/cwd-api/scripts/auto_migrate.js b/cwd-api/scripts/auto_migrate.js new file mode 100644 index 0000000..3a0f9cc --- /dev/null +++ b/cwd-api/scripts/auto_migrate.js @@ -0,0 +1,93 @@ +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +function findDatabaseName() { + const files = ['wrangler.jsonc', 'wrangler.toml']; + const baseDirs = [process.cwd(), path.resolve(__dirname, '..')]; + for (const base of baseDirs) { + for (const file of files) { + const filePath = path.join(base, file); + if (!fs.existsSync(filePath)) { + continue; + } + const content = fs.readFileSync(filePath, 'utf-8'); + if (file.endsWith('.jsonc')) { + const jsonMatch = content.match(/"database_name"\s*:\s*["'](.*?)["']/); + if (jsonMatch) { + return jsonMatch[1]; + } + } else { + const chunks = content.split('[[d1_databases]]'); + for (const chunk of chunks) { + if (chunk.includes('CWD_DB') || chunk.includes('"CWD_DB"')) { + const nameMatch = chunk.match(/database_name\s*=\s*["'](.*?)["']/); + if (nameMatch) { + return nameMatch[1]; + } + } + } + const match = content.match(/database_name\s*=\s*["'](.*?)["']/); + if (match) { + return match[1]; + } + } + } + } + return null; +} + +function run() { + try { + console.log('🔍 [Auto-Migrate] Detecting D1 database...'); + const dbName = findDatabaseName(); + if (!dbName) { + console.warn('⚠️ [Auto-Migrate] Could not detect database_name from wrangler config. Skipping.'); + return; + } + console.log(`✅ [Auto-Migrate] Found database: ${dbName}`); + + console.log('🔍 [Auto-Migrate] Checking schema status...'); + try { + // Check if post_url column exists + const checkCmd = `npx wrangler d1 execute ${dbName} --command "SELECT count(*) as count FROM pragma_table_info('Comment') WHERE name='post_url'" --remote --json`; + const output = execSync(checkCmd, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }); + + const result = JSON.parse(output); + const count = result[0]?.results?.[0]?.count; + + if (count > 0) { + console.log('✅ [Auto-Migrate] Schema is up to date.'); + return; + } + } catch (e) { + console.warn('⚠️ [Auto-Migrate] Check failed (Database might be new or network error). Skipping migration to be safe.'); + console.warn(e.message); + return; + } + + console.log('🚀 [Auto-Migrate] Applying migration...'); + const sql = ` + ALTER TABLE Comment ADD COLUMN post_url TEXT; + UPDATE Comment SET post_url = post_slug; + UPDATE Comment + SET post_slug = SUBSTR( + REPLACE(REPLACE(post_slug, 'https://', ''), 'http://', ''), + INSTR(REPLACE(REPLACE(post_slug, 'https://', ''), 'http://', ''), '/') + ) + WHERE post_slug LIKE 'http%' AND INSTR(REPLACE(REPLACE(post_slug, 'https://', ''), 'http://', ''), '/') > 0; + `; + + const flatSql = sql.replace(/\s+/g, ' ').trim(); + const migrateCmd = `npx wrangler d1 execute ${dbName} --command "${flatSql}" --remote --yes`; + + execSync(migrateCmd, { stdio: 'inherit' }); + console.log('✅ [Auto-Migrate] Completed successfully.'); + + } catch (error) { + console.error('❌ [Auto-Migrate] Failed:', error.message); + process.exit(1); + } +} + +run(); diff --git a/cwd-api/src/api/public/postComment.ts b/cwd-api/src/api/public/postComment.ts index efccce3..af38224 100644 --- a/cwd-api/src/api/public/postComment.ts +++ b/cwd-api/src/api/public/postComment.ts @@ -159,13 +159,14 @@ export const postComment = async (c: Context<{ Bindings: Bindings }>) => { try { const result = await c.env.CWD_DB.prepare(` INSERT INTO Comment ( - created, post_slug, name, email, url, ip_address, + created, post_slug, post_url, name, email, url, ip_address, os, browser, device, ua, content_text, content_html, parent_id, status - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `).bind( Date.now(), post_slug, + post_url || null, name, email, url || null, diff --git a/docs/widget/src/core/CWDComments.js b/docs/widget/src/core/CWDComments.js index e02956a..843b576 100644 --- a/docs/widget/src/core/CWDComments.js +++ b/docs/widget/src/core/CWDComments.js @@ -30,7 +30,7 @@ export class CWDComments { constructor(config) { this.config = { ...config }; if (typeof window !== 'undefined') { - this.config.postSlug = window.location.origin + window.location.pathname; + this.config.postSlug = window.location.pathname; } if (typeof document !== 'undefined') { this.config.postTitle = document.title || this.config.postSlug; @@ -572,7 +572,7 @@ export class CWDComments { Object.assign(this.config, newConfig); if (typeof window !== 'undefined') { - this.config.postSlug = window.location.origin + window.location.pathname; + this.config.postSlug = window.location.pathname; } if (typeof document !== 'undefined') { this.config.postTitle = document.title || this.config.postSlug;