import crypto from 'node:crypto'; export async function ensureWordFilterSchema(pool) { await pool.query(` CREATE TABLE IF NOT EXISTS h5_blocked_words ( id CHAR(36) PRIMARY KEY, word VARCHAR(200) NOT NULL, replacement VARCHAR(200) NOT NULL DEFAULT '***', note VARCHAR(500) NULL, status ENUM('active', 'disabled') NOT NULL DEFAULT 'active', created_at BIGINT NOT NULL, updated_at BIGINT NOT NULL, UNIQUE KEY uk_blocked_word (word) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci `); } export function createWordFilterService(pool) { async function listBlockedWords() { const [rows] = await pool.query( 'SELECT id, word, replacement, note, status, created_at, updated_at FROM h5_blocked_words ORDER BY created_at DESC', ); return rows; } async function createBlockedWord({ word, replacement, note }) { const trimmed = String(word ?? '').trim(); if (!trimmed) return { ok: false, message: '词语不能为空' }; const id = crypto.randomUUID(); const now = Date.now(); try { await pool.query( 'INSERT INTO h5_blocked_words (id, word, replacement, note, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)', [id, trimmed, replacement ?? '***', note ?? '', 'active', now, now], ); const [rows] = await pool.query('SELECT * FROM h5_blocked_words WHERE id = ?', [id]); return { ok: true, blockedWord: rows[0] }; } catch (err) { if (err?.code === 'ER_DUP_ENTRY') return { ok: false, message: '该词语已存在' }; throw err; } } async function updateBlockedWord(id, { word, replacement, note, status }) { const updates = []; const values = []; if (word !== undefined) { const trimmed = String(word).trim(); if (!trimmed) return { ok: false, message: '词语不能为空' }; updates.push('word = ?'); values.push(trimmed); } if (replacement !== undefined) { updates.push('replacement = ?'); values.push(replacement); } if (note !== undefined) { updates.push('note = ?'); values.push(note); } if (status !== undefined) { updates.push('status = ?'); values.push(status); } if (!updates.length) return { ok: false, message: '没有可更新的字段' }; updates.push('updated_at = ?'); values.push(Date.now(), id); const [result] = await pool.query( `UPDATE h5_blocked_words SET ${updates.join(', ')} WHERE id = ?`, values, ); if (!result.affectedRows) return { ok: false, message: '记录不存在' }; const [rows] = await pool.query('SELECT * FROM h5_blocked_words WHERE id = ?', [id]); return { ok: true, blockedWord: rows[0] }; } async function deleteBlockedWord(id) { const [result] = await pool.query('DELETE FROM h5_blocked_words WHERE id = ?', [id]); if (!result.affectedRows) return { ok: false, message: '记录不存在' }; return { ok: true }; } async function listAllForFrontend() { const [rows] = await pool.query( 'SELECT word, replacement FROM h5_blocked_words WHERE status = ? ORDER BY word', ['active'], ); return rows; } return { listBlockedWords, createBlockedWord, updateBlockedWord, deleteBlockedWord, listAllForFrontend }; }