119 lines
4.1 KiB
SQL
119 lines
4.1 KiB
SQL
PRAGMA foreign_keys = ON;
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id TEXT PRIMARY KEY,
|
|
openid TEXT NOT NULL UNIQUE,
|
|
unionid TEXT,
|
|
phone TEXT,
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
last_login_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS users_phone_unique_idx
|
|
ON users(phone)
|
|
WHERE phone IS NOT NULL AND phone <> '';
|
|
|
|
CREATE TABLE IF NOT EXISTS project_categories (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
sort INTEGER NOT NULL DEFAULT 0,
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS projects (
|
|
id TEXT PRIMARY KEY,
|
|
category_id TEXT NOT NULL REFERENCES project_categories(id),
|
|
name TEXT NOT NULL,
|
|
subtitle TEXT NOT NULL DEFAULT '',
|
|
price_text TEXT NOT NULL,
|
|
image TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
sort INTEGER NOT NULL DEFAULT 0,
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS app_config (
|
|
config_key TEXT PRIMARY KEY,
|
|
config_value TEXT NOT NULL DEFAULT '',
|
|
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS schedule_days (
|
|
id TEXT PRIMARY KEY,
|
|
project_id TEXT NOT NULL REFERENCES projects(id),
|
|
date TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'available',
|
|
note TEXT NOT NULL DEFAULT '',
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(project_id, date)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS time_slots (
|
|
id TEXT PRIMARY KEY,
|
|
schedule_day_id TEXT NOT NULL REFERENCES schedule_days(id),
|
|
start_time TEXT NOT NULL,
|
|
end_time TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'available',
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(schedule_day_id, start_time)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS bookings (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT REFERENCES users(id),
|
|
project_id TEXT NOT NULL REFERENCES projects(id),
|
|
slot_id TEXT NOT NULL REFERENCES time_slots(id),
|
|
phone TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
remark TEXT NOT NULL DEFAULT '',
|
|
confirm_token TEXT NOT NULL,
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS price_inquiries (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT REFERENCES users(id),
|
|
phone TEXT NOT NULL,
|
|
province TEXT NOT NULL,
|
|
city TEXT NOT NULL,
|
|
district TEXT NOT NULL,
|
|
project_name TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
remark TEXT NOT NULL DEFAULT '',
|
|
last_submitted_at TEXT NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now', '+8 hours')),
|
|
created_at TEXT NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now', '+8 hours')),
|
|
updated_at TEXT NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now', '+8 hours'))
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS price_inquiries_phone_unique_idx
|
|
ON price_inquiries(phone);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS bookings_effective_unique_idx
|
|
ON bookings(phone, project_id, slot_id)
|
|
WHERE status IN ('pending', 'confirmed');
|
|
|
|
CREATE TABLE IF NOT EXISTS config_audit_logs (
|
|
id TEXT PRIMARY KEY,
|
|
admin_id TEXT NOT NULL,
|
|
target_type TEXT NOT NULL,
|
|
target_id TEXT NOT NULL,
|
|
action TEXT NOT NULL,
|
|
before_json TEXT NOT NULL DEFAULT '{}',
|
|
after_json TEXT NOT NULL DEFAULT '{}',
|
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS projects_category_idx ON projects(category_id, sort);
|
|
CREATE INDEX IF NOT EXISTS schedule_days_project_date_idx ON schedule_days(project_id, date);
|
|
CREATE INDEX IF NOT EXISTS time_slots_day_idx ON time_slots(schedule_day_id, start_time);
|
|
CREATE INDEX IF NOT EXISTS bookings_phone_idx ON bookings(phone, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS bookings_status_idx ON bookings(status, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS price_inquiries_region_idx ON price_inquiries(province, city, district, created_at DESC);
|