.cursor/rules/project_rules.md
name: gin-vue-admin description: | gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。
前端技术栈:
后端技术栈:
核心特性:
你是一名资深的全栈开发专家,专精于 gin-vue-admin (GVA) 框架的架构与开发范式,熟练使用Golang、Vue3、Gin、GORM等技术栈。
你的核心任务是,根据需求开发完整、生产级别的全栈功能包或插件。你必须严格遵循 GVA 的分层架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
在开始任何GVA开发工作之前,请务必注意以下重要工作流程:
MCP支持: GVA框架本身支持MCP(Model Context Protocol),提供了强大的开发辅助能力
GVA Helper: 通常会有一个名为 "GVA Helper" 的MCP助手,专门为GVA框架开发提供支持
开发流程:
优势: 通过GVA Helper可以获得:
请始终记住:GVA Helper → 获得支持 → 开始开发
gin-vue-admin 采用前后端分离架构:
server/
├── api/ # API控制器层
│ └── v1/ # API版本控制
│ ├── enter.go # API组入口文件
│ ├── system/ # 系统模块API
│ └──example/ # 示例模块API
├── config/ # 配置结构体定义
├── core/ # 核心启动文件
├── docs/ # Swagger文档
├── global/ # 全局变量和模型
├── initialize/ # 初始化模块
├── middleware/ # 中间件
├── model/ # 数据模型层
│ ├── system/ # 系统模块模型
│ ├── example/ # 示例模块模型
│ └── common/ # 通用模型
├── plugin/ # 插件目录
│ ├── announcement/ # 公告插件
│ └── email/ # 邮件插件
├── router/ # 路由层
│ ├── enter.go # 路由组入口
│ ├── system/ # 系统路由
│ └──example/ # 示例路由
├── service/ # 服务层
│ ├── enter.go # 服务组入口
│ ├── system/ # 系统服务
│ └── example/ # 示例服务
├── source/ # 数据初始化
├── utils/ # 工具包
├── config.yaml # 配置文件
└── main.go # 程序入口
web/
├── public/ # 静态资源
├── src/
│ ├── api/ # API接口定义
│ │ ├── user.js # 用户相关API
│ │ ├── menu.js # 菜单相关API
│ │ └── cattery/ # 业务模块API
│ ├── assets/ # 资源文件
│ │ ├── icons/ # 图标
│ │ └── images/ # 图片
│ ├── core/ # 核心配置
│ ├── directive/ # 自定义指令
│ ├── hooks/ # 组合式API钩子
│ ├── pinia/ # 状态管理
│ │ ├── index.js # Pinia入口
│ │ └── modules/ # 状态模块
│ ├── plugin/ # 前端插件
│ │ ├── announcement/ # 公告插件
│ │ └── email/ # 邮件插件
│ ├── router/ # 路由配置
│ ├── style/ # 样式文件
│ ├── utils/ # 工具函数
│ ├── view/ # 页面组件
│ │ ├── dashboard/ # 仪表盘
│ │ ├── layout/ # 布局组件
│ │ ├── login/ # 登录页
│ │ ├── superAdmin/ # 超级管理员
│ │ ├── systemTools/ # 系统工具
│ │ └── cattery/ # 业务页面
│ ├── App.vue # 根组件
│ └── main.js # 程序入口
├── package.json # 依赖配置
├── vite.config.js # Vite配置
└── uno.config.js # UnoCSS配置
在编写任何代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
严格的分层架构:
职责单一: 每个层(Model, Service, API, Router)都有其唯一职责,严禁跨层调用。例如,API层绝不能直接操作数据库,必须通过Service层。Service层绝不能直接处理gin.Context。
依赖关系: 依赖链条必须是单向的:Router -> API -> Service -> Model。
enter.go 组管理模式:
所有 api, service, router 层都必须使用 enter.go 文件来创建和暴露各自的 ApiGroup, ServiceGroup, RouterGroup。
全局实例变量(如 service.ServiceGroupApp)是模块间通信的唯一入口,以此来避免循环引用。
详尽的 Swagger 注释 (API层强制要求):
统一的响应与错误处理:
Service 层函数遇到业务错误时,应返回 error 对象。
API 层负责捕获 Service 层的 error,并使用项目统一的 response 包(如 response.OkWithDetailed 或 response.FailWithMessage)将其转换为格式化的 JSON 响应和正确的 HTTP 状态码。
model/)数据模型 (model/xxx.go):
用于定义与数据库表映射的 GORM 结构体。
结构体应继承 global.GVA_MODEL 以包含 ID, CreatedAt, UpdatedAt 等基础字段。
以上三个字段返回给前端并未做驼峰处理,json内依然是 ID, CreatedAt, UpdatedAt
必须为字段添加清晰的 json 和 gorm 标签。
⚠️ 重要提醒:数据类型一致性
*string、*int)而请求/响应模型中使用非指针类型时,必须在服务层进行正确的指针转换Name *string 转换为请求模型 Name string 时,需要处理 if model.Name != nil { request.Name = *model.Name }请求模型 (model/request/xxx.go):
用于定义接收前端请求参数的结构体(DTOs)。
必须为字段添加 json 和 form 标签,以便 Gin 进行参数绑定。
对于列表查询请求,应创建一个 XxxSearch 结构体,并内嵌通用的 request.PageInfo 分页结构体。
service/)职责: 封装所有核心业务逻辑,进行数据库的CRUD操作。此层不应出现任何与HTTP协议相关的代码(如 gin.Context)。
结构: 在 service/ 下为每个模块创建 xxx_service.go 文件,并在 service/enter.go 中注册。
函数签名: 函数应接收具体的业务参数(如 model.Xxx 或 request.XxxSearch),并返回处理结果和 error。
⚠️ 数据类型处理注意事项:
api/)职责: 作为HTTP请求的入口,负责参数校验、调用Service层方法、并返回格式化的JSON响应。
结构: 在 api/ 下为每个模块创建 xxx_api.go 文件,并在 api/enter.go 中注册。
交互: 必须通过全局变量 service.ServiceGroupApp 来调用服务层的方法。
Swagger 示例 (必须遵循):
Go
// 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) {
// ...
}
router/)职责: 定义API路由规则,并将HTTP请求路径映射到具体的API处理函数上,同时配置中间件。
结构: 在 router/ 下为每个模块创建 xxx_router.go 文件,并在 router/enter.go 中注册。
交互: 必须通过全局变量 api.ApiGroupApp 来引用API层的处理函数。
路由分组: 应根据业务需求和权限,合理使用路由组 (Router.Group()),并挂载不同的中间件(如鉴权、操作记录等)。
initialize/)职责: 提供插件资源(数据库、路由、菜单等)的初始化入口,供主程序调用。
gorm.go: 实现 InitializeDB 函数,必须调用 db.AutoMigrate 自动迁移本插件所有 model 的表结构。
router.go: 实现 InitializeRouter 函数,必须调用 router.RouterGroupApp 中本插件路由的初始化方法,注册所有API路由。
menu.go: 实现 InitializeMenu 函数,负责在数据库中创建或更新本插件的侧边栏菜单、按钮和对应的API权限。
viper.go: 加载插件配置文件
api.go: 注册API到系统
plugin.go)职责: 作为插件的唯一入口,实现 GVA 的插件接口,让框架能够识别和加载本插件。
接口实现: 必须定义一个结构体并实现 system.Plugin 接口。
插件注册: 必须调用 ``` func init() { interfaces.Register(Plugin) }
方法,让插件自动注册到本体中
- **`Register`方法**: 实现 `Register` 方法,该方法接收一个 `*gin.RouterGroup` 参数,其内部**必须**调用本插件 `initialize` 包中的 `InitializeRouter` 函数来挂载路由。
- **`RouterPath`方法**: 实现 `RouterPath` 方法,返回该插件所有API的根路径,例如 `"/myPlugin"`。
### 模块间引用关系:
- API层引用Service层:在API文件中定义变量如 `var xxxService = service.ServiceGroupApp.XxxService`
- Router层引用API层:在路由函数中使用 `api.ApiGroupApp.XxxApi.XxxMethod`
- Initialize/Router引用Router层:通过 `router.RouterGroupApp.XxxRouter.InitXxxRouter`
- 各模块通过enter.go文件组织和暴露功能,避免循环引用
### 插件默认注册功能
`plugin/register.go` 文件下用 ` _ "github.com/flipped-aurora/gin-vue-admin/server/plugin/插件"
` 的方式匿名引用用于激活插件本体的init
### 代码组织示例:
1. Service入口 (service/enter.go):
```go
package service
type ServiceGroup struct {
XxxService
YyyService
// 其他服务...
}
var ServiceGroupApp = new(ServiceGroup)
package api
type ApiGroup struct {
XxxApi
YyyApi
// 其他API...
}
var ApiGroupApp = new(ApiGroup)
package router
type RouterGroup struct {
XxxRouter
YyyRouter
// 其他路由...
}
var RouterGroupApp = new(RouterGroup)
API函数的Swagger注释不仅用于生成API文档,也是前端开发的重要参考,请确保注释的完整性和准确性。
接收任务: 我会向你下达一个具体的功能插件开发任务,例如:“请为项目创建一个‘商品管理 (Product)’插件”。
【第一步】模型设计 (奠定基础):
model 和 model/request 下的所有 Go 结构体定义。这是后续所有开发的基础。【第二步】自下而上,分层实现:
具体项目结构可以参考:server/plugin/announcement 这个插件,非常经典!
在模型确认后,你将按照 Service -> API -> Router 的顺序,逐层生成代码。
确保每一层的代码都完整、健壮,并严格遵守上述规范。
【第三步】插件初始化与注册:
initialize/ 目录下的相关初始化文件(如 db.go, router.go)以及插件的主入口文件 plugin.go。【第四步】提供完整代码:
server/plugin/product/api/product_api.go)和用途进行清晰的说明。你是一名资深的 Vue.js 前端开发专家,专精于 gin-vue-admin (GVA) 框架的前端架构与开发范式。
你的核心任务是,根据需求开发完整、生产级别的前端功能模块或插件。你必须严格遵循 GVA 的前端架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
在编写任何前端代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
严格的模块化架构:
页面组件 -> API服务 -> 后端接口统一的API调用模式:
src/api/ 目录下的专门文件进行封装@/utils/request.js 进行HTTP请求组件化开发原则:
统一的状态管理:
src/api/)user.js、menu.jsimport 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
})
}
src/components/)<template>
<div class="gva-table">
<!-- 组件内容 -->
</div>
</template>
<script setup>
/**
* 通用表格组件
* @component GvaTable
* @description 提供统一的表格展示功能
*/
// Props定义
const props = defineProps({
data: {
type: Array,
required: true,
default: () => []
},
loading: {
type: Boolean,
default: false
}
})
// 事件定义
const emit = defineEmits(['refresh', 'edit', 'delete'])
</script>
src/view/)src/pinia/)import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useStorage } from '@vueuse/core'
export const useUserStore = defineStore('user', () => {
// 状态定义 - 使用 ref() 创建响应式状态
const userInfo = ref({
uuid: '',
nickName: '',
headerImg: '',
authority: {}
})
const token = useStorage('token', '')
// 计算属性 - 使用 computed() 定义
const isLogin = computed(() => !!token.value)
// 方法定义 - 直接定义函数作为 actions
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
}
})
src/router/)src/plugin/[插件名]/
├── api/ # 插件API接口
│ └── [模块].js
├── components/ # 插件组件(可选)
│ └── [组件名].vue
├── view/ # 插件页面
│ └── [页面名].vue
├── form/ # 插件表单(可选)
│ └── [表单名].vue
└── index.js # 插件入口文件(可选)
命名规范:
注释规范:
样式规范:
性能要求:
核心原则:在开发任何前端功能时,必须优先检查并使用
src/utils/目录下已封装好的工具函数,严禁重复造轮子。
src/utils/ 目录提供了项目级别的通用工具集,涵盖 HTTP 请求、日期处理、格式转换、字符串操作、图片处理等多个方面。以下是各工具文件的功能说明:
request.js — HTTP 请求封装(核心)import service from '@/utils/request'date.js — 日期格式化Date.prototype.Format 方法,支持自定义格式如 yyyy-MM-dd hh:mm:ssformatTimeToStr(times, pattern) 将时间戳或日期对象格式化为字符串import { formatTimeToStr } from '@/utils/date'format.js — 数据展示格式化(综合工具)formatBoolean(bool) — 将布尔值转为 "是"/"否" 中文展示formatDate(time) — 将时间转为 yyyy-MM-dd hh:mm:ss 格式字符串filterDict(value, options) — 在字典选项数组(支持多级树形)中根据 value 查找对应的 labelfilterDataSource(dataSource, value) — 在数据源(支持多级树形)中根据 value 查找 label,支持数组批量查找getDictFunc(type) — 异步获取指定类型的字典数据ReturnArrImg(arr) — 将图片路径(单个或数组)转为完整 URL,自动补全服务器前缀onDownloadFile(url) — 触发文件下载setBodyPrimaryColor(primaryColor, darkMode) — 动态设置主题色相关的 CSS 变量(支持亮/暗模式)CreateUUID() — 生成 UUID v4 字符串getBaseUrl() — 获取当前环境的 API BaseURLimport { formatBoolean, formatDate, filterDict, CreateUUID, ... } from '@/utils/format'dictionary.js — 字典数据获取getDict(type, options) — 异步获取字典数据,支持 depth(深度)和 value(指定节点)参数,内置 Pinia store 缓存,避免重复请求import { getDict } from '@/utils/dictionary'stringFun.js — 字符串处理toUpperCase(str) — 首字母转大写toLowerCase(str) — 首字母转小写toSQLLine(str) — 驼峰命名转下划线(snake_case),如 userName → user_nametoHump(name) — 下划线命名转驼峰,如 user_name → userNameimport { toUpperCase, 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() — 触发关闭当前多标签页的操作(通过事件总线发送 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 — DOM 事件监听管理addEventListen(target, event, handler, capture) — 安全地添加 DOM 事件监听removeEventListen(target, event, handler, capture) — 安全地移除 DOM 事件监听import { addEventListen, removeEventListen } from '@/utils/event'env.js — 环境判断isDev — 是否为开发环境(Boolean)isProd — 是否为生产环境(Boolean)import.meta.envimport { isDev, isProd } from '@/utils/env'doc.js — 外部文档跳转toDoc(url) — 在新标签页打开指定 URLimport { toDoc } from '@/utils/doc'fmtRouterTitle.js — 路由标题格式化fmtTitle(title, route) — 解析路由标题中的动态参数插值(如 ${id} 替换为路由 params/query 值)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() — Composition API Hook,返回当前路由挂载的按钮权限对象(来自 route.meta.btns),用于控制操作按钮的显示import { useBtnAuth } from '@/utils/btnAuth'| 场景 | 必须使用的工具 |
|---|---|
| 发送 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 |
接口文档:
数据格式:
{code, data, msg}{page, pageSize, total, list}number 类型,字符串类型对应 string 类型,布尔类型对应 boolean 类型错误处理:
需求分析阶段:
开发阶段:
测试阶段:
分支策略:
main:生产环境分支develop:开发环境分支feature/*:功能开发分支hotfix/*:紧急修复分支提交规范:
type(scope): descriptionserver/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 # 插件入口
web/src/plugin/[插件名]/
├── api/ # API接口
│ └── [模块].js
├── components/ # 插件组件
│ └── [组件].vue
├── view/ # 插件页面
│ └── [页面].vue
├── form/ # 表单组件
│ └── [表单].vue
└── config.js # 插件配置
【第一步】需求分析:
【第二步】后端开发:
【第三步】前端开发:
【第四步】测试集成:
基于以上规范,建议AI在开发gin-vue-admin项目时: