feat(mcp): MCP 管理菜单与分发迁移

This commit is contained in:
augushong
2026-08-16 23:33:39 +08:00
parent 0d20fd7786
commit adc10d1157

View File

@@ -0,0 +1,88 @@
<?php
use think\migration\Migrator;
/**
* MCP 管理菜单数据 - 「系统管理」分组追加两条
*
* 分发背景:基础菜单结构由框架内核数据 extend/base/admin/service/adminInitData/SystemMenu.php
* (显式 id 227~311seed:run 时经 AdminInitService 写入)初始化;空库安装顺序为
* migrate:run 先于 seed:run故本迁移使用显式 id 312/313 与内核 id 序列衔接,
* 保证 sort=0 组内排在「快捷入口」(id 252) 之后菜单排序规则sort DESC, id ASC
* 即分组尾部pid=228 为内核数据中「系统管理」分组的固定 id。
*
* 节点说明auth_node 填控制器 index 节点(同 xhprof 菜单行 305~307 惯例),
* 菜单可见性由 MenuServiceBase::buildMenuChild 经 checkNode(auth_node) 精确校验;
* 动作级权限add/edit/delete/authorize/saveAuthorize/read 等)由 auth 注解节点体系承担,
* 不在菜单 auth_nodechar 100单节点表达。
*
* 幂等system_menu.href 无唯一键up 用存在性检查href + delete_time=0防重
* 经 CLIadmin:menu:create先行建行的环境重放为 no-op。
* down 与 up 对称:按 href 物理删除本迁移引入的两行。
*/
class SystemMcpMenuSeed extends Migrator
{
public function up()
{
$prefix = $this->getAdapter()->getOption('table_prefix');
$now = time();
$rows = [
[
'id' => 312,
'title' => 'MCP密钥管理',
'icon' => 'fa fa-key',
'href' => 'system.mcp_key/index',
'auth_node' => 'system.mcp_key/index',
],
[
'id' => 313,
'title' => 'MCP调用日志',
'icon' => 'fa fa-file-text-o',
'href' => 'system.mcp_log/index',
'auth_node' => 'system.mcp_log/index',
],
];
foreach ($rows as $row) {
$href = $this->quoteLiteral($row['href']);
$exists = $this->fetchRow(
"SELECT `id` FROM `{$prefix}system_menu` WHERE `href` = {$href} AND `delete_time` = 0"
);
if (!empty($exists)) {
continue;
}
$sql = sprintf(
"INSERT INTO `%ssystem_menu` (`id`, `pid`, `title`, `icon`, `href`, `auth_node`, `params`, `target`, `sort`, `status`, `remark`, `create_time`, `update_time`, `delete_time`)"
. " VALUES (%d, 228, %s, %s, %s, %s, '', '_self', 0, 1, '', %d, %d, 0)",
$prefix,
$row['id'],
$this->quoteLiteral($row['title']),
$this->quoteLiteral($row['icon']),
$this->quoteLiteral($row['href']),
$this->quoteLiteral($row['auth_node']),
$now,
$now
);
$this->execute($sql);
}
}
public function down()
{
$prefix = $this->getAdapter()->getOption('table_prefix');
$hrefs = implode(', ', [
$this->quoteLiteral('system.mcp_key/index'),
$this->quoteLiteral('system.mcp_log/index'),
]);
$this->execute("DELETE FROM `{$prefix}system_menu` WHERE `href` IN ({$hrefs})");
}
/**
* MySQL 字面量包装:单引号包裹 + 反斜杠转义(照 XhprofWatchSeed 惯例).
*/
private function quoteLiteral(string $value): string
{
return "'" . addcslashes($value, "\\") . "'";
}
}