Files
im_server/docs/third/IM-第三方配置与文件安全SQL.sql
T

347 lines
27 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- IM 第三方配置字典与文件安全表
-- 更新时间:2026-08-23
--
-- 执行范围:
-- 1. hotgo 控制库:后台字典项与第三方配置项。
-- 2. tinode 租户业务库:文件安全审核任务表。
--
-- 注意:
-- - 本脚本不写入真实 AccessKey、Secret、密码等敏感值。
-- - 独立租户库方案下,业务表不包含 tenant_id。
-- - 多租户时,im_file_review_tasks 需要在每个租户业务库执行。
USE hotgo;
-- 1. 后台字典类型
INSERT INTO hg_sys_dict_type
(`pid`, `name`, `type`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, 'IM 存储服务商', 'im_storage_provider', 210, 'IM 文件存储 provider 字典', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_type WHERE `type` = 'im_storage_provider');
INSERT INTO hg_sys_dict_type
(`pid`, `name`, `type`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, 'IM 文件审核服务商', 'im_file_review_provider', 220, 'IM 文件审核 provider 字典', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_type WHERE `type` = 'im_file_review_provider');
INSERT INTO hg_sys_dict_type
(`pid`, `name`, `type`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, 'IM 文件审核任务类型', 'im_file_review_task_type', 230, 'IM 文件审核任务类型字典', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_type WHERE `type` = 'im_file_review_task_type');
INSERT INTO hg_sys_dict_type
(`pid`, `name`, `type`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, 'IM 文件审核状态', 'im_file_review_status', 240, 'IM 文件审核任务状态字典', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_type WHERE `type` = 'im_file_review_status');
INSERT INTO hg_sys_dict_type
(`pid`, `name`, `type`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, 'IM RTC 服务商', 'im_rtc_provider', 250, 'IM 音视频通话 RTC provider 字典', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_type WHERE `type` = 'im_rtc_provider');
INSERT INTO hg_sys_dict_type
(`pid`, `name`, `type`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, 'IM RTC 鉴权模式', 'im_rtc_auth_mode', 260, 'IM 音视频通话 RTC 鉴权模式字典', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_type WHERE `type` = 'im_rtc_auth_mode');
INSERT INTO hg_sys_dict_type
(`pid`, `name`, `type`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, 'IM RTC UID 模式', 'im_rtc_uid_mode', 270, 'IM 音视频通话 RTC UID 模式字典', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_type WHERE `type` = 'im_rtc_uid_mode');
-- 2. 后台字典数据
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '阿里云 OSS', 'oss', 'string', 'im_storage_provider', 'success', 1, 10, '阿里云对象存储 OSS', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_storage_provider' AND `value` = 'oss');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '阿里云内容安全增强版', 'aliyun_green', 'string', 'im_file_review_provider', 'info', 1, 10, 'FileModeration + document_detection', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_file_review_provider' AND `value` = 'aliyun_green');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '阿里云云安全中心', 'aliyun_sas', 'string', 'im_file_review_provider', 'warning', 1, 20, '恶意文件检测', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_file_review_provider' AND `value` = 'aliyun_sas');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '内容审核', 'content', 'string', 'im_file_review_task_type', 'info', 1, 10, '文件内容审核任务', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_file_review_task_type' AND `value` = 'content');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '恶意文件检测', 'malware', 'string', 'im_file_review_task_type', 'warning', 1, 20, '病毒、木马、WebShell 等恶意文件检测任务', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_file_review_task_type' AND `value` = 'malware');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '待处理', 'pending', 'string', 'im_file_review_status', 'default', 1, 10, '等待 worker 提交或重试', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_file_review_status' AND `value` = 'pending');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '处理中', 'running', 'string', 'im_file_review_status', 'info', 1, 20, '第三方审核任务处理中', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_file_review_status' AND `value` = 'running');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '无风险', 'clean', 'string', 'im_file_review_status', 'success', 1, 30, '审核通过或无风险', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_file_review_status' AND `value` = 'clean');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '有风险', 'risky', 'string', 'im_file_review_status', 'error', 1, 40, '命中风险标签或恶意文件', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_file_review_status' AND `value` = 'risky');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '失败', 'failed', 'string', 'im_file_review_status', 'warning', 1, 50, '不可重试失败或超过重试次数', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_file_review_status' AND `value` = 'failed');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '声网 RTC', 'agora', 'string', 'im_rtc_provider', 'success', 1, 10, '声网实时音视频 RTC', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_rtc_provider' AND `value` = 'agora');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '仅 App ID', 'app_id', 'string', 'im_rtc_auth_mode', 'warning', 1, 10, '调试模式,客户端入会 Token 为空', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_rtc_auth_mode' AND `value` = 'app_id');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 'RTC Token', 'token', 'string', 'im_rtc_auth_mode', 'success', 0, 20, '正式模式,后端使用 App Certificate 生成 Token', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_rtc_auth_mode' AND `value` = 'token');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '数字 UID', 'int', 'string', 'im_rtc_uid_mode', 'success', 1, 10, '客户端使用数字 UID 加入 RTC 频道', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_rtc_uid_mode' AND `value` = 'int');
INSERT INTO hg_sys_dict_data
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT '字符串 UID', 'string', 'string', 'im_rtc_uid_mode', 'info', 0, 20, '客户端使用字符串 UID 加入 RTC 频道', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_dict_data WHERE `type` = 'im_rtc_uid_mode' AND `value` = 'string');
-- 3. 第三方配置项。配置真值存 hg_sys_config;字典只提供 UI 选项。
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '媒体存储 Handler', 'string', 'media_handler', 'oss', 'oss', 9, 'IM 文件存储 handler;生产使用 oss,配置文件可使用 sys_config 间接读取', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'media_handler');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS 启用状态', 'bool', 'oss_enabled', '0', '0', 10, '是否启用阿里云 OSS 作为 IM 文件存储', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_enabled');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS 服务商', 'string', 'oss_provider', 'oss', 'oss', 11, '取值来自字典 im_storage_provider', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_provider');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS Endpoint', 'string', 'oss_endpoint', '', '', 12, '例如 oss-cn-shenzhen.aliyuncs.com,禁止写 AccessPoint endpoint', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_endpoint');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS Bucket', 'string', 'oss_bucket', '', '', 13, 'IM 文件对象存储 Bucket', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_bucket');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS Region', 'string', 'oss_region_id', 'cn-shenzhen', 'cn-shenzhen', 14, 'OSS Bucket 所属地域', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_region_id');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS AccessKey ID', 'string', 'oss_access_key_id', '', '', 15, '敏感配置,建议由部署环境或密钥系统注入', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_access_key_id');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS AccessKey Secret', 'string', 'oss_access_key_secret', '', '', 16, '敏感配置,后台和日志必须脱敏展示', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_access_key_secret');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS 签名 URL TTL', 'int', 'oss_presign_ttl', '120', '120', 17, '签名下载 URL 有效秒数', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_presign_ttl');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS 文件服务 URL 前缀', 'string', 'oss_serve_url', '/v0/file/s/', '/v0/file/s/', 18, 'IM 文件下载接口前缀,OSS handler 用于解析文件 ID 和返回签名跳转', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_serve_url');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS 下载缓存头', 'string', 'oss_cache_control', 'no-cache, must-revalidate', 'no-cache, must-revalidate', 19, 'OSS 签名下载响应 Cache-Control', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_cache_control');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS CORS 来源', 'string', 'oss_cors_origins', '["*"]', '["*"]', 20, 'JSON 数组或逗号分隔列表', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_cors_origins');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', 'OSS 启动校验 Bucket', 'bool', 'oss_verify_bucket', '0', '0', 21, '启动时是否调用 OSS 校验 Bucket 存在;生产可按需开启', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'oss_verify_bucket');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '文件内容安全启用状态', 'bool', 'file_review_content_enabled', '0', '0', 30, '是否启用阿里云内容安全增强版文件审核', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'file_review_content_enabled');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '内容安全 Provider', 'string', 'file_review_content_provider', 'aliyun_green', 'aliyun_green', 31, '取值来自字典 im_file_review_provider', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'file_review_content_provider');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '内容安全 Region', 'string', 'aliyun_green_region_id', 'cn-shanghai', 'cn-shanghai', 32, '阿里云内容安全增强版地域', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'aliyun_green_region_id');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '内容安全 Endpoint', 'string', 'aliyun_green_endpoint', 'green-cip.cn-shanghai.aliyuncs.com', 'green-cip.cn-shanghai.aliyuncs.com', 33, '阿里云内容安全增强版 endpoint', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'aliyun_green_endpoint');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '内容安全服务', 'string', 'aliyun_green_document_service', 'document_detection', 'document_detection', 34, 'FileModeration 服务名', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'aliyun_green_document_service');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '恶意文件检测启用状态', 'bool', 'file_review_malware_enabled', '0', '0', 40, '是否启用阿里云云安全中心恶意文件检测', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'file_review_malware_enabled');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '恶意文件检测 Provider', 'string', 'file_review_malware_provider', 'aliyun_sas', 'aliyun_sas', 41, '取值来自字典 im_file_review_provider', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'file_review_malware_provider');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '恶意文件检测 Region', 'string', 'aliyun_sas_region_id', 'cn-shanghai', 'cn-shanghai', 42, '阿里云云安全中心恶意文件检测地域', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'aliyun_sas_region_id');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '阿里云 AccessKey ID', 'string', 'aliyun_access_key_id', '', '', 90, '内容安全和恶意文件检测共用的敏感配置,建议由部署环境或密钥系统注入', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'aliyun_access_key_id');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_third_party', '阿里云 AccessKey Secret', 'string', 'aliyun_access_key_secret', '', '', 91, '内容安全和恶意文件检测共用的敏感配置,后台和日志必须脱敏展示', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_third_party' AND `key` = 'aliyun_access_key_secret');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网启用状态', 'bool', 'agora_enabled', '0', '0', 100, '是否启用声网 RTC 音视频通话', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_enabled');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_client_feature', '语音通话入口开关', 'bool', 'audio_call_enabled', '1', '1', 10, '控制 /v1/im/bootstrap features.audio_call 与 permissions.audio_call', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_client_feature' AND `key` = 'audio_call_enabled');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_client_feature', '视频通话入口开关', 'bool', 'video_call_enabled', '1', '1', 20, '控制 /v1/im/bootstrap features.video_call 与 permissions.video_call', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_client_feature' AND `key` = 'video_call_enabled');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', 'RTC 服务商', 'string', 'agora_provider', 'agora', 'agora', 101, '取值来自字典 im_rtc_provider,当前支持 agora', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_provider');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网鉴权模式', 'string', 'agora_auth_mode', 'token', 'token', 102, '取值来自字典 im_rtc_auth_mode;调试 app_id,正式 token', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_auth_mode');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网 App ID', 'string', 'agora_app_id', '', '', 103, '声网项目 App ID,可返回客户端', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_app_id');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网 App Certificate', 'string', 'agora_app_certificate', '', '', 104, '敏感配置,仅后端生成 RTC Token 使用,禁止下发客户端', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_app_certificate');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网 Token TTL', 'int', 'agora_token_ttl_seconds', '3600', '3600', 105, 'RTC Token 有效秒数,正式 token 模式使用', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_token_ttl_seconds');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网频道名前缀', 'string', 'agora_channel_prefix', 'call_', 'call_', 106, '服务端生成频道名时使用,最终为 prefix + call_id', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_channel_prefix');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网 UID 模式', 'string', 'agora_uid_mode', 'string', 'string', 107, '取值来自字典 im_rtc_uid_mode;BIGINT 用户 ID 建议 string', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_uid_mode');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网 REST Customer ID', 'string', 'agora_rest_customer_id', '', '', 108, '声网控制台 REST API 客户 ID,禁止下发客户端', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_rest_customer_id');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网 REST Customer Secret', 'string', 'agora_rest_customer_secret', '', '', 109, '声网控制台 REST API 客户密钥,必须脱敏展示', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_rest_customer_secret');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网 REST 主域名', 'string', 'agora_rest_primary_domain', 'https://api.sd-rtn.com', 'https://api.sd-rtn.com', 110, '国内控制台 REST API 主域名', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_rest_primary_domain');
INSERT INTO hg_sys_config
(`group`, `name`, `type`, `key`, `value`, `default_value`, `sort`, `tip`, `is_default`, `status`, `created_at`, `updated_at`)
SELECT 'im_shengwang', '声网 REST 备用域名', 'string', 'agora_rest_backup_domain', 'https://api.agora.io', 'https://api.agora.io', 111, '控制台 REST API 备用域名', 1, 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_sys_config WHERE `group` = 'im_shengwang' AND `key` = 'agora_rest_backup_domain');
USE tinode;
-- 4. 文件安全审核任务表
CREATE TABLE IF NOT EXISTS im_file_review_tasks (
id BIGINT NOT NULL,
task_id VARCHAR(64) NOT NULL,
file_id BIGINT NOT NULL,
user_id BIGINT NOT NULL DEFAULT 0,
task_type VARCHAR(32) NOT NULL,
provider VARCHAR(64) NOT NULL,
storage_provider VARCHAR(32) NOT NULL DEFAULT '',
object_name VARCHAR(2048) NOT NULL DEFAULT '',
mime_type VARCHAR(255) NOT NULL DEFAULT '',
file_size BIGINT NOT NULL DEFAULT 0,
provider_task_id VARCHAR(128) NOT NULL DEFAULT '',
status VARCHAR(16) NOT NULL DEFAULT 'pending',
risk_level VARCHAR(32) NOT NULL DEFAULT '',
risk_labels JSON,
result_json JSON,
error_code VARCHAR(64) NOT NULL DEFAULT '',
error_message VARCHAR(512) NOT NULL DEFAULT '',
attempts INT NOT NULL DEFAULT 0,
next_retry_at DATETIME(3),
completed_at DATETIME(3),
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 INDEX uk_im_file_review_tasks_task(task_id),
UNIQUE INDEX uk_im_file_review_tasks_file_provider(file_id, task_type, provider),
INDEX idx_im_file_review_tasks_pending(status, next_retry_at, id),
INDEX idx_im_file_review_tasks_file(file_id),
INDEX idx_im_file_review_tasks_object(storage_provider, object_name(191)),
INDEX idx_im_file_review_tasks_provider_task(provider, provider_task_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;