- 后台全面引入 Naive UI 组件库,统一 UI 规范 - 前台 usePublicApi 切换到 API 调用(GET /api/content/[key]) - 前后台数据源统一(site_content 表) - 产品线统一管理(tour/camp/course 三套编辑器) - 产品数据归一化(itinerary/faq/pricing 格式统一) - 表单提交 API 改写入 submissions 表 - 新增 submissions 标记已读 API - site-content PUT 支持 upsert - 修复前台 bug(stories 路由冲突、占位符警告、selector breadcrumb) - 消除 PageHero 类型警告(useSEO reactive 修复) - 25 个前台页面全部 HTTP 200,展示效果不变 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
129 行
3.2 KiB
JavaScript
129 行
3.2 KiB
JavaScript
/**
|
|
* 数据库初始化脚本
|
|
* 运行: node server/database/migrate.js
|
|
*
|
|
* 创建所有表(如果不存在)
|
|
*/
|
|
import Database from 'better-sqlite3'
|
|
import { join } from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
import { dirname } from 'path'
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
const DB_PATH = join(__dirname, 'hulai.db')
|
|
|
|
const db = new Database(DB_PATH)
|
|
db.pragma('journal_mode = WAL')
|
|
db.pragma('foreign_keys = ON')
|
|
|
|
// ── 建表 SQL ────────────────────────────────────────
|
|
const tables = `
|
|
CREATE TABLE IF NOT EXISTS admin_users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
username TEXT NOT NULL UNIQUE,
|
|
password_hash TEXT NOT NULL,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS articles (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
slug TEXT NOT NULL UNIQUE,
|
|
title TEXT NOT NULL,
|
|
summary TEXT,
|
|
content TEXT,
|
|
category TEXT,
|
|
type TEXT NOT NULL DEFAULT 'news',
|
|
cover_image TEXT,
|
|
author TEXT,
|
|
tags TEXT,
|
|
seo_title TEXT,
|
|
seo_description TEXT,
|
|
seo_keywords TEXT,
|
|
published INTEGER DEFAULT 1,
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS reviews (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
author TEXT NOT NULL,
|
|
rating INTEGER DEFAULT 5,
|
|
title TEXT,
|
|
content TEXT,
|
|
date TEXT,
|
|
verified INTEGER DEFAULT 0,
|
|
published INTEGER DEFAULT 1,
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS faqs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
question TEXT NOT NULL,
|
|
answer TEXT NOT NULL,
|
|
sort_order INTEGER DEFAULT 0,
|
|
published INTEGER DEFAULT 1
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS gallery_items (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
title TEXT NOT NULL,
|
|
category TEXT,
|
|
location TEXT,
|
|
description TEXT,
|
|
image TEXT NOT NULL,
|
|
orientation TEXT,
|
|
published INTEGER DEFAULT 1,
|
|
sort_order INTEGER DEFAULT 0
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS stories (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
slug TEXT NOT NULL UNIQUE,
|
|
title TEXT NOT NULL,
|
|
subtitle TEXT,
|
|
family_type TEXT,
|
|
children_age TEXT,
|
|
from_city TEXT,
|
|
trip_product TEXT,
|
|
travel_date TEXT,
|
|
cover_image TEXT,
|
|
sections TEXT,
|
|
key_moments TEXT,
|
|
seo_title TEXT,
|
|
seo_description TEXT,
|
|
published INTEGER DEFAULT 1,
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS submissions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
type TEXT NOT NULL,
|
|
data TEXT NOT NULL,
|
|
ip TEXT,
|
|
read INTEGER DEFAULT 0,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS site_content (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
key TEXT NOT NULL UNIQUE,
|
|
label TEXT NOT NULL,
|
|
data TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
token TEXT PRIMARY KEY,
|
|
user_id INTEGER NOT NULL,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
`
|
|
|
|
db.exec(tables)
|
|
console.log('✅ 数据库表创建完成:', DB_PATH)
|
|
|
|
db.close()
|