607 lines
26 KiB
SQL
607 lines
26 KiB
SQL
-- Banban shared schema
|
|
-- Sources:
|
|
-- 1. talkingq-url/mysql/init/01-init.sql
|
|
-- 2. mini-program/database/init.sql
|
|
-- Target database: talkingq
|
|
--
|
|
-- Notes:
|
|
-- 1. talkingq-url base tables are kept as the device-domain foundation.
|
|
-- 2. mini-program business tables are merged into the same database.
|
|
-- 3. device_auth.device_id is the shared device identity key.
|
|
-- 4. Device <-> AI conversation records remain in
|
|
-- conversation_histories / conversation_messages.
|
|
-- 5. The database owner is shared, but table ownership is explicit:
|
|
-- talkingq-url owns device-domain base tables; mini-program owns
|
|
-- parent/child/binding/im/location extension tables.
|
|
-- 6. During migration to the shared database, talkingq-url data in
|
|
-- `talkingq` is the source of truth. Legacy `mini_program` data is
|
|
-- not merged into `talkingq`.
|
|
|
|
CREATE DATABASE IF NOT EXISTS `talkingq`
|
|
DEFAULT CHARACTER SET utf8mb4
|
|
COLLATE utf8mb4_unicode_ci;
|
|
|
|
USE `talkingq`;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- talkingq-url base tables
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
CREATE TABLE IF NOT EXISTS `device_imei_mapping` (
|
|
`id` INT NOT NULL AUTO_INCREMENT,
|
|
`imei` VARCHAR(64) NOT NULL,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`serial_number` VARCHAR(64) NOT NULL,
|
|
`status` VARCHAR(32) NOT NULL DEFAULT 'pending',
|
|
`activated_at` DATETIME 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 `imei_UNIQUE` (`imei` ASC),
|
|
UNIQUE INDEX `device_id_UNIQUE` (`device_id` ASC),
|
|
INDEX `idx_device_imei_mapping_status` (`status` ASC)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
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;
|
|
|
|
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`;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- mini-program extension tables
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS `parents` (
|
|
`user_id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`openid` VARCHAR(64) NOT NULL,
|
|
`unionid` VARCHAR(64) NULL,
|
|
`nickname` VARCHAR(64) NULL,
|
|
`avatar_url` VARCHAR(255) NULL,
|
|
`avatar_file_key` VARCHAR(255) NULL,
|
|
`phone` VARCHAR(20) NULL,
|
|
`status` TINYINT 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 (`user_id`),
|
|
UNIQUE KEY `uq_parents_openid` (`openid`),
|
|
KEY `idx_parents_unionid` (`unionid`),
|
|
KEY `idx_parents_phone` (`phone`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `children` (
|
|
`child_id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`child_name` VARCHAR(32) NOT NULL,
|
|
`child_gender` TINYINT NOT NULL DEFAULT 2,
|
|
`child_birthday` DATE NULL,
|
|
`status` TINYINT 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 (`child_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `parent_child_relations` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`user_id` BIGINT NOT NULL,
|
|
`child_id` BIGINT NOT NULL,
|
|
`relation_type` TINYINT NOT NULL DEFAULT 9,
|
|
`is_primary` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`status` TINYINT 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`),
|
|
CONSTRAINT `uq_user_child` UNIQUE (`user_id`, `child_id`),
|
|
KEY `idx_pcr_user_id` (`user_id`),
|
|
KEY `idx_pcr_child_id` (`child_id`),
|
|
CONSTRAINT `fk_pcr_user`
|
|
FOREIGN KEY (`user_id`)
|
|
REFERENCES `parents` (`user_id`)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT `fk_pcr_child`
|
|
FOREIGN KEY (`child_id`)
|
|
REFERENCES `children` (`child_id`)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `device_bindings` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`owner_user_id` BIGINT NOT NULL,
|
|
`child_id` BIGINT NULL,
|
|
`status` TINYINT NOT NULL DEFAULT 1,
|
|
`bound_at` DATETIME NOT NULL,
|
|
`unbound_at` DATETIME NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
CONSTRAINT `uq_device_binding_device` UNIQUE (`device_id`),
|
|
CONSTRAINT `uq_device_binding_child` UNIQUE (`child_id`),
|
|
KEY `idx_device_bindings_owner_user_id` (`owner_user_id`),
|
|
CONSTRAINT `fk_device_bindings_device`
|
|
FOREIGN KEY (`device_id`)
|
|
REFERENCES `device_auth` (`device_id`),
|
|
CONSTRAINT `fk_device_bindings_owner`
|
|
FOREIGN KEY (`owner_user_id`)
|
|
REFERENCES `parents` (`user_id`),
|
|
CONSTRAINT `fk_device_bindings_child`
|
|
FOREIGN KEY (`child_id`)
|
|
REFERENCES `children` (`child_id`)
|
|
ON DELETE SET NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `device_family_members` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`user_id` BIGINT NOT NULL,
|
|
`role` TINYINT NOT NULL DEFAULT 2 COMMENT '1=owner,2=member',
|
|
`status` TINYINT NOT NULL DEFAULT 1,
|
|
`invited_by_user_id` BIGINT NULL,
|
|
`joined_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`removed_at` DATETIME NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
CONSTRAINT `uq_device_family_member` UNIQUE (`device_id`, `user_id`),
|
|
KEY `idx_device_family_members_device_status` (`device_id`, `status`),
|
|
KEY `idx_device_family_members_user_status` (`user_id`, `status`),
|
|
KEY `idx_device_family_members_invited_by` (`invited_by_user_id`),
|
|
CONSTRAINT `fk_device_family_members_device`
|
|
FOREIGN KEY (`device_id`)
|
|
REFERENCES `device_auth` (`device_id`),
|
|
CONSTRAINT `fk_device_family_members_user`
|
|
FOREIGN KEY (`user_id`)
|
|
REFERENCES `parents` (`user_id`),
|
|
CONSTRAINT `fk_device_family_members_invited_by`
|
|
FOREIGN KEY (`invited_by_user_id`)
|
|
REFERENCES `parents` (`user_id`)
|
|
ON DELETE SET NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `device_family_invitations` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`invite_token` CHAR(36) NOT NULL,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`owner_user_id` BIGINT NOT NULL,
|
|
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1=pending,2=accepted,3=expired,4=cancelled',
|
|
`expires_at` DATETIME NOT NULL,
|
|
`accepted_by_user_id` BIGINT NULL,
|
|
`accepted_at` DATETIME 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 KEY `uq_device_family_invite_token` (`invite_token`),
|
|
KEY `idx_device_family_invites_device_status` (`device_id`, `status`),
|
|
KEY `idx_device_family_invites_owner_status` (`owner_user_id`, `status`),
|
|
KEY `idx_device_family_invites_expires_at` (`expires_at`),
|
|
KEY `idx_device_family_invites_accepted_by` (`accepted_by_user_id`),
|
|
CONSTRAINT `fk_device_family_invites_device`
|
|
FOREIGN KEY (`device_id`)
|
|
REFERENCES `device_auth` (`device_id`),
|
|
CONSTRAINT `fk_device_family_invites_owner`
|
|
FOREIGN KEY (`owner_user_id`)
|
|
REFERENCES `parents` (`user_id`),
|
|
CONSTRAINT `fk_device_family_invites_accepted_by`
|
|
FOREIGN KEY (`accepted_by_user_id`)
|
|
REFERENCES `parents` (`user_id`)
|
|
ON DELETE SET NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `device_bind_sessions` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`bind_token` CHAR(36) NOT NULL,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`initiator_user_id` BIGINT NOT NULL,
|
|
`target_child_id` BIGINT NULL,
|
|
`challenge_code_hash` CHAR(64) NULL,
|
|
`challenge_set_at` DATETIME NULL,
|
|
`expires_at` DATETIME NOT NULL,
|
|
`max_attempt_count` TINYINT UNSIGNED NOT NULL DEFAULT 5,
|
|
`attempt_count` TINYINT UNSIGNED NOT NULL DEFAULT 0,
|
|
`status` TINYINT NOT NULL DEFAULT 1,
|
|
`bind_mode` TINYINT NOT NULL DEFAULT 1 COMMENT '1=device bind, 2=additional card bind',
|
|
`card_uuid` VARCHAR(64) NULL,
|
|
`confirmed_at` DATETIME NULL,
|
|
`consumed_at` DATETIME 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 KEY `uq_device_bind_sessions_token` (`bind_token`),
|
|
KEY `idx_device_bind_sessions_device_id` (`device_id`),
|
|
KEY `idx_device_bind_sessions_initiator_user_id` (`initiator_user_id`),
|
|
KEY `idx_device_bind_sessions_target_child_id` (`target_child_id`),
|
|
KEY `idx_device_bind_sessions_expires_at` (`expires_at`),
|
|
KEY `idx_device_bind_sessions_card_uuid` (`card_uuid`),
|
|
CONSTRAINT `fk_device_bind_sessions_device`
|
|
FOREIGN KEY (`device_id`)
|
|
REFERENCES `device_auth` (`device_id`),
|
|
CONSTRAINT `fk_device_bind_sessions_initiator`
|
|
FOREIGN KEY (`initiator_user_id`)
|
|
REFERENCES `parents` (`user_id`),
|
|
CONSTRAINT `fk_device_bind_sessions_target_child`
|
|
FOREIGN KEY (`target_child_id`)
|
|
REFERENCES `children` (`child_id`)
|
|
ON DELETE SET NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `device_bind_history` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`child_id` BIGINT NULL,
|
|
`bound_by_user_id` BIGINT NOT NULL,
|
|
`unbound_by_user_id` BIGINT NULL,
|
|
`bind_source` TINYINT NOT NULL DEFAULT 1,
|
|
`bound_at` DATETIME NOT NULL,
|
|
`unbound_at` DATETIME NULL,
|
|
`unbind_reason` VARCHAR(191) NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_device_bind_history_device_id` (`device_id`),
|
|
KEY `idx_device_bind_history_child_id` (`child_id`),
|
|
KEY `idx_device_bind_history_bound_by_user_id` (`bound_by_user_id`),
|
|
KEY `idx_device_bind_history_unbound_by_user_id` (`unbound_by_user_id`),
|
|
KEY `idx_device_bind_history_bound_at` (`bound_at`),
|
|
CONSTRAINT `fk_device_bind_history_device`
|
|
FOREIGN KEY (`device_id`)
|
|
REFERENCES `device_auth` (`device_id`),
|
|
CONSTRAINT `fk_device_bind_history_child`
|
|
FOREIGN KEY (`child_id`)
|
|
REFERENCES `children` (`child_id`)
|
|
ON DELETE SET NULL,
|
|
CONSTRAINT `fk_device_bind_history_bound_by`
|
|
FOREIGN KEY (`bound_by_user_id`)
|
|
REFERENCES `parents` (`user_id`),
|
|
CONSTRAINT `fk_device_bind_history_unbound_by`
|
|
FOREIGN KEY (`unbound_by_user_id`)
|
|
REFERENCES `parents` (`user_id`)
|
|
ON DELETE SET NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `cards` (
|
|
`card_id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`card_uuid` VARCHAR(64) NOT NULL,
|
|
`device_id` VARCHAR(64) NULL,
|
|
`card_name` VARCHAR(64) NULL,
|
|
`status` TINYINT NOT NULL DEFAULT 0,
|
|
`total_swaps` INT NOT NULL DEFAULT 0,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`card_id`),
|
|
UNIQUE KEY `uq_cards_card_uuid` (`card_uuid`),
|
|
KEY `idx_cards_device_id` (`device_id`),
|
|
KEY `idx_cards_status` (`status`),
|
|
CONSTRAINT `fk_cards_device`
|
|
FOREIGN KEY (`device_id`)
|
|
REFERENCES `device_auth` (`device_id`)
|
|
ON DELETE SET NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- Shared device volume is recommended to use device_configs.volume as source of truth.
|
|
-- device_settings.volume is retained for mini-program compatibility and UI storage.
|
|
CREATE TABLE IF NOT EXISTS `device_settings` (
|
|
`setting_id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`sleep_mode` TINYINT NOT NULL DEFAULT 0,
|
|
`manual_sleep_mode` TINYINT NOT NULL DEFAULT 0,
|
|
`schedule_suppressed_until` DATETIME NULL,
|
|
`disable_time_start` TIME NULL,
|
|
`disable_time_end` TIME NULL,
|
|
`timezone` VARCHAR(32) NOT NULL DEFAULT 'Asia/Shanghai',
|
|
`volume` TINYINT UNSIGNED NULL,
|
|
`brightness` TINYINT UNSIGNED NULL,
|
|
`power` TINYINT UNSIGNED NULL,
|
|
`signal` TINYINT UNSIGNED NULL,
|
|
`version` VARCHAR(64) NULL,
|
|
`disable_weekdays` VARCHAR(32) NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`setting_id`),
|
|
UNIQUE KEY `uq_device_settings_device_id` (`device_id`),
|
|
CONSTRAINT `fk_device_settings_device`
|
|
FOREIGN KEY (`device_id`)
|
|
REFERENCES `device_auth` (`device_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- Device alarm events are reported by the device side through MQTT msg_id=010.
|
|
CREATE TABLE IF NOT EXISTS `device_alarm_events` (
|
|
`alarm_id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`owner_user_id` BIGINT NULL,
|
|
`child_id` BIGINT NULL,
|
|
`source_msg_id` VARCHAR(8) NOT NULL DEFAULT '010',
|
|
`coord_type` VARCHAR(16) NULL,
|
|
`lat` DECIMAL(10, 7) NULL,
|
|
`lng` DECIMAL(10, 7) NULL,
|
|
`location_updated_at` DATETIME NULL,
|
|
`address` VARCHAR(255) NULL,
|
|
`address_resolved_at` DATETIME NULL,
|
|
`address_resolve_status` TINYINT NULL COMMENT '0=pending,1=success,2=failed',
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`alarm_id`),
|
|
KEY `idx_device_alarm_device_created` (`device_id`, `created_at`),
|
|
KEY `idx_device_alarm_owner_created` (`owner_user_id`, `created_at`),
|
|
KEY `idx_device_alarm_child_created` (`child_id`, `created_at`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `im_conversations` (
|
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`conversation_type` TINYINT UNSIGNED NOT NULL,
|
|
`participant_a_type` TINYINT UNSIGNED NOT NULL,
|
|
`participant_a_id` VARCHAR(64) NOT NULL,
|
|
`participant_b_type` TINYINT UNSIGNED NOT NULL,
|
|
`participant_b_id` VARCHAR(64) NOT NULL,
|
|
`pair_key` VARCHAR(191) NOT NULL,
|
|
`status` TINYINT NOT NULL DEFAULT 1,
|
|
`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 NULL,
|
|
`ext_json` JSON NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
CONSTRAINT `uq_conv_type_pair` UNIQUE (`conversation_type`, `pair_key`),
|
|
KEY `idx_im_conv_participant_a` (`participant_a_type`, `participant_a_id`),
|
|
KEY `idx_im_conv_participant_b` (`participant_b_type`, `participant_b_id`),
|
|
KEY `idx_im_conv_last_message_at` (`last_message_at`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `im_messages` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`conversation_id` BIGINT UNSIGNED NOT NULL,
|
|
`seq` BIGINT UNSIGNED NOT NULL,
|
|
`sender_type` TINYINT UNSIGNED NOT NULL,
|
|
`sender_id` VARCHAR(64) NOT NULL,
|
|
`receiver_type` TINYINT UNSIGNED NOT NULL,
|
|
`receiver_id` VARCHAR(64) NOT NULL,
|
|
`content_type` TINYINT UNSIGNED NOT NULL,
|
|
`content_text` MEDIUMTEXT NULL,
|
|
`content_json` JSON NULL,
|
|
`media_file_key` VARCHAR(255) NULL,
|
|
`media_duration_ms` INT UNSIGNED NULL,
|
|
`media_mime_type` VARCHAR(64) NULL,
|
|
`media_size_bytes` BIGINT UNSIGNED NULL,
|
|
`media_transcript_text` TEXT NULL,
|
|
`client_msg_id` VARCHAR(64) NULL,
|
|
`sender_name_snapshot` VARCHAR(64) NULL,
|
|
`sender_avatar_snapshot` VARCHAR(255) NULL,
|
|
`receiver_name_snapshot` VARCHAR(64) NULL,
|
|
`receiver_avatar_snapshot` VARCHAR(255) NULL,
|
|
`ext_json` JSON NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`deleted_at` DATETIME NULL,
|
|
PRIMARY KEY (`id`),
|
|
CONSTRAINT `uq_im_msg_conv_seq` UNIQUE (`conversation_id`, `seq`),
|
|
CONSTRAINT `uq_im_msg_client` UNIQUE (`conversation_id`, `client_msg_id`),
|
|
KEY `idx_im_msg_conversation_created_at` (`conversation_id`, `created_at`),
|
|
KEY `idx_im_msg_sender` (`sender_type`, `sender_id`, `created_at`),
|
|
KEY `idx_im_msg_receiver` (`receiver_type`, `receiver_id`, `created_at`),
|
|
CONSTRAINT `fk_im_messages_conversation`
|
|
FOREIGN KEY (`conversation_id`)
|
|
REFERENCES `im_conversations` (`id`)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- Persistent unread voice-message index for device NFC owner-card playback.
|
|
-- Audio content is still stored by im_messages/media_file_key; this table only stores delivery state.
|
|
CREATE TABLE IF NOT EXISTS `device_pending_voice_messages` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`target_device_id` VARCHAR(64) NOT NULL,
|
|
`sender_device_id` VARCHAR(64) NULL,
|
|
`im_message_id` BIGINT NOT NULL,
|
|
`media_file_key` VARCHAR(255) NOT NULL,
|
|
`audio_url` VARCHAR(512) NULL,
|
|
`source` VARCHAR(32) NOT NULL DEFAULT 'unknown',
|
|
`status` VARCHAR(32) NOT NULL DEFAULT 'pending',
|
|
`delivery_count` INT NOT NULL DEFAULT 0,
|
|
`delivered_at` DATETIME NULL,
|
|
`listened_at` DATETIME 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 KEY `uq_device_pending_voice_target_msg` (`target_device_id`, `im_message_id`),
|
|
KEY `idx_device_pending_voice_target_status_created` (`target_device_id`, `status`, `created_at`),
|
|
KEY `idx_device_pending_voice_sender` (`sender_device_id`),
|
|
KEY `idx_device_pending_voice_im_message` (`im_message_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `child_location_current` (
|
|
`child_id` BIGINT NOT NULL,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`coord_type` VARCHAR(16) NOT NULL DEFAULT 'gcj02',
|
|
`lat` DECIMAL(10, 7) NOT NULL,
|
|
`lng` DECIMAL(10, 7) NOT NULL,
|
|
`accuracy_m` INT UNSIGNED NULL,
|
|
`altitude_m` DECIMAL(8, 2) NULL,
|
|
`speed_mps` DECIMAL(8, 2) NULL,
|
|
`heading_deg` SMALLINT UNSIGNED NULL,
|
|
`source` TINYINT UNSIGNED NOT NULL,
|
|
`battery_pct` TINYINT UNSIGNED NULL,
|
|
`device_time` DATETIME NOT NULL,
|
|
`server_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
`address` VARCHAR(255) NULL,
|
|
`address_resolved_at` DATETIME NULL,
|
|
`address_resolve_status` TINYINT NULL COMMENT '0=pending,1=success,2=failed',
|
|
PRIMARY KEY (`child_id`),
|
|
KEY `idx_child_loc_current_device` (`device_id`),
|
|
KEY `idx_child_loc_current_server_time` (`server_time`),
|
|
CONSTRAINT `fk_child_loc_current_child`
|
|
FOREIGN KEY (`child_id`)
|
|
REFERENCES `children` (`child_id`)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT `fk_child_loc_current_device`
|
|
FOREIGN KEY (`device_id`)
|
|
REFERENCES `device_auth` (`device_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `child_location_history` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
`child_id` BIGINT NOT NULL,
|
|
`device_id` VARCHAR(64) NOT NULL,
|
|
`coord_type` VARCHAR(16) NOT NULL DEFAULT 'gcj02',
|
|
`lat` DECIMAL(10, 7) NOT NULL,
|
|
`lng` DECIMAL(10, 7) NOT NULL,
|
|
`accuracy_m` INT UNSIGNED NULL,
|
|
`altitude_m` DECIMAL(8, 2) NULL,
|
|
`speed_mps` DECIMAL(8, 2) NULL,
|
|
`heading_deg` SMALLINT UNSIGNED NULL,
|
|
`source` TINYINT UNSIGNED NOT NULL,
|
|
`battery_pct` TINYINT UNSIGNED NULL,
|
|
`device_time` DATETIME NOT NULL,
|
|
`server_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_child_loc_hist_child` (`child_id`, `created_at`),
|
|
KEY `idx_child_loc_hist_device` (`device_id`, `created_at`),
|
|
CONSTRAINT `fk_child_loc_hist_child`
|
|
FOREIGN KEY (`child_id`)
|
|
REFERENCES `children` (`child_id`)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT `fk_child_loc_hist_device`
|
|
FOREIGN KEY (`device_id`)
|
|
REFERENCES `device_auth` (`device_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|