游乐游手机版
首页/数据库/文章详情

程序员转型:从PHP到AI+Golang,新增admin_rule模型与数据表迁移

时间:2026-07-18 21:03
在后台系统开发中,为管理员规则表创建模型与数据迁移脚本,借助AI工具生成Go模型和迁移SQL,经手动微调后插入权限数据。过程中遇到AI理解偏差,通过反复调整提示词,最终成功生成准确的AdminRule模型。

这是一个系列 Blog,作者将以一个 PHP 全栈工程师的身份,利用 AI 工具(claude code、codex、deepseek、豆包等):从零开始学习 golang 语言,并最终完成 ai-go-admin(github | gitee)开源项目的制作,全程记录分享。

从 PHP 到 AI + Golang,程序员自救转型手记(三十二):增加 admin_rule 模型及数据表迁移

上一期我们刚刚搞定 config 模型和自动迁移的优化,这期趁热打铁,把管理员规则表这块也搬过来。管理员规则表是后台系统的核心表之一——菜单结构、权限节点全都存在里面,这一步绕不开。

增加 admin_rule 模型及数据表迁移

管理员规则表,说白了就是后台导航菜单和权限节点的数据载体。既然上一期已经对自动迁移机制做了优化,这一期直接复用就行。具体操作分两步:

第一步,把管理员规则表的 SQL 给到 AI,让它帮忙生成对应的 Go 模型和迁移脚本。模型放在 internal/model/admin.go,迁移文件则是 cmd/migrate/migrations/000001_admin.up.sql000001_admin.down.sql

原始 SQL 长这样——从建表语句就能看出字段比较全面:id、pid、type(dir/menu/node 三种类型)、title、name、path、icon、open_type、url、component、keepalive、extend、remark、weigh、status,再加上 create_time 和 update_time。

CREATE TABLE `ba_admin_rule`  (
  `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `pid` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '上级规则',
  `type` enum('dir','menu','node') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'menu' COMMENT '规则类型:dir=规则目录,menu=菜单项,node=权限节点',
  `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '规则标题',
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '规则名称',
  `path` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '菜单路由路径',
  `icon` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '图标',
  `open_type` enum('tab','link','iframe') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '菜单打开方式:tab=选项卡,link=链接,iframe=Iframe',
  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '菜单 Url',
  `component` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '菜单组件路径',
  `keepalive` tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT '缓存:0=关闭,1=开启',
  `extend` enum('none','add_route_only','add_menu_only') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'none' COMMENT '扩展属性:none=无,add_route_only=只添加为路由,add_menu_only=只添加为菜单',
  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '备注',
  `weigh` int NOT NULL DEFAULT 0 COMMENT '权重',
  `status` tinyint UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态:0=禁用,1=启用',
  `update_time` bigint UNSIGNED NULL DEFAULT NULL COMMENT '更新时间',
  `create_time` bigint UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `pid`(`pid` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单和权限规则表' ROW_FORMAT = DYNAMIC;

第二步,从 src/layouts/admin/index.vue 的临时 MOCK 数据里随便抽几行权限数据出来,打印后手动插入。

AI 生成的迁移 SQL 长这样(PostgreSQL 版):

CREATE TABLE IF NOT EXISTS "__PREFIX__admin_rule" (
    "id"          bigserial PRIMARY KEY,
    "pid"         bigint DEFAULT NULL,
    "type"        varchar(50) NOT NULL DEFAULT '',
    "title"       varchar(50) NOT NULL DEFAULT '',
    "name"        varchar(50) NOT NULL DEFAULT '',
    "path"        varchar(255) NOT NULL DEFAULT '',
    "icon"        varchar(50) NOT NULL DEFAULT '',
    "open_type"   varchar(50) NOT NULL DEFAULT '',
    "url"         varchar(255) NOT NULL DEFAULT '',
    "component"   varchar(255) NOT NULL DEFAULT '',
    "keepalive"   smallint NOT NULL DEFAULT 0,
    "extend"      varchar(50) NOT NULL DEFAULT '',
    "remark"      varchar(255) NOT NULL DEFAULT '',
    "weigh"       bigint NOT NULL DEFAULT 0,
    "status"      smallint NOT NULL DEFAULT 1,
    "update_time" timestamptz,
    "create_time" timestamptz
);CREATE INDEX IF NOT EXISTS "__PREFIX__idx_admin_rule_pid" ON "__PREFIX__admin_rule" ("pid");COMMENT ON TABLE "__PREFIX__admin_rule" IS '菜单和权限规则表';
COMMENT ON COLUMN "__PREFIX__admin_rule"."id" IS 'ID';
COMMENT ON COLUMN "__PREFIX__admin_rule"."pid" IS '上级规则';
COMMENT ON COLUMN "__PREFIX__admin_rule"."type" IS '规则类型:dir=规则目录,menu=菜单项,node=权限节点';
COMMENT ON COLUMN "__PREFIX__admin_rule"."title" IS '规则标题';
COMMENT ON COLUMN "__PREFIX__admin_rule"."name" IS '规则名称';
COMMENT ON COLUMN "__PREFIX__admin_rule"."path" IS '菜单路由路径';
COMMENT ON COLUMN "__PREFIX__admin_rule"."icon" IS '菜单图标';
COMMENT ON COLUMN "__PREFIX__admin_rule"."open_type" IS '菜单打开方式:tab=选项卡,link=链接,iframe=Iframe';
COMMENT ON COLUMN "__PREFIX__admin_rule"."url" IS '菜单URL';
COMMENT ON COLUMN "__PREFIX__admin_rule"."component" IS '菜单组件路径';
COMMENT ON COLUMN "__PREFIX__admin_rule"."keepalive" IS '缓存:0=关闭,1=开启';
COMMENT ON COLUMN "__PREFIX__admin_rule"."extend" IS '扩展属性:add_route_only=只添加为路由,add_menu_only=只添加为菜单';
COMMENT ON COLUMN "__PREFIX__admin_rule"."remark" IS '备注';
COMMENT ON COLUMN "__PREFIX__admin_rule"."weigh" IS '权重';
COMMENT ON COLUMN "__PREFIX__admin_rule"."status" IS '状态:0=禁用,1=启用';
COMMENT ON COLUMN "__PREFIX__admin_rule"."update_time" IS '更新时间';
COMMENT ON COLUMN "__PREFIX__admin_rule"."create_time" IS '创建时间';

拿到迁移 SQL 之后,按惯例手动微调了一下,然后让 CC(Claude Code)基于我修改后的 @internal/middleware/admin_auth.go 重新整理管理员权限模型。

结果翻车了——@ 的文件搞错了,它以为我要整的是中间件逻辑,直接给我整出了 admin_groupadmin_group_access 表的迁移数据,还把 admin 控制器里查询 admin_group 获取登录用户权限的逻辑也给生成了。

本来只是想根据迁移 SQL 更新一下 AdminRule 模型,结果绕了一大圈,还浪费了不少 tokens。这种 AI 理解偏差在开发中确实时有发生,关键要看住,别让它跑太远。

最终生成的 AdminRule 模型倒是没毛病:

// AdminRule 菜单和权限规则模型
type AdminRule struct {
	ID         uint      `gorm:"comment:ID;primarykey;autoIncrement" json:"id"`
	Pid        *uint     `gorm:"comment:上级规则" json:"pid"`
	Type       string    `gorm:"comment:规则类型:dir=规则目录,menu=菜单项,node=权限节点;type:varchar(50);not null;default:''" json:"type"`
	Title      string    `gorm:"comment:规则标题;type:varchar(50);not null;default:''" json:"title"`
	Name       string    `gorm:"comment:规则名称;type:varchar(50);not null;default:''" json:"name"`
	Path       string    `gorm:"comment:菜单路由路径;type:varchar(255);not null;default:''" json:"path"`
	Icon       string    `gorm:"comment:菜单图标;type:varchar(50);not null;default:''" json:"icon"`
	OpenType   string    `gorm:"comment:菜单打开方式:tab=选项卡,link=链接,iframe=Iframe;type:varchar(50);not null;default:''" json:"open_type"`
	URL        string    `gorm:"comment:菜单URL;type:varchar(255);not null;default:''" json:"url"`
	Component  string    `gorm:"comment:菜单组件路径;type:varchar(255);not null;default:''" json:"component"`
	Keepalive  uint8     `gorm:"comment:缓存:0=关闭,1=开启;not null;default:0" json:"keepalive"`
	Extend     string    `gorm:"comment:扩展属性:add_route_only=只添加为路由,add_menu_only=只添加为菜单;type:varchar(50);not null;default:''" json:"extend"`
	Remark     string    `gorm:"comment:备注;type:varchar(255);not null;default:''" json:"remark"`
	Weigh      int       `gorm:"comment:权重;not null;default:0" json:"weigh"`
	Status     uint8     `gorm:"comment:状态:0=禁用,1=启用;not null;default:1" json:"status"`
	UpdateTime time.Time `gorm:"comment:更新时间" json:"update_time"`
	CreateTime time.Time `gorm:"comment:创建时间" json:"create_time"`
}func (AdminRule) TableName() string {
	return "admin_rules"
}

模型字段完整,GORM 标签和 JSON 序列化也都没问题。TableName 返回的 admin_rules 跟迁移脚本保持一致。这样一来,后台的菜单和权限体系就有了数据结构支撑,下一步就可以把前端的菜单树和后端权限校验串联起来了。

来源:https://juejin.cn/post/7660902280342601791
上一篇Airflow实现S3到DatabendCloud数据入仓编排实践 下一篇避免MongoDB文档超16MB的设计建议
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
MySQL管理工具实战指南常见用法整理
数据库 · 2026-07-18

MySQL管理工具实战指南常见用法整理

MySQL图形化管理工具可提升数据库运维效率,常见选择包括官方Workbench及Navicat、DBeaver等第三方工具。核心功能涵盖连接管理、SQL查询与调试、数据导入导出、结构同步、用户权限管理及服务器监控,均提供可视化操作,简化日常管理与性能优化。

MySQL管理工具对比指南:各类方案优缺点全面分析
数据库 · 2026-07-18

MySQL管理工具对比指南:各类方案优缺点全面分析

数据库管理工具对比显示,桌面客户端图形化界面降低操作门槛,适合本地复杂调试;Web工具免安装,便于远程协作与集中管理;命令行与编程接口利于自动化与集成。选择需根据场景,个人或小团队可选用免费桌面客户端,大型企业常组合多种工具以满足不同需求。

MySQL管理工具使用教程完整操作步骤详解
数据库 · 2026-07-18

MySQL管理工具使用教程完整操作步骤详解

MySQL管理工具分命令行与图形化两类,代表有Workbench、phpMyAdmin、Navicat等。支持创建数据库与表、执行SQL查询、管理用户权限、数据导入导出、服务器监控及性能优化,还提供备份恢复、查询分析等功能,全面满足日常开发与运维需求。

MySQL分页实战指南:常见用法详解
数据库 · 2026-07-18

MySQL分页实战指南:常见用法详解

分页查询通过LIMIT和OFFSET实现,但深度分页时性能下降明显。基于游标的分页利用唯一有序字段定位,避免扫描无效行,适用于无限滚动场景。复杂关联查询可采用延迟关联优化,先分页主键再关联。合理设计索引、避免SELECT*、监控慢查询是优化关键。

MySQL分页使用常见问题与解决方法
数据库 · 2026-07-18

MySQL分页使用常见问题与解决方法

MySQL分页通过LIMIT和OFFSET实现,但深分页时需扫描大量数据行,性能下降非常严重。基于游标的WHERE子句优化可绕开OFFSET,提升效率。常见问题包括数据一致性、COUNT(*)性能瓶颈及缺少ORDERBY导致顺序混乱等。