gin-vue-admin 全栈开发规范指南:面向 AI 开发者的 GVA 分层架构、插件机制与代码生成实战
【免费下载链接】gin-vue-admin🚀Vite+Vue3+Gin的开发基础平台,支持TS和JS混用。它集成了JWT鉴权、权限管理、动态路由、显隐可控组件、分页封装、多点登录拦截、资源权限、上传下载、代码生成器【可AI辅助】、表单生成器和可配置的导入导出等开发必备功能。项目地址: https://gitcode.com/flipped-aurora/gin-vue-admin
gin-vue-admin(以下简称 GVA)是一个基于 Vue 3 + Vite + Go + Gin 的前后端分离管理系统框架。本文以仓库内置的 AI 开发规范文档为骨架,结合仓库真实源码逐层拆解 GVA 的分层架构、enter.go 组管理模式、前后端代码规范、工具库强制使用清单与插件开发完整流程。读完本文,你将掌握一套可直接用于为 GVA 编写生产级全栈功能包/插件的开发范式,并能在 AI 辅助编码时高效对齐项目规范。
一、技术栈与总体架构
1.1 技术栈全景
规范文档开篇即明确了 GVA 的现代技术栈基线,这些版本号来自仓库实际声明(见 server/go.mod 与 web/package.json):
- 前端:Vue 3.5.7 + Composition API、Vite 6.2.3 构建、Pinia 2.2.2 状态管理、Element Plus 2.10.2 UI 库、UnoCSS 66.4.2 原子化 CSS、Vue Router 4.4.3、Axios 1.8.2、ECharts 5.5.1、@vueuse/core 组合式工具集
- 后端:Go 1.23 + Gin 1.10.0、GORM 1.25.12 ORM、Casbin 2.103.0 权限管理、Viper 1.19.0 配置管理、Zap 1.27.0 日志、Redis 9.7.0 缓存、JWT 5.2.2 认证授权
- 多数据库:MySQL、PostgreSQL、SQLite、SQL Server、MongoDB
- 多对象存储:阿里云 OSS、AWS S3、MinIO、七牛云、腾讯云 COS 等
1.2 前后端分离与三段式目录
GVA 采用典型的前后端分离架构,仓库根目录下划分为三大区域:
- 后端服务(server/):Go + Gin 的 RESTful API 服务
- 前端应用(web/):Vue 3 + Vite 单页应用
- 部署配置(deploy/):Docker、Kubernetes 等容器化部署方案
规范文档特别强调了一个对 AI 开发至关重要的工作流:在开始任何 GVA 开发工作之前,先通过 GVA Helper MCP 助手获得支持与指导,其流程为「GVA Helper → 获得支持 → 开始开发」。仓库 server/mcp/ 目录下确实提供了完整的 MCP 服务端实现(server.go、standalone_manager.go、requirement_analyzer.go、gva_execute.go等),为 AI 助手理解并操作 GVA 项目提供了通道。
二、后端开发规范:分层架构是最高行为准则
2.1 严格的分层与单向依赖
后端规则的第一条铁律是严格的分层架构:
- 职责单一:每个层(Model、Service、API、Router)职责唯一,严禁跨层调用。API 层绝不能直接操作数据库,必须经由 Service 层;Service 层绝不能直接处理
gin.Context。 - 依赖单向:依赖链必须是
Router -> API -> Service -> Model,不可反向。
仓库 server/api/v1/system/enter.go 中可以看到 API 层对 Service 层的引用方式,全部通过全局入口service.ServiceGroupApp.SystemServiceGroup.XxxService注入,例如:
var ( apiService = service.ServiceGroupApp.SystemServiceGroup.ApiService userService = service.ServiceGroupApp.SystemServiceGroup.UserService casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService )2.2 enter.go 组管理模式
所有api、service、router层必须使用enter.go文件创建并暴露各自的ApiGroup、ServiceGroup、RouterGroup。全局实例变量是模块间通信的唯一入口,以此避免循环引用。仓库中三个真实的 enter.go 展示了这一模式的落地:
- Service 入口server/service/enter.go:
package service import ( "github.com/flipped-aurora/gin-vue-admin/server/service/example" "github.com/flipped-aurora/gin-vue-admin/server/service/system" ) var ServiceGroupApp = new(ServiceGroup) type ServiceGroup struct { SystemServiceGroup system.ServiceGroup ExampleServiceGroup example.ServiceGroup }- API 入口server/api/v1/enter.go:
var ApiGroupApp = new(ApiGroup) type ApiGroup struct { SystemApiGroup system.ApiGroup ExampleApiGroup example.ApiGroup }- Router 入口server/router/enter.go:
var RouterGroupApp = new(RouterGroup) type RouterGroup struct { System system.RouterGroup Example example.RouterGroup }各层之间的引用关系在源码中有清晰体现(server/router/system/enter.go):
- API 层引用 Service 层:
apiService = service.ServiceGroupApp.SystemServiceGroup.ApiService - Router 层引用 API 层:
dbApi = api.ApiGroupApp.SystemApiGroup.DBApi - Initialize/Router 引用 Router 层:通过
router.RouterGroupApp.XxxRouter.InitXxxRouter调用
2.3 模型层规范(model/)
- 数据模型:定义与数据库表映射的 GORM 结构体,必须继承
global.GVA_MODEL以包含基础字段。见 server/global/model.go:
type GVA_MODEL struct { ID uint `gorm:"primarykey" json:"ID"` // 主键ID CreatedAt time.Time // 创建时间 UpdatedAt time.Time // 更新时间 DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` // 删除时间 }注意:ID、CreatedAt、UpdatedAt三个字段返回前端时未做驼峰处理,JSON 中依然是ID、CreatedAt、UpdatedAt。字段必须带清晰的json和gorm标签。
请求模型(DTO):定义接收前端请求参数的结构体,必须带
json和form标签以便 Gin 绑定。列表查询请求应创建XxxSearch结构体内嵌通用request.PageInfo分页结构体——server/model/common/request/common.go 中的PageInfo定义了page、pageSize、keyword三个参数,并提供Paginate()方法:页码小于等于 0 时重置为 1,pageSize大于 100 时钳制为 100,小于等于 0 时默认为 10。⚠️ 数据类型一致性:同一字段在不同模型文件(数据模型、请求模型、响应模型)中必须保持数据类型严格一致,特别注意状态字段、ID 字段、枚举字段、时间字段。数据模型使用指针类型(
*string、*int)而请求/响应模型使用非指针类型时,必须在 Service 层做指针转换:从指针到非指针需检查 nil(if model.Name != nil { request.Name = *model.Name }),从非指针到指针需取地址。
2.4 服务层规范(service/)
- 职责是封装核心业务逻辑、执行数据库 CRUD,此层不应出现任何 HTTP 协议相关代码(如
gin.Context)。 - 在
service/下为每个模块创建xxx_service.go文件,并在service/enter.go中注册。 - 函数签名接收具体业务参数(
model.Xxx或request.XxxSearch),返回处理结果和error。 - 数据模型转换时确保字段类型一致;必须转换时添加详细注释说明原因与逻辑。
2.5 API 层规范(api/)
- 职责:HTTP 请求入口,负责参数校验、调用 Service 层方法、返回格式化 JSON 响应。
- 必须通过全局变量
service.ServiceGroupApp调用服务层方法。 - 每一个对外暴露的 API 函数都必须拥有完整准确的 Swagger 注释块。这不仅是 API 文档来源,也是前后端协作、自动化测试和前端 AI 分析的基础。规范文档给出的标准模板:
// CreateXxx 创建XXX // @Tags XxxModule // @Summary 创建一个新的XXX // @Security ApiKeyAuth // @accept application/json // @Produce application/json // @Param data body request.CreateXxxRequest true "XXX的名称和描述" // @Success 200 {object} response.Response{msg=string} "创建成功" // @Router /xxx/createXxx [post] func (a *XxxApi) CreateXxx(c *gin.Context) { // ... }2.6 路由层规范(router/)
- 职责:定义 API 路由规则,将 HTTP 请求路径映射到 API 处理函数,并配置中间件(鉴权、操作记录等)。
- 必须通过全局变量
api.ApiGroupApp引用 API 层处理函数。 - 根据业务需求和权限合理使用路由组
Router.Group(),挂载不同中间件。
2.7 初始化层规范(initialize/)
插件初始化层负责为插件提供资源(数据库、路由、菜单等)的初始化入口,规范文档明确各文件的职责:
gorm.go:实现InitializeDB,必须调用db.AutoMigrate自动迁移本插件所有 model 的表结构router.go:实现InitializeRouter,必须调用router.RouterGroupApp中本插件路由的初始化方法注册所有 API 路由menu.go:实现InitializeMenu,负责创建/更新插件的侧边栏菜单、按钮及对应 API 权限viper.go:加载插件配置文件api.go:注册 API 到系统
2.8 插件入口规范(plugin.go)
插件入口是框架识别和加载插件的唯一入口:
- 必须定义一个结构体实现
system.Plugin接口 - 必须通过
init()自动注册到本体:
func init() { interfaces.Register(Plugin) }- Register 方法:接收一个
*gin.RouterGroup参数,内部必须调用本插件initialize包中的InitializeRouter挂载路由 - RouterPath 方法:返回该插件所有 API 的根路径,例如
"/myPlugin"
以仓库内置的公告插件 server/plugin/announcement/plugin.go 为例,它完整实现了上述接口,并在Register中依次调用initialize.Api、initialize.Menu、initialize.Dictionary、initialize.Gorm、initialize.Router。
插件默认注册方式:在 server/plugin/register.go 中通过匿名导入激活插件本体的init():
import ( _ "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement" _ "github.com/flipped-aurora/gin-vue-admin/server/plugin/auto" )规范文档特别指出:server/plugin/announcement是最经典、最值得参考的插件实现范例,开发新插件时建议以其为蓝本。
三、前端开发规范:模块化与统一封装
3.1 核心原则
- 严格的模块化架构:每个模块(API、组件、页面、状态)职责单一,严禁跨模块直接调用;依赖链单向:
页面组件 -> API服务 -> 后端接口。 - 统一的 API 调用模式:所有 API 调用必须通过 web/src/api/ 下的专门文件封装,必须使用统一的
@/utils/request.js发送 HTTP 请求,API 函数必须包含完整 JSDoc 注释。 - 组件化开发:每个可复用 UI 元素必须封装为组件,遵循单一职责,带完整 props 定义与事件说明。
- 统一状态管理:全局状态必须使用 Pinia,按业务功能划分模块,严禁在组件中直接修改全局状态,必须通过 actions。
3.2 API 层规范(src/api/)
按业务模块创建 API 文件(user.js、menu.js等),统一封装:
import service from '@/utils/request' /** * 获取用户列表 * @param {Object} data 查询参数 * @param {number} data.page 页码 * @param {number} data.pageSize 每页数量 * @returns {Promise} 用户列表数据 */ export const getUserList = (data) => { return service({ url: '/user/getUserList', method: 'post', data: data }) }3.3 页面层规范(src/view/)
- 必须使用 Composition API,进行响应式数据管理
- 必须处理加载状态和错误状态,遵循 Element Plus 组件规范
- 必须优先使用 UnoCSS 原子化类名进行样式设计
- 必须优先使用
el-drawer组件进行编辑、新增、步骤等操作 - 使用
el-drawer和el-dialog组件时必须携带destroy-on-close属性,确保组件销毁,避免内存泄漏和状态污染
3.4 状态管理规范(src/pinia/)
使用 Pinia 的 setup 风格定义 store,规范文档给出的示例完整展示了userstore 的写法:ref()创建响应式状态、computed()定义计算属性、直接定义函数作为 actions、通过useStorage持久化 token:
import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { useStorage } from '@vueuse/core' export const useUserStore = defineStore('user', () => { const userInfo = ref({ uuid: '', nickName: '', headerImg: '', authority: {} }) const token = useStorage('token', '') const isLogin = computed(() => !!token.value) const setUserInfo = (val) => { userInfo.value = val } const setToken = (val) => { token.value = val } const login = async (loginForm) => { try { const res = await loginApi(loginForm) if (res.code === 0) { setUserInfo(res.data.user) setToken(res.data.token) return true } return false } catch (error) { console.error('Login error:', error) return false } } const logout = async () => { token.value = '' userInfo.value = {} } return { userInfo, token, isLogin, setUserInfo, setToken, login, logout } })四、前端工具库使用规范(强制):严禁重复造轮子
规范文档以强制语气强调:开发任何前端功能时,必须优先检查并使用 web/src/utils/ 目录下已封装好的工具函数。这是 GVA 前端开发中最容易被忽略、也最影响代码一致性的规则。
4.1 核心工具清单
| 文件 | 核心能力 | 用法 |
|---|---|---|
request.js | 基于 Axios 的统一请求实例,内置全局 Loading、JWT Token 自动注入、统一错误处理与响应拦截(仓库实现见 web/src/utils/request.js) | import service from '@/utils/request' |
date.js | 扩展Date.prototype.Format,导出formatTimeToStr(times, pattern) | import { formatTimeToStr } from '@/utils/date' |
format.js | formatBoolean、formatDate、filterDict、filterDataSource、getDictFunc、ReturnArrImg、onDownloadFile、setBodyPrimaryColor、CreateUUID、getBaseUrl等 | import { formatBoolean, CreateUUID } from '@/utils/format' |
dictionary.js | getDict(type, options),支持depth、value参数,内置 Pinia store 缓存避免重复请求 | import { getDict } from '@/utils/dictionary' |
stringFun.js | toUpperCase、toLowerCase、toSQLLine(驼峰转下划线)、toHump(下划线转驼峰) | import { toSQLLine, toHump } from '@/utils/stringFun' |
params.js | getParams(key)从 Pinia store 获取系统参数,内置缓存 | import { getParams } from '@/utils/params' |
bus.js | 基于 mitt 的全局事件总线emitter,用于跨组件通信 | import { emitter } from '@/utils/bus' |
closeThisPage.js | closeThisPage()程序化关闭当前多标签页 | import { closeThisPage } from '@/utils/closeThisPage' |
downloadImg.js | downloadImage(imgsrc, name)通过 Canvas 转 base64 下载,支持跨域 | import { downloadImage } from '@/utils/downloadImg' |
image.js | ImageCompress类,图片等比压缩至指定最大宽高并限制文件大小 | import ImageCompress from '@/utils/image' |
event.js | addEventListen/removeEventListen安全管理 DOM 事件 | import { addEventListen } from '@/utils/event' |
env.js | isDev、isProd环境判断,禁止直接读import.meta.env | import { isDev, isProd } from '@/utils/env' |
doc.js | toDoc(url)新标签页打开外部文档 | import { toDoc } from '@/utils/doc' |
fmtRouterTitle.js | fmtTitle(title, route)解析路由标题动态参数插值(如${id}) | import { fmtTitle } from '@/utils/fmtRouterTitle' |
page.js | getPageTitle(pageTitle, route)生成完整浏览器 Tab 标题 | import getPageTitle from '@/utils/page' |
asyncRouter.js | asyncRouterHandle(asyncRouter)将后端返回的路由配置(字符串 component 路径)动态转换为 Vue 组件 import 函数,支持view/与plugin/目录 | import { asyncRouterHandle } from '@/utils/asyncRouter' |
btnAuth.js | useBtnAuth()返回当前路由挂载的按钮权限对象(来自route.meta.btns),控制操作按钮显隐 | import { useBtnAuth } from '@/utils/btnAuth' |
4.2 场景强制对照表
规范文档给出了「场景 → 必须使用的工具」对照表,是审查前端代码是否符合规范的最快方式:
| 场景 | 必须使用的工具 |
|---|---|
| 发送 HTTP 请求 | @/utils/request |
| 格式化日期时间 | @/utils/date或@/utils/format中的formatDate |
| 获取字典数据 | @/utils/dictionary中的getDict |
| 布尔值/字典值展示转换 | @/utils/format中的formatBoolean/filterDict |
| 生成 UUID | @/utils/format中的CreateUUID |
| 驼峰/下划线命名转换 | @/utils/stringFun |
| 获取系统参数 | @/utils/params中的getParams |
| 按钮权限判断 | @/utils/btnAuth中的useBtnAuth |
| 跨组件事件通信 | @/utils/bus中的emitter |
| 图片下载 | @/utils/downloadImg中的downloadImage |
| 图片上传压缩 | @/utils/image中的ImageCompress |
| 关闭当前 Tab 页 | @/utils/closeThisPage中的closeThisPage |
注意:asyncRouter.js已统一处理动态路由转换逻辑,开发者不需要也不应该手动实现;env.js的引入则要求禁止直接读取import.meta.env做环境判断。
五、前后端协作规范
5.1 接口协作
- 接口文档:后端必须提供完整 Swagger API 文档;前端必须基于 Swagger 文档进行接口调用;接口变更必须提前通知并更新文档。
- 数据格式统一:
- 统一使用 JSON 进行数据交换
- 统一响应格式:
{code, data, msg} - 统一分页格式:
{page, pageSize, total, list}(与后端request.PageInfo的page/pageSize参数一一对应) - 统一时间格式:ISO 8601 标准
- ⚠️ 前后端数据类型一致性:同一字段前后端必须使用相同类型——后端 Go 结构体字段类型与前端 JS/TS 类型保持一致;数值类型对应
number,字符串对应string,布尔对应boolean。Go 指针类型在 JSON 序列化时会自动处理 nil,前端收到的是基础类型或null,无需特殊处理。 - 错误处理:后端返回标准化错误码和错误信息;前端统一处理 HTTP 状态码与业务错误码,提供用户友好的错误提示。
5.2 开发流程与版本管理
- 开发阶段:需求分析 → 后端优先开发 API 接口 → 前端基于 Mock 数据并行开发 → 定期接口联调 → 单元测试(前后端各自负责)、集成测试(前后端协作)、用户验收测试(产品团队主导)。
- 分支策略:
main(生产)、develop(开发)、feature/*(功能开发)、hotfix/*(紧急修复)。 - 提交规范:使用语义化提交信息,格式
type(scope): description,类型包括 feat、fix、docs、style、refactor、test、chore。
六、插件开发完整规范与工作流
6.1 插件目录结构
后端插件(server/plugin/[插件名]/):
server/plugin/[插件名]/ ├── api/ # API控制器 │ ├── enter.go # API组入口 │ └── [模块].go # 具体API实现 ├── config/ # 插件配置 │ └── config.go ├── initialize/ # 初始化模块 │ ├── api.go # API注册 │ ├── gorm.go # 数据库初始化 │ ├── menu.go # 菜单初始化 │ ├── router.go # 路由初始化 │ └── viper.go # 配置初始化 ├── model/ # 数据模型 │ ├── [模型].go # 数据库模型 │ └── request/ # 请求模型 ├── router/ # 路由定义 │ ├── enter.go # 路由组入口 │ └── [模块].go # 具体路由 ├── service/ # 业务服务 │ ├── enter.go # 服务组入口 │ └── [模块].go # 具体服务 └── plugin.go # 插件入口仓库中的公告插件 server/plugin/announcement/ 与自动代码插件 server/plugin/auto/ 即为该结构的实际落地范例,其中 announcement 插件被规范文档点名推荐为经典参考。
前端插件(web/src/plugin/[插件名]/):
web/src/plugin/[插件名]/ ├── api/ # API接口 │ └── [模块].js ├── components/ # 插件组件 │ └── [组件].vue ├── view/ # 插件页面 │ └── [页面].vue ├── form/ # 表单组件 │ └── [表单].vue └── config.js # 插件配置6.2 插件开发四步工作流
- 需求分析:明确插件功能和业务需求,设计数据模型和接口规范,规划前端页面与交互流程。
- 后端开发:创建数据模型和请求模型 → 实现服务层业务逻辑 → 开发 API 控制器和路由 → 编写初始化和配置代码。
- 前端开发:创建 API 接口封装 → 开发页面组件和表单 → 实现业务逻辑和状态管理 → 集成到主系统菜单。
- 测试集成:单元测试、前后端联调、用户体验测试、性能和安全测试。
6.3 插件质量标准
功能完整性(满足业务需求)、代码质量(规范、注释完整、易维护)、数据类型一致性(前后端字段类型严格一致,避免类型转换错误)、性能表现(响应快、资源占用合理)、用户体验(界面友好、错误处理完善)、兼容性(与主系统兼容)、安全性(数据安全、权限控制、防漏洞)。
七、给 AI 开发者的落地建议
基于规范文档的结尾建议与仓库现状,在 GVA 中开展 AI 辅助开发时应当遵循:
- 严格遵循分层架构:前后端代码均按 Router → API → Service → Model 单向依赖组织,杜绝跨层调用。
- 保持代码一致性:统一命名规范(文件名 kebab-case、组件名 PascalCase、变量 camelCase、常量 UPPER_SNAKE_CASE)、注释格式(API 层 Swagger 块、前端 JSDoc)与代码风格。
- 注重文档完整性:每个对外 API 的 Swagger 注释、前端 API 函数的 JSDoc、插件各文件的相对路径与用途说明缺一不可——这些文档不仅是协作基础,也是 AI 后续理解与生成代码的重要上下文。
- 优化用户体验:关注页面加载速度(路由懒加载、大列表虚拟滚动、缓存与资源优化)、交互流畅性与错误处理。
- 考虑扩展性:设计时预留扩展接口,便于后续功能增强。
- 重视安全性:实现完善的权限控制(RBAC、按钮级权限
useBtnAuth)与数据验证机制。
开发新插件时,以 server/plugin/announcement 为蓝本逐文件对照,并结合 .aone_copilot/rules/project_rules.md 中的检查要点(尤其是数据类型一致性、指针类型转换、Swagger 完整性)做最终自查,即可稳定产出符合 GVA 规范、可无缝集成到现有项目中的生产级代码。
【免费下载链接】gin-vue-admin🚀Vite+Vue3+Gin的开发基础平台,支持TS和JS混用。它集成了JWT鉴权、权限管理、动态路由、显隐可控组件、分页封装、多点登录拦截、资源权限、上传下载、代码生成器【可AI辅助】、表单生成器和可配置的导入导出等开发必备功能。项目地址: https://gitcode.com/flipped-aurora/gin-vue-admin
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考