119 行
6.0 KiB
JavaScript
119 行
6.0 KiB
JavaScript
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'
|
||
|
||
// ── 管理员 ──────────────────────────────────────────
|
||
export const adminUsers = sqliteTable('admin_users', {
|
||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||
username: text('username').notNull().unique(),
|
||
// 存储 hash 后的密码
|
||
passwordHash: text('password_hash').notNull(),
|
||
createdAt: text('created_at').notNull().$defaultFn(() => new Date().toISOString()),
|
||
})
|
||
|
||
// ── 新闻/公告 ────────────────────────────────────────
|
||
export const articles = sqliteTable('articles', {
|
||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||
slug: text('slug').notNull().unique(),
|
||
title: text('title').notNull(),
|
||
summary: text('summary'),
|
||
content: text('content'), // HTML 或 Markdown
|
||
category: text('category'), // 产品 / 公告 / 活动 / 攻略 / 亲子
|
||
type: text('type').notNull(), // news / blog
|
||
coverImage: text('cover_image'),
|
||
author: text('author'),
|
||
tags: text('tags'), // JSON 数组字符串
|
||
seoTitle: text('seo_title'),
|
||
seoDesc: text('seo_description'),
|
||
seoKeywords: text('seo_keywords'),
|
||
published: integer('published', { mode: 'boolean' }).default(true),
|
||
sortOrder: integer('sort_order').default(0),
|
||
createdAt: text('created_at').notNull().$defaultFn(() => new Date().toISOString()),
|
||
updatedAt: text('updated_at').notNull().$defaultFn(() => new Date().toISOString()),
|
||
})
|
||
|
||
// ── 客户评价 ─────────────────────────────────────────
|
||
export const reviews = sqliteTable('reviews', {
|
||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||
author: text('author').notNull(),
|
||
rating: integer('rating').default(5),
|
||
title: text('title'),
|
||
content: text('content'),
|
||
date: text('date'),
|
||
screenshot: text('screenshot'), // 评价截图路径
|
||
scenes: text('scenes'), // JSON数组: 出行场景标签
|
||
concerns: text('concerns'), // JSON数组: 关注维度标签
|
||
verified: integer('verified', { mode: 'boolean' }).default(false),
|
||
published: integer('published', { mode: 'boolean' }).default(true),
|
||
sortOrder: integer('sort_order').default(0),
|
||
createdAt: text('created_at').notNull().$defaultFn(() => new Date().toISOString()),
|
||
})
|
||
|
||
// ── FAQ ──────────────────────────────────────────────
|
||
export const faqs = sqliteTable('faqs', {
|
||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||
question: text('question').notNull(),
|
||
answer: text('answer').notNull(),
|
||
sortOrder: integer('sort_order').default(0),
|
||
published: integer('published', { mode: 'boolean' }).default(true),
|
||
})
|
||
|
||
// ── 相册/旅拍 ────────────────────────────────────────
|
||
export const galleryItems = sqliteTable('gallery_items', {
|
||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||
title: text('title').notNull(),
|
||
category: text('category'), // 草原 / 森林 / 湖泊 / 冬季 ...
|
||
location: text('location'),
|
||
description: text('description'),
|
||
image: text('image').notNull(), // 图片路径
|
||
orientation: text('orientation'), // portrait / landscape
|
||
published: integer('published', { mode: 'boolean' }).default(true),
|
||
sortOrder: integer('sort_order').default(0),
|
||
})
|
||
|
||
// ── 客户故事 ─────────────────────────────────────────
|
||
export const stories = sqliteTable('stories', {
|
||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||
slug: text('slug').notNull().unique(),
|
||
title: text('title').notNull(),
|
||
subtitle: text('subtitle'),
|
||
familyType: text('family_type'),
|
||
childrenAge: text('children_age'),
|
||
fromCity: text('from_city'),
|
||
tripProduct: text('trip_product'),
|
||
travelDate: text('travel_date'),
|
||
coverImage: text('cover_image'),
|
||
summary: text('summary'), // 卡片展示的 2 行摘要
|
||
author: text('author'), // 客户昵称/作者
|
||
sourceUrl: text('source_url'), // 小红书等外链(有则前台卡片外跳)
|
||
tags: text('tags'), // JSON 数组(标签)
|
||
// sections 存为 JSON 字符串: [{ heading, content }]
|
||
sections: text('sections'),
|
||
keyMoments: text('key_moments'), // JSON 数组
|
||
seoTitle: text('seo_title'),
|
||
seoDesc: text('seo_description'),
|
||
published: integer('published', { mode: 'boolean' }).default(true),
|
||
sortOrder: integer('sort_order').default(0),
|
||
createdAt: text('created_at').notNull().$defaultFn(() => new Date().toISOString()),
|
||
})
|
||
|
||
// ── 表单提交记录 ─────────────────────────────────────
|
||
export const submissions = sqliteTable('submissions', {
|
||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||
type: text('type').notNull(), // contact / customize
|
||
data: text('data').notNull(), // JSON 字符串,存完整表单数据
|
||
ip: text('ip'),
|
||
read: integer('read', { mode: 'boolean' }).default(false),
|
||
replied: integer('replied', { mode: 'boolean' }).default(false),
|
||
repliedAt: text('replied_at'),
|
||
createdAt: text('created_at').notNull().$defaultFn(() => new Date().toISOString()),
|
||
})
|
||
|
||
// ── 站点配置(catch-all,存复杂 JSON 内容)───────────
|
||
// 用于 products / destinations / courses / navigation 等复杂嵌套数据
|
||
export const siteContent = sqliteTable('site_content', {
|
||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||
key: text('key').notNull().unique(), // 如 'products', 'navigation', 'brand'
|
||
label: text('label').notNull(), // 显示名称,如 '产品管理', '导航配置'
|
||
data: text('data').notNull(), // JSON 字符串
|
||
updatedAt: text('updated_at').notNull().$defaultFn(() => new Date().toISOString()),
|
||
})
|