-- Migration: create parameter/model management and migrate system_config -- Created at: 2026-03-12 BEGIN; CREATE TABLE IF NOT EXISTS `sys_system_parameters` ( `param_id` bigint(20) NOT NULL AUTO_INCREMENT, `param_key` varchar(128) NOT NULL, `param_name` varchar(255) NOT NULL, `param_value` text, `value_type` varchar(32) NOT NULL DEFAULT 'string', `category` varchar(64) NOT NULL DEFAULT 'system', `description` varchar(500) DEFAULT NULL, `is_active` tinyint(1) NOT NULL DEFAULT 1, `created_at` datetime DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`param_id`), UNIQUE KEY `uk_param_key` (`param_key`), KEY `idx_param_category` (`category`), KEY `idx_param_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `ai_model_configs` ( `model_id` bigint(20) NOT NULL AUTO_INCREMENT, `model_code` varchar(128) NOT NULL, `model_name` varchar(255) NOT NULL, `model_type` varchar(32) NOT NULL, `provider` varchar(64) DEFAULT NULL, `config_json` json DEFAULT NULL, `description` varchar(500) DEFAULT NULL, `is_active` tinyint(1) NOT NULL DEFAULT 1, `is_default` tinyint(1) NOT NULL DEFAULT 0, `created_at` datetime DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`model_id`), UNIQUE KEY `uk_model_code` (`model_code`), KEY `idx_model_type` (`model_type`), KEY `idx_model_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- migrate system_config parameters except model-like records INSERT INTO `sys_system_parameters` (`param_key`, `param_name`, `param_value`, `value_type`, `category`, `description`, `is_active`) SELECT d.`dict_code`, d.`label_cn`, JSON_UNQUOTE(JSON_EXTRACT(d.`extension_attr`, '$.value')), 'string', 'system', CONCAT('migrated from dict_data.system_config(', d.`dict_code`, ')'), CASE WHEN d.`status` = 1 THEN 1 ELSE 0 END FROM `sys_dict_data` d WHERE d.`dict_type` = 'system_config' AND d.`dict_code` NOT IN ('llm_model', 'voiceprint') AND JSON_EXTRACT(d.`extension_attr`, '$.value') IS NOT NULL ON DUPLICATE KEY UPDATE `param_name` = VALUES(`param_name`), `param_value` = VALUES(`param_value`), `is_active` = VALUES(`is_active`); -- migrate llm model INSERT INTO `ai_model_configs` (`model_code`, `model_name`, `model_type`, `provider`, `config_json`, `description`, `is_active`, `is_default`) SELECT 'llm_model', 'LLM文本模型', 'llm', 'dashscope', d.`extension_attr`, 'migrated from dict_data.system_config.llm_model', CASE WHEN d.`status` = 1 THEN 1 ELSE 0 END, 1 FROM `sys_dict_data` d WHERE d.`dict_type` = 'system_config' AND d.`dict_code` = 'llm_model' LIMIT 1 ON DUPLICATE KEY UPDATE `config_json` = VALUES(`config_json`), `is_active` = VALUES(`is_active`); -- migrate audio model (voiceprint) INSERT INTO `ai_model_configs` (`model_code`, `model_name`, `model_type`, `provider`, `config_json`, `description`, `is_active`, `is_default`) SELECT 'voiceprint_model', '声纹模型', 'audio', 'funasr', d.`extension_attr`, 'migrated from dict_data.system_config.voiceprint', CASE WHEN d.`status` = 1 THEN 1 ELSE 0 END, 1 FROM `sys_dict_data` d WHERE d.`dict_type` = 'system_config' AND d.`dict_code` = 'voiceprint' LIMIT 1 ON DUPLICATE KEY UPDATE `config_json` = VALUES(`config_json`), `is_active` = VALUES(`is_active`); -- ensure audio ASR model exists (from current hard-coded settings) INSERT INTO `ai_model_configs` (`model_code`, `model_name`, `model_type`, `provider`, `config_json`, `description`, `is_active`, `is_default`) SELECT 'audio_model', '音频识别模型', 'audio', 'dashscope', JSON_OBJECT( 'model', 'paraformer-v2', 'language_hints', JSON_ARRAY('zh', 'en'), 'disfluency_removal_enabled', TRUE, 'diarization_enabled', TRUE, 'speaker_count', 10, 'vocabulary_id', ( SELECT JSON_UNQUOTE(JSON_EXTRACT(extension_attr, '$.value')) FROM sys_dict_data WHERE dict_type = 'system_config' AND dict_code = 'asr_vocabulary_id' LIMIT 1 ) ), '默认音频识别模型', 1, 1 FROM dual WHERE NOT EXISTS ( SELECT 1 FROM ai_model_configs WHERE model_code = 'audio_model' ); -- add new platform submenus INSERT IGNORE INTO `sys_menus` (`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `sort_order`, `is_active`, `is_visible`, `description`) SELECT 'parameter_management', '参数管理', 'Setting', '/admin/management/parameter-management', 'link', m.`menu_id`, 8, 1, 1, '系统参数管理' FROM `sys_menus` m WHERE m.`menu_code` = 'platform_admin'; INSERT IGNORE INTO `sys_menus` (`menu_code`, `menu_name`, `menu_icon`, `menu_url`, `menu_type`, `parent_id`, `sort_order`, `is_active`, `is_visible`, `description`) SELECT 'model_management', '模型管理', 'Appstore', '/admin/management/model-management', 'link', m.`menu_id`, 9, 1, 1, '音频/LLM模型配置管理' FROM `sys_menus` m WHERE m.`menu_code` = 'platform_admin'; -- Keep existing role-menu permissions unchanged. -- New menus are added to sys_menus only; authorization is assigned manually. -- backfill menu tree metadata for newly inserted rows UPDATE `sys_menus` c JOIN `sys_menus` p ON c.`parent_id` = p.`menu_id` SET c.`menu_level` = p.`menu_level` + 1, c.`tree_path` = CONCAT(p.`tree_path`, '/', c.`menu_id`) WHERE c.`menu_code` IN ('parameter_management', 'model_management') AND (c.`tree_path` IS NULL OR c.`menu_level` = 1); COMMIT;