Files
zyt/server/database/migrations/2026_09_24_ai_mcp.sql
T
2026-09-24 09:45:44 +08:00

130 lines
8.6 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.
-- AI 助手(MCP)只读查询:授权令牌、访问日志、菜单与权限点。
-- 只新增表和菜单,不修改任何已有表结构或已有菜单。可重复执行。
-- 表前缀如非 zyt_ 请整体替换。执行前请备份数据库。
--
-- 权限点(默认不授予任何角色,请在「权限管理 > 角色」中按需勾选;root 自动拥有):
-- ai.mcp/access 允许 AI 助手查询(绑定行知等客户端、调用 /mcp 的前提)
-- ai.mcp/sensitive AI 可见完整个人信息(手机号、身份证号、住址、附件地址不脱敏)
-- ai.grant/lists AI 授权管理(查看全部授权;无此权限的账号只能看、撤销自己的授权)
-- ai.grant/revoke 撤销他人的 AI 授权
-- ai.accessLog/lists AI 访问日志(查看全部;无此权限只能看自己的)
-- ai.catalog/lists AI 数据目录(查看数据资源的开放状态与覆盖率)
-- ai.mcp/tables AI 可查询后台没有页面的业务数据表(按审核配置的列和数据范围)
CREATE TABLE IF NOT EXISTS `zyt_ai_grant` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`admin_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '后台账号ID',
`token_hash` char(64) NOT NULL DEFAULT '' COMMENT '令牌 SHA-256(不保存明文)',
`token_prefix` varchar(16) NOT NULL DEFAULT '' COMMENT '令牌前缀(界面辨认用)',
`client` varchar(32) NOT NULL DEFAULT '' COMMENT '客户端,如 xingzhi',
`client_instance` varchar(64) NOT NULL DEFAULT '' COMMENT '客户端实例标识',
`label` varchar(100) NOT NULL DEFAULT '' COMMENT '备注',
`scopes` varchar(255) NOT NULL DEFAULT 'zyt.read' COMMENT '授权范围',
`pwd_fp` char(64) NOT NULL DEFAULT '' COMMENT '签发时的密码指纹,改密后授权自动失效',
`status` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '1=有效 2=已撤销 3=已过期',
`expire_time` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '绝对到期时间',
`idle_days` smallint(5) UNSIGNED NOT NULL DEFAULT 30 COMMENT '闲置多少天后失效',
`last_used_time` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最近使用时间',
`last_used_ip` varchar(45) NOT NULL DEFAULT '' COMMENT '最近使用IP',
`created_ip` varchar(45) NOT NULL DEFAULT '' COMMENT '签发时IP',
`revoke_time` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '撤销时间',
`revoke_by` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '撤销人(0=系统或客户端)',
`revoke_reason` varchar(64) NOT NULL DEFAULT '' COMMENT '撤销原因',
`create_time` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_token_hash` (`token_hash`),
KEY `idx_admin_status` (`admin_id`, `status`),
KEY `idx_client` (`client`, `client_instance`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'AI 助手授权令牌';
CREATE TABLE IF NOT EXISTS `zyt_ai_access_log` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`grant_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '授权ID',
`admin_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '后台账号ID',
`tool` varchar(64) NOT NULL DEFAULT '' COMMENT '工具或动作',
`resource` varchar(128) NOT NULL DEFAULT '' COMMENT '数据资源(权限点)',
`arguments` text NULL COMMENT '调用参数(已脱敏)',
`result_rows` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '返回条数',
`record_ids` varchar(1000) NOT NULL DEFAULT '' COMMENT '返回的记录ID(截断)',
`status` varchar(16) NOT NULL DEFAULT '' COMMENT 'ok/denied/invalid/error/limited',
`message` varchar(255) NOT NULL DEFAULT '' COMMENT '失败原因',
`duration_ms` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '耗时毫秒',
`client_task_id` varchar(64) NOT NULL DEFAULT '' COMMENT '客户端任务号(行知 X-Xingzhi-Task-Id)',
`ip` varchar(45) NOT NULL DEFAULT '' COMMENT '来源IP',
`create_time` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_admin_time` (`admin_id`, `create_time`),
KEY `idx_resource_time` (`resource`, `create_time`),
KEY `idx_task` (`client_task_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'AI 助手数据访问日志';
START TRANSACTION;
-- 目录:AI 助手
INSERT INTO `zyt_system_menu`
(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
SELECT 0, 'M', 'AI 助手', 'el-icon-MagicStick', 150, '', 'ai_mcp', '', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `zyt_system_menu` WHERE `type` = 'M' AND `paths` = 'ai_mcp');
SET @ai_root_id = (SELECT `id` FROM `zyt_system_menu` WHERE `type` = 'M' AND `paths` = 'ai_mcp' ORDER BY `id` ASC LIMIT 1);
-- 页面:AI 授权管理
INSERT INTO `zyt_system_menu`
(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
SELECT @ai_root_id, 'C', 'AI 授权管理', 'el-icon-Key', 100, 'ai.grant/lists', 'grant', 'ai_mcp/grant/index', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @ai_root_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'ai.grant/lists');
SET @ai_grant_id = (SELECT `id` FROM `zyt_system_menu` WHERE `perms` = 'ai.grant/lists' ORDER BY `id` ASC LIMIT 1);
-- 页面:AI 访问日志
INSERT INTO `zyt_system_menu`
(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
SELECT @ai_root_id, 'C', 'AI 访问日志', 'el-icon-Tickets', 90, 'ai.accessLog/lists', 'access_log', 'ai_mcp/access_log/index', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @ai_root_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'ai.accessLog/lists');
-- 页面:AI 数据目录
INSERT INTO `zyt_system_menu`
(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
SELECT @ai_root_id, 'C', 'AI 数据目录', 'el-icon-Collection', 80, 'ai.catalog/lists', 'catalog', 'ai_mcp/catalog/index', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @ai_root_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'ai.catalog/lists');
-- 按钮:撤销他人授权 / 允许 AI 助手查询 / AI 可见完整个人信息(挂在「AI 授权管理」下,便于在角色里勾选)
INSERT INTO `zyt_system_menu`
(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
SELECT @ai_grant_id, 'A', '撤销他人授权', '', 30, 'ai.grant/revoke', '', '', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @ai_grant_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'ai.grant/revoke');
INSERT INTO `zyt_system_menu`
(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
SELECT @ai_grant_id, 'A', '允许 AI 助手查询', '', 20, 'ai.mcp/access', '', '', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @ai_grant_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'ai.mcp/access');
INSERT INTO `zyt_system_menu`
(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
SELECT @ai_grant_id, 'A', 'AI 可见完整个人信息', '', 10, 'ai.mcp/sensitive', '', '', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @ai_grant_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'ai.mcp/sensitive');
INSERT INTO `zyt_system_menu`
(`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`, `create_time`, `update_time`)
SELECT @ai_grant_id, 'A', 'AI 可查询无页面的数据表', '', 5, 'ai.mcp/tables', '', '', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @ai_grant_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `zyt_system_menu` WHERE `perms` = 'ai.mcp/tables');
COMMIT;