整理小程序数据库初始化脚本
This commit is contained in:
@@ -1,26 +1,29 @@
|
||||
-- New tables per design.md
|
||||
-- Supports both MySQL and SQLite
|
||||
-- Current MySQL schema for mini-program
|
||||
|
||||
-- parents table
|
||||
CREATE DATABASE IF NOT EXISTS mini_program
|
||||
DEFAULT CHARACTER SET utf8mb4
|
||||
COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
USE mini_program;
|
||||
|
||||
-- parents
|
||||
CREATE TABLE IF NOT EXISTS parents (
|
||||
user_id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
openid VARCHAR(64) UNIQUE NOT NULL,
|
||||
unionid VARCHAR(64),
|
||||
nickname VARCHAR(64),
|
||||
avatar_url VARCHAR(255),
|
||||
avatar_file_key VARCHAR(255),
|
||||
phone VARCHAR(20),
|
||||
status TINYINT NOT NULL DEFAULT 1,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- SQLite uses TRIGGER for updated_at, MySQL uses ON UPDATE
|
||||
-- For SQLite compatibility, we'll handle in app layer
|
||||
CREATE INDEX idx_parents_unionid ON parents(unionid);
|
||||
CREATE INDEX idx_parents_phone ON parents(phone);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_parents_unionid ON parents(unionid);
|
||||
CREATE INDEX IF NOT EXISTS idx_parents_phone ON parents(phone);
|
||||
|
||||
-- children table
|
||||
-- children
|
||||
CREATE TABLE IF NOT EXISTS children (
|
||||
child_id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
child_name VARCHAR(32) NOT NULL,
|
||||
@@ -29,9 +32,9 @@ CREATE TABLE IF NOT EXISTS children (
|
||||
status TINYINT NOT NULL DEFAULT 1,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- parent_child_relations table
|
||||
-- parent_child_relations
|
||||
CREATE TABLE IF NOT EXISTS parent_child_relations (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
user_id BIGINT NOT NULL,
|
||||
@@ -41,10 +44,13 @@ CREATE TABLE IF NOT EXISTS parent_child_relations (
|
||||
status TINYINT NOT NULL DEFAULT 1,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (user_id, child_id)
|
||||
);
|
||||
CONSTRAINT uq_user_child UNIQUE (user_id, child_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- device_bindings table
|
||||
CREATE INDEX idx_pcr_user_id ON parent_child_relations(user_id);
|
||||
CREATE INDEX idx_pcr_child_id ON parent_child_relations(child_id);
|
||||
|
||||
-- device_bindings
|
||||
CREATE TABLE IF NOT EXISTS device_bindings (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
device_id VARCHAR(64) NOT NULL,
|
||||
@@ -55,13 +61,13 @@ CREATE TABLE IF NOT EXISTS device_bindings (
|
||||
unbound_at DATETIME,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (device_id),
|
||||
UNIQUE (child_id)
|
||||
);
|
||||
CONSTRAINT uq_device_binding_device UNIQUE (device_id),
|
||||
CONSTRAINT uq_device_binding_child UNIQUE (child_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_device_bindings_owner_user_id ON device_bindings(owner_user_id);
|
||||
CREATE INDEX idx_device_bindings_owner_user_id ON device_bindings(owner_user_id);
|
||||
|
||||
-- device_bind_sessions table
|
||||
-- device_bind_sessions
|
||||
CREATE TABLE IF NOT EXISTS device_bind_sessions (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
bind_token CHAR(36) UNIQUE NOT NULL,
|
||||
@@ -78,9 +84,9 @@ CREATE TABLE IF NOT EXISTS device_bind_sessions (
|
||||
consumed_at DATETIME,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- device_bind_history table
|
||||
-- device_bind_history
|
||||
CREATE TABLE IF NOT EXISTS device_bind_history (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
device_id VARCHAR(64) NOT NULL,
|
||||
@@ -92,9 +98,9 @@ CREATE TABLE IF NOT EXISTS device_bind_history (
|
||||
unbound_at DATETIME,
|
||||
unbind_reason VARCHAR(191),
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- cards table
|
||||
-- cards
|
||||
CREATE TABLE IF NOT EXISTS cards (
|
||||
card_id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
card_uuid VARCHAR(64) UNIQUE NOT NULL,
|
||||
@@ -104,9 +110,9 @@ CREATE TABLE IF NOT EXISTS cards (
|
||||
total_swaps INT NOT NULL DEFAULT 0,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- device_settings table
|
||||
-- device_settings
|
||||
CREATE TABLE IF NOT EXISTS device_settings (
|
||||
setting_id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
device_id VARCHAR(64) NOT NULL UNIQUE,
|
||||
@@ -119,9 +125,9 @@ CREATE TABLE IF NOT EXISTS device_settings (
|
||||
disable_weekdays VARCHAR(32),
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- im_conversations table
|
||||
-- im_conversations
|
||||
CREATE TABLE IF NOT EXISTS im_conversations (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
conversation_type TINYINT UNSIGNED NOT NULL,
|
||||
@@ -138,14 +144,14 @@ CREATE TABLE IF NOT EXISTS im_conversations (
|
||||
ext_json JSON,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (conversation_type, pair_key)
|
||||
);
|
||||
CONSTRAINT uq_conv_type_pair UNIQUE (conversation_type, pair_key)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_im_conv_participant_a ON im_conversations(participant_a_type, participant_a_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_im_conv_participant_b ON im_conversations(participant_b_type, participant_b_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_im_conv_last_message_at ON im_conversations(last_message_at);
|
||||
CREATE INDEX idx_im_conv_participant_a ON im_conversations(participant_a_type, participant_a_id);
|
||||
CREATE INDEX idx_im_conv_participant_b ON im_conversations(participant_b_type, participant_b_id);
|
||||
CREATE INDEX idx_im_conv_last_message_at ON im_conversations(last_message_at);
|
||||
|
||||
-- im_messages table
|
||||
-- im_messages
|
||||
CREATE TABLE IF NOT EXISTS im_messages (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
conversation_id BIGINT UNSIGNED NOT NULL,
|
||||
@@ -170,14 +176,14 @@ CREATE TABLE IF NOT EXISTS im_messages (
|
||||
ext_json JSON,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at DATETIME,
|
||||
UNIQUE (conversation_id, seq),
|
||||
UNIQUE (conversation_id, client_msg_id)
|
||||
);
|
||||
CONSTRAINT uq_im_msg_conv_seq UNIQUE (conversation_id, seq),
|
||||
CONSTRAINT uq_im_msg_client UNIQUE (conversation_id, client_msg_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_im_msg_sender ON im_messages(sender_type, sender_id, created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_im_msg_receiver ON im_messages(receiver_type, receiver_id, created_at);
|
||||
CREATE INDEX idx_im_msg_sender ON im_messages(sender_type, sender_id, created_at);
|
||||
CREATE INDEX idx_im_msg_receiver ON im_messages(receiver_type, receiver_id, created_at);
|
||||
|
||||
-- child_location_current table
|
||||
-- child_location_current
|
||||
CREATE TABLE IF NOT EXISTS child_location_current (
|
||||
child_id BIGINT UNSIGNED PRIMARY KEY,
|
||||
device_id VARCHAR(64) NOT NULL,
|
||||
@@ -193,9 +199,9 @@ CREATE TABLE IF NOT EXISTS child_location_current (
|
||||
device_time DATETIME NOT NULL,
|
||||
server_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- child_location_history table
|
||||
-- child_location_history
|
||||
CREATE TABLE IF NOT EXISTS child_location_history (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
child_id BIGINT UNSIGNED NOT NULL,
|
||||
@@ -212,6 +218,6 @@ CREATE TABLE IF NOT EXISTS child_location_history (
|
||||
device_time DATETIME NOT NULL,
|
||||
server_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_child_loc_hist_child ON child_location_history(child_id, created_at);
|
||||
CREATE INDEX idx_child_loc_hist_child ON child_location_history(child_id, created_at);
|
||||
@@ -1,305 +0,0 @@
|
||||
-- Chat schema and seed data for mini-program
|
||||
-- Target: MySQL 8+
|
||||
|
||||
CREATE DATABASE IF NOT EXISTS mini_program
|
||||
DEFAULT CHARACTER SET utf8mb4
|
||||
COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
USE mini_program;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
DROP TABLE IF EXISTS chat_message;
|
||||
DROP TABLE IF EXISTS chat_conversation_member;
|
||||
DROP TABLE IF EXISTS chat_conversation;
|
||||
DROP TABLE IF EXISTS chat_user_auth;
|
||||
DROP TABLE IF EXISTS chat_user;
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chat_user (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
nickname VARCHAR(64) NULL,
|
||||
avatar_file_key VARCHAR(255) NULL COMMENT 'Stored file key, not URL',
|
||||
status TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1-active 2-disabled 3-deleted',
|
||||
last_login_at DATETIME(3) NULL,
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_status (status),
|
||||
KEY idx_created_at (created_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chat_user_auth (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
auth_type TINYINT UNSIGNED NOT NULL COMMENT '1-wechat_miniapp_openid 2-wechat_unionid 3-phone_sms 4-email_magic_link 5-oauth 6-username_password',
|
||||
auth_identifier VARCHAR(191) NOT NULL COMMENT 'openid/unionid/phone/email/oauth-sub/username',
|
||||
password_hash CHAR(64) NULL COMMENT 'sha256 hex for demo only; production should use bcrypt/argon2',
|
||||
credential_json JSON NULL COMMENT 'Extra auth payload, e.g. app_id/provider/phone_area',
|
||||
is_primary TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1-primary login identity 0-secondary',
|
||||
status TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1-active 2-disabled 3-revoked',
|
||||
last_login_at DATETIME(3) NULL,
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_auth_type_identifier (auth_type, auth_identifier),
|
||||
KEY idx_user_status (user_id, status),
|
||||
KEY idx_last_login_at (last_login_at),
|
||||
CONSTRAINT fk_user_auth_user
|
||||
FOREIGN KEY (user_id) REFERENCES chat_user(id)
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chat_conversation (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
user_low_id BIGINT UNSIGNED NOT NULL COMMENT 'Smaller user_id in direct chat pair',
|
||||
user_high_id BIGINT UNSIGNED NOT NULL COMMENT 'Larger user_id in direct chat pair',
|
||||
status TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1-active 2-archived',
|
||||
last_seq BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
message_count BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
last_message_preview VARCHAR(255) NULL,
|
||||
last_message_at DATETIME(3) NULL,
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_direct_pair (user_low_id, user_high_id),
|
||||
KEY idx_last_message_at (last_message_at),
|
||||
KEY idx_user_low_id (user_low_id),
|
||||
KEY idx_user_high_id (user_high_id),
|
||||
CONSTRAINT fk_conv_user_low
|
||||
FOREIGN KEY (user_low_id) REFERENCES chat_user(id)
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT fk_conv_user_high
|
||||
FOREIGN KEY (user_high_id) REFERENCES chat_user(id)
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chat_message (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
conversation_id BIGINT UNSIGNED NOT NULL,
|
||||
seq BIGINT UNSIGNED NOT NULL COMMENT 'Conversation-local incremental sequence',
|
||||
sender_user_id BIGINT UNSIGNED NULL COMMENT 'Null means assistant/system sender',
|
||||
role TINYINT UNSIGNED NOT NULL COMMENT '1-user 2-assistant 3-system 4-tool',
|
||||
content_type TINYINT UNSIGNED NOT NULL COMMENT '1-text 2-audio 3-image 4-json',
|
||||
content_text MEDIUMTEXT NULL,
|
||||
content_json JSON NULL,
|
||||
media_file_key VARCHAR(255) NULL COMMENT 'Stored file key, not URL',
|
||||
media_duration_ms INT UNSIGNED NULL,
|
||||
client_msg_id VARCHAR(64) NULL COMMENT 'Idempotency key from client',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
deleted_at DATETIME(3) NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_conv_seq (conversation_id, seq),
|
||||
UNIQUE KEY uk_conv_client_msg (conversation_id, client_msg_id),
|
||||
KEY idx_conv_created (conversation_id, created_at),
|
||||
KEY idx_sender_created (sender_user_id, created_at),
|
||||
CONSTRAINT fk_msg_conv
|
||||
FOREIGN KEY (conversation_id) REFERENCES chat_conversation(id)
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT fk_msg_sender_user
|
||||
FOREIGN KEY (sender_user_id) REFERENCES chat_user(id)
|
||||
ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
INSERT INTO chat_user (
|
||||
id,
|
||||
nickname,
|
||||
avatar_file_key,
|
||||
status,
|
||||
last_login_at,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
1,
|
||||
'Parent A',
|
||||
'avatars/parent-a.png',
|
||||
1,
|
||||
'2026-03-25 09:58:00.000',
|
||||
'2026-03-25 09:00:00.000',
|
||||
'2026-03-25 09:58:00.000'
|
||||
),
|
||||
(
|
||||
2,
|
||||
'Parent B',
|
||||
'avatars/parent-b.png',
|
||||
1,
|
||||
'2026-03-25 10:01:00.000',
|
||||
'2026-03-25 09:20:00.000',
|
||||
'2026-03-25 10:01:00.000'
|
||||
),
|
||||
(
|
||||
3,
|
||||
'Parent C',
|
||||
'avatars/parent-c.png',
|
||||
1,
|
||||
'2026-03-25 21:11:00.000',
|
||||
'2026-03-25 20:30:00.000',
|
||||
'2026-03-25 21:11:00.000'
|
||||
);
|
||||
|
||||
INSERT INTO chat_user_auth (
|
||||
id,
|
||||
user_id,
|
||||
auth_type,
|
||||
auth_identifier,
|
||||
password_hash,
|
||||
credential_json,
|
||||
is_primary,
|
||||
status,
|
||||
last_login_at,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
1,
|
||||
1,
|
||||
6,
|
||||
'test1',
|
||||
SHA2('123', 256),
|
||||
JSON_OBJECT('provider', 'local_account'),
|
||||
1,
|
||||
1,
|
||||
'2026-03-25 09:58:00.000',
|
||||
'2026-03-25 09:00:00.000',
|
||||
'2026-03-25 09:58:00.000'
|
||||
),
|
||||
(
|
||||
2,
|
||||
2,
|
||||
6,
|
||||
'test2',
|
||||
SHA2('123', 256),
|
||||
JSON_OBJECT('provider', 'local_account'),
|
||||
1,
|
||||
1,
|
||||
'2026-03-25 10:01:00.000',
|
||||
'2026-03-25 09:20:00.000',
|
||||
'2026-03-25 10:01:00.000'
|
||||
),
|
||||
(
|
||||
3,
|
||||
3,
|
||||
6,
|
||||
'test3',
|
||||
SHA2('123', 256),
|
||||
JSON_OBJECT('provider', 'local_account'),
|
||||
1,
|
||||
1,
|
||||
'2026-03-25 21:11:00.000',
|
||||
'2026-03-25 20:30:00.000',
|
||||
'2026-03-25 21:11:00.000'
|
||||
);
|
||||
|
||||
INSERT INTO chat_conversation (
|
||||
id,
|
||||
user_low_id,
|
||||
user_high_id,
|
||||
status,
|
||||
last_seq,
|
||||
message_count,
|
||||
last_message_preview,
|
||||
last_message_at,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
5,
|
||||
5,
|
||||
'user: Thanks, I understand now.',
|
||||
'2026-03-25 10:00:40.000',
|
||||
'2026-03-25 10:00:00.000',
|
||||
'2026-03-25 10:00:40.000'
|
||||
);
|
||||
|
||||
INSERT INTO chat_message (
|
||||
id,
|
||||
conversation_id,
|
||||
seq,
|
||||
sender_user_id,
|
||||
role,
|
||||
content_type,
|
||||
content_text,
|
||||
content_json,
|
||||
media_file_key,
|
||||
media_duration_ms,
|
||||
client_msg_id,
|
||||
created_at
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
1001,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
'Hi, did you finish homework?',
|
||||
JSON_OBJECT('lang', 'en'),
|
||||
NULL,
|
||||
NULL,
|
||||
'c1-m1',
|
||||
'2026-03-25 10:00:05.000'
|
||||
),
|
||||
(
|
||||
1002,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
'Almost done, one question left.',
|
||||
JSON_OBJECT('lang', 'en'),
|
||||
NULL,
|
||||
NULL,
|
||||
'c1-m2',
|
||||
'2026-03-25 10:00:12.000'
|
||||
),
|
||||
(
|
||||
1003,
|
||||
1,
|
||||
3,
|
||||
NULL,
|
||||
2,
|
||||
1,
|
||||
'I can help explain the last question.',
|
||||
JSON_OBJECT('tone', 'assistant'),
|
||||
NULL,
|
||||
NULL,
|
||||
'c1-m3',
|
||||
'2026-03-25 10:00:20.000'
|
||||
),
|
||||
(
|
||||
1004,
|
||||
1,
|
||||
4,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
'Great, explain how to solve it.',
|
||||
JSON_OBJECT('lang', 'en'),
|
||||
NULL,
|
||||
NULL,
|
||||
'c1-m4',
|
||||
'2026-03-25 10:00:30.000'
|
||||
),
|
||||
(
|
||||
1005,
|
||||
1,
|
||||
5,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
'Thanks, I understand now.',
|
||||
JSON_OBJECT('lang', 'en'),
|
||||
NULL,
|
||||
NULL,
|
||||
'c1-m5',
|
||||
'2026-03-25 10:00:40.000'
|
||||
);
|
||||
@@ -1,227 +0,0 @@
|
||||
-- 家长微信账号表
|
||||
CREATE TABLE parents (
|
||||
user_id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
openid VARCHAR(64) UNIQUE NOT NULL COMMENT '微信openid',
|
||||
unionid VARCHAR(64) COMMENT '微信unionid',
|
||||
nickname VARCHAR(64) COMMENT '家长昵称',
|
||||
avatar_url VARCHAR(255),
|
||||
phone VARCHAR(20),
|
||||
status TINYINT DEFAULT 1 COMMENT '0禁用 1正常',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_unionid (unionid),
|
||||
INDEX idx_phone (phone)
|
||||
) ENGINE=InnoDB COMMENT='家长用户表';
|
||||
|
||||
CREATE TABLE children (
|
||||
profile_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '档案主键',
|
||||
user_id BIGINT NOT NULL COMMENT '所属家长ID',
|
||||
|
||||
-- 核心资料
|
||||
child_name VARCHAR(32) NOT NULL COMMENT '儿童昵称(设备唤醒名)',
|
||||
child_gender TINYINT DEFAULT 2 COMMENT '性别:0女 1男 2保密',
|
||||
child_birthday DATE COMMENT '出生日期',
|
||||
child_age TINYINT UNSIGNED GENERATED ALWAYS AS (
|
||||
TIMESTAMPDIFF(YEAR, child_birthday, CURDATE())
|
||||
) STORED COMMENT '自动计算年龄(用于适龄内容过滤)',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
-- 约束与索引
|
||||
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE,
|
||||
)ENGINE=InnoDB COMMENT='儿童档案表(一个家长可创建多个档案)';
|
||||
|
||||
CREATE TABLE cards (
|
||||
card_id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
card_uuid VARCHAR(64) UNIQUE NOT NULL COMMENT 'NFC卡片UUID',
|
||||
device_id BIGINT UNIQUE COMMENT '绑定设备ID',
|
||||
card_name VARCHAR(64) COMMENT '名片名称',
|
||||
status TINYINT DEFAULT 0 COMMENT '0未绑定 1已绑定 2挂失',
|
||||
total_swaps INT DEFAULT 0 COMMENT '交换次数',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
FOREIGN KEY (device_id) REFERENCES devices(device_id),
|
||||
INDEX idx_uuid (card_uuid),
|
||||
INDEX idx_device (device_id)
|
||||
) ENGINE=InnoDB COMMENT='实体交友名片表';
|
||||
-- Todo 待修改
|
||||
CREATE TABLE device_settings (
|
||||
setting_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '设置主键',
|
||||
device_id BIGINT NOT NULL UNIQUE COMMENT '设备ID(一对一)',
|
||||
|
||||
-- 休眠与时间管理(防熬夜)
|
||||
sleep_mode TINYINT DEFAULT 0 COMMENT '休眠模式:0关闭 1定时休眠 2连续使用限制',
|
||||
sleep_start TIME COMMENT '定时休眠开始时间,如 22:00:00',
|
||||
sleep_end TIME COMMENT '定时休眠结束时间,如 07:00:00',
|
||||
timezone VARCHAR(32) DEFAULT 'Asia/Shanghai' COMMENT '时区,解决跨时区问题',
|
||||
|
||||
-- 音量与硬件控制
|
||||
volume TINYINT UNSIGNED DEFAULT 80 COMMENT '系统音量 0-100',
|
||||
brightness TINYINT UNSIGNED DEFAULT 100 COMMENT '指示灯亮度 0-100(0为关闭)',
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
) ENGINE=InnoDB COMMENT='设备设置表(家长远程管控配置)';
|
||||
|
||||
-- 初始化数据库表
|
||||
|
||||
-- 创建device_configs表
|
||||
CREATE TABLE IF NOT EXISTS `device_configs` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`device_id` VARCHAR(64) NOT NULL,
|
||||
`selected_role_key` VARCHAR(64) NOT NULL,
|
||||
`preferred_language` VARCHAR(10) NULL,
|
||||
`volume` INT NULL,
|
||||
`last_update_time` FLOAT NOT NULL,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `device_id_UNIQUE` (`device_id` ASC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建conversation_histories表
|
||||
CREATE TABLE IF NOT EXISTS `conversation_histories` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`device_id` VARCHAR(64) NOT NULL,
|
||||
`role_key` VARCHAR(64) NOT NULL,
|
||||
`last_interaction_time` FLOAT NOT NULL,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `idx_device_id` (`device_id` ASC),
|
||||
INDEX `idx_role_key` (`role_key` ASC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建conversation_messages表
|
||||
CREATE TABLE IF NOT EXISTS `conversation_messages` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`conversation_id` INT NOT NULL,
|
||||
`is_user` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`content` TEXT NOT NULL,
|
||||
`timestamp` FLOAT NOT NULL,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `idx_conversation_id` (`conversation_id` ASC),
|
||||
CONSTRAINT `fk_messages_conversation`
|
||||
FOREIGN KEY (`conversation_id`)
|
||||
REFERENCES `conversation_histories` (`id`)
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建roles表
|
||||
CREATE TABLE IF NOT EXISTS `roles` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`role_key` VARCHAR(64) NOT NULL,
|
||||
`name` VARCHAR(128) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`content` TEXT NOT NULL,
|
||||
`default_language` VARCHAR(10) NULL,
|
||||
`asr_provider` VARCHAR(64) NULL,
|
||||
`llm_provider` VARCHAR(64) NULL,
|
||||
`tts_provider` VARCHAR(64) NULL,
|
||||
`competitive_llm_mode` TINYINT(1) NULL,
|
||||
`volcano_model_id` VARCHAR(64) NULL,
|
||||
`volcano_voice_type` VARCHAR(64) NULL,
|
||||
`tencent_voice_type` VARCHAR(64) NULL,
|
||||
`aliyun_voice_name` VARCHAR(64) NULL,
|
||||
`minimax_voice_id` VARCHAR(64) NULL,
|
||||
`url` VARCHAR(255) NULL,
|
||||
`homophones` JSON NULL,
|
||||
`enabled` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `role_key_UNIQUE` (`role_key` ASC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建role_languages表
|
||||
CREATE TABLE IF NOT EXISTS `role_languages` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`role_id` INT NOT NULL,
|
||||
`language_code` VARCHAR(10) NOT NULL,
|
||||
`name` VARCHAR(128) NULL,
|
||||
`content` TEXT NULL,
|
||||
`asr_provider` VARCHAR(64) NULL,
|
||||
`llm_provider` VARCHAR(64) NULL,
|
||||
`tts_provider` VARCHAR(64) NULL,
|
||||
`volcano_voice_type` VARCHAR(64) NULL,
|
||||
`tencent_voice_type` VARCHAR(64) NULL,
|
||||
`aliyun_voice_name` VARCHAR(64) NULL,
|
||||
`minimax_voice_id` VARCHAR(64) NULL,
|
||||
`url` VARCHAR(255) NULL,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `uix_role_language` (`role_id`, `language_code`),
|
||||
CONSTRAINT `fk_role_languages_role`
|
||||
FOREIGN KEY (`role_id`)
|
||||
REFERENCES `roles` (`id`)
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建device_auth表
|
||||
CREATE TABLE IF NOT EXISTS `device_auth` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`device_id` VARCHAR(64) NOT NULL,
|
||||
`serial_number` VARCHAR(64) NOT NULL,
|
||||
`batch_id` VARCHAR(20) NULL,
|
||||
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `device_id_UNIQUE` (`device_id` ASC),
|
||||
INDEX `idx_batch_id` (`batch_id` ASC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建device_firmware_update表
|
||||
CREATE TABLE IF NOT EXISTS `device_firmware_update` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`device_id` VARCHAR(64) NOT NULL,
|
||||
`serial_number` VARCHAR(64) NOT NULL,
|
||||
`mac_address` VARCHAR(512) NULL,
|
||||
`firmware_version` VARCHAR(64) NOT NULL,
|
||||
`update_status` VARCHAR(32) NOT NULL DEFAULT 'success',
|
||||
`progress` FLOAT NULL DEFAULT 0.0,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `device_id_UNIQUE` (`device_id` ASC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 创建system_config表
|
||||
CREATE TABLE IF NOT EXISTS `system_config` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`config_key` VARCHAR(128) NOT NULL,
|
||||
`config_value` TEXT NULL,
|
||||
`description` VARCHAR(255) NULL,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `config_key_UNIQUE` (`config_key` ASC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 添加初始角色配置
|
||||
INSERT INTO `device_configs` (`device_id`, `selected_role_key`, `preferred_language`, `last_update_time`)
|
||||
VALUES ('default', 'assistant', 'zh', UNIX_TIMESTAMP())
|
||||
ON DUPLICATE KEY UPDATE `selected_role_key`=`selected_role_key`;
|
||||
|
||||
-- 添加默认系统配置
|
||||
INSERT INTO `system_config` (`config_key`, `config_value`, `description`)
|
||||
VALUES
|
||||
('latest_firmware_version', '1.0.0', '最新固件版本'),
|
||||
('update_firmware_url', 'https://example.com/firmware/latest.bin', '固件更新URL')
|
||||
ON DUPLICATE KEY UPDATE `config_value`=`config_value`;
|
||||
|
||||
-- 添加默认角色
|
||||
INSERT INTO `roles` (`role_key`, `name`, `description`, `content`, `default_language`, `enabled`)
|
||||
VALUES (
|
||||
'assistant',
|
||||
'智能助手',
|
||||
'默认智能助手角色',
|
||||
'你是一个友好的智能助手,乐于帮助用户解答问题。',
|
||||
'zh',
|
||||
1
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE `role_key`=`role_key`;
|
||||
@@ -1,46 +0,0 @@
|
||||
-- Migration: support "bind device first, then set child profile"
|
||||
-- Target: MySQL 8.x
|
||||
|
||||
-- 1) Add owner_user_id on device_bindings.
|
||||
ALTER TABLE device_bindings
|
||||
ADD COLUMN owner_user_id BIGINT NULL AFTER device_id;
|
||||
|
||||
-- 2) Backfill owner_user_id from active parent-child relation (prefer primary relation).
|
||||
UPDATE device_bindings b
|
||||
SET owner_user_id = (
|
||||
SELECT r.user_id
|
||||
FROM parent_child_relations r
|
||||
WHERE r.child_id = b.child_id
|
||||
AND r.status = 1
|
||||
ORDER BY r.is_primary DESC, r.id ASC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE b.owner_user_id IS NULL;
|
||||
|
||||
-- 3) Fallback backfill from latest bind history.
|
||||
UPDATE device_bindings b
|
||||
SET owner_user_id = (
|
||||
SELECT h.bound_by_user_id
|
||||
FROM device_bind_history h
|
||||
WHERE h.device_id = b.device_id
|
||||
ORDER BY h.bound_at DESC, h.id DESC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE b.owner_user_id IS NULL;
|
||||
|
||||
-- 4) Ensure no NULL owner before setting NOT NULL.
|
||||
-- If this query returns rows, handle manually before continuing:
|
||||
-- SELECT id, device_id, child_id FROM device_bindings WHERE owner_user_id IS NULL;
|
||||
|
||||
-- 5) Make schema changes for new flow.
|
||||
ALTER TABLE device_bindings
|
||||
MODIFY COLUMN owner_user_id BIGINT NOT NULL;
|
||||
|
||||
ALTER TABLE device_bindings
|
||||
MODIFY COLUMN child_id BIGINT NULL;
|
||||
|
||||
ALTER TABLE device_bindings
|
||||
ADD INDEX idx_device_bindings_owner_user_id (owner_user_id);
|
||||
|
||||
ALTER TABLE device_bind_history
|
||||
MODIFY COLUMN child_id BIGINT NULL;
|
||||
Reference in New Issue
Block a user