一个基于 Gin + Vue 3 + Ant Design Vue + Vite 的 极简 MVC Web框架,专注于快速构建管理平台。
🚀 零基础也能起飞! 只需掌握一点点 Go 语法(会写
struct就够了)、一点点前端基础(知道htmlcssjs就够用),再加上对MySQL的基本理解,就能开始全栈开发之旅!🎓 甚至不需要 Vue 基础? 这个项目就是你的最佳练手场!边做边学,在实战中掌握 Vue 3,框架已帮你封装好复杂逻辑,你只需关注业务本身!
⚙️ 配置?不存在的! 繁杂的前端编译、打包、统统帮你搞定!系统已内置 Ant Design Vue、ECharts、Font Awesome 图标等常用组件,开箱即用!你只需集中精力到核心开发,告别那些烦人的配置文件!
💪 三步搞定 CRUD! 开发?三步搞定!部署?一条命令启动!从零到上线,比写 Hello World 还快!
⚡ 5 分钟搭建,10 分钟跑通,30 分钟完成第一个模块! 这不是画饼,这是真实的上手体验!🎯
🌟 拥抱开源,技术栈全明星阵容! 后端 Gin(Go 界最火的 Web 框架)、前端 Vue 3(渐进式框架的标杆)、构建工具 Vite(快如闪电的构建体验)——全部采用最流行、最成熟的开源技术!这意味着你可以随心所欲地添加任何你需要的功能:想接入 ChatGPT?没问题!想集成支付系统(微信/支付宝)?轻松搞定!想加个实时聊天?WebSocket 走起!想做个数据大屏?ECharts 已内置!想接入第三方登录?OAuth 2.0 安排上!开源生态就是你的武器库,想怎么玩就怎么玩!🚀
😎 先看效果、再看原理——直接感受 gin-vue-web 带来的“所见即所得”!
列表页 · 搜索/排序/分页
|
新增弹窗
|
编辑弹窗
|
关联管理弹窗
|
改动日志
|
导航树
|
路由列表
|
角色管理
|
角色授权
|
个人中心
|
公共组件库
|
Echarts用例
|
图标库 |
gin-vue-web 是一个企业级全栈 Web 开发框架,专为快速构建现代化管理平台而生。采用前后端分离架构,基于 Go 和 Vue 3 生态,通过约定优于配置的设计理念,将传统 CRUD 开发效率提升 10 倍以上。
框架采用经典的 MVC(Model-View-Controller)架构模式,通过智能约定和自动装配,将传统开发中的样板代码减少 80% 以上。开发者只需关注业务逻辑,框架自动处理路由、数据绑定、表单验证等繁琐工作。
核心优势:
- 零配置启动:无需编写配置文件,开箱即用
- 约定优于配置:遵循最佳实践,减少决策成本
- 高度可扩展:支持自定义中间件、拦截器、扩展点
- 性能卓越:基于 Gin 高性能框架,轻松应对高并发场景
框架通过 Go 反射机制自动扫描 Controller 中的 Action* 方法,实现路由的零配置自动注册。告别手动维护路由表的时代,只需定义方法,路由自动生成并注册。
技术亮点:
- 反射扫描:自动识别
ActionIndex、ActionEdit、ActionSave等方法 - RESTful 风格:自动生成符合 RESTful 规范的路由
- 类型安全:编译期检查,避免运行时错误
- 自动文档:支持自动生成 API 文档
框架围绕三个核心文件构建了一套完整的通用 CRUD 解决方案,实现了从数据模型到前端页面的全自动生成。
核心文件架构:
| 文件 | 职责 | 技术栈 |
|---|---|---|
backend/g/x.go |
CRUD 核心逻辑引擎 | Go + XORM |
frontend/src/templates/index.vue |
通用列表页模板 | Vue 3 + Ant Design Vue |
backend/g/rule.go |
字段规则配置引擎 | JSON 配置驱动 |
功能矩阵:
| 功能模块 | 支持特性 | 说明 |
|---|---|---|
| 列表页 | 搜索、排序、分页、筛选 | 支持多字段组合查询 |
| 数据操作 | 新增、编辑、删除 | 单条和批量操作 |
| 数据验证 | 前端 + 后端双重验证 | 类型检查、必填验证、格式验证 |
| 权限控制 | 基于角色的访问控制 | 细粒度权限管理 |
通过 rule.json 配置文件,采用声明式编程方式定义字段规则,实现真正的配置驱动开发。一次配置,全栈生效。
规则配置能力:
- 显示规则:字段标签、显示顺序、是否可见、格式化方式
- 验证规则:必填验证、类型验证、长度限制、正则表达式
- 搜索规则:精确匹配、模糊搜索、范围查询、IN 查询、关联查询
- 交互规则:下拉选项、级联选择、日期范围、文件上传
优势:
- 零代码配置:无需编写验证逻辑
- 前后端同步:一次配置,前后端自动同步
- 业务聚焦:专注业务逻辑,而非技术细节
- 快速迭代:修改配置即可调整功能
框架内置了开箱即用的企业级基础功能模块,覆盖了 90% 的管理系统通用需求,让你从第一天就开始构建业务功能。
功能清单:
| 功能模块 | 技术实现 | 特性说明 |
|---|---|---|
| 用户认证 | Session | 支持登录、注册、账号切换 |
| 权限管理 | RBAC + 路由守卫 | 基于角色和路由的细粒度权限控制 |
| 菜单管理 | 动态菜单树 | 支持多级菜单、图标、权限绑定 |
| 会话管理 | Redis 分布式会话 | 支持集群部署、会话共享 |
| 操作日志 | 自动记录 + 回滚 | 自动记录数据变更,支持查看详情和回滚操作 |
| 组件库 | Ant Design Vue | 60+ 高质量组件,开箱即用 |
| 图表库 | ECharts | 20+ 图表类型,支持数据可视化 |
| 图标库 | Font Awesome | 1000+ 图标,满足各种场景需求 |
操作日志功能详解:
框架内置了强大的**操作日志(op-log)**功能,能够自动记录所有数据变更操作,并提供完整的审计和回滚能力。
核心特性:
- 自动记录:根据
op.json配置,自动记录 core 数据库中所有配置表的数据变更 - 事件聚合:同一请求中的多条数据变更自动聚合为一个操作事件
- 详细记录:记录操作类型(新增/更新/删除)、数据表、数据ID、变更前后数据
- 差异对比:智能计算并展示字段级别的变更差异,支持字段翻译和格式化显示
- 一键回滚:支持将数据回滚到变更前的状态,自动处理依赖关系检查
- 审计追踪:记录操作用户、操作路径、操作时间等完整审计信息
工作原理:
- 在
op.json中配置需要记录的表(仅限 core 数据库) - 框架在数据保存/删除时自动检测并记录变更
- 同一请求中的多条变更通过 UUID 关联,聚合为一个操作事件
- 操作事件存储在
base数据库的op_event表 - 具体变更详情存储在
base数据库的op_log表
依赖关系检查机制:
框架在回滚操作前会自动检查数据依赖关系,确保数据一致性。这是操作日志功能的核心设计,防止因回滚导致的数据不一致问题。
为什么需要依赖检查?
数据库的改动必须遵循主键-外键依赖关系,否则会导致数据不一致。例如:如果 b.a_id = a.id(表 b 的外键引用表 a 的主键),那么在删除数据 a 之前,必须先删除数据 b,否则数据 b 将无法映射到有效的主键,造成数据不一致。
三种依赖关系类型:
-
同一条数据的连续改动依赖
- 场景:同一条数据经历了多次连续改动,如
a -> b -> c - 规则:如果回滚
a -> b,则必须同时回滚b -> c,因为操作 2 依赖于操作 1 的结果 - 示例:用户先修改了订单状态为"已支付",后又修改为"已发货"。回滚"已支付"状态时,必须同时回滚"已发货"状态
- 场景:同一条数据经历了多次连续改动,如
-
主键依赖(新增数据被引用)
- 场景:操作 1 新增了数据 a,操作 2 改动(或新增)数据 b,改动后
b.a_id = a.id - 规则:如果回滚操作 1(删除新增的 a),则必须同时回滚操作 2,因为操作 2 依赖于操作 1 创建的主键
- 示例:先创建了分类 A(id=100),后创建了文章 B 并设置
category_id=100。回滚创建分类 A 时,必须同时回滚创建文章 B
- 场景:操作 1 新增了数据 a,操作 2 改动(或新增)数据 b,改动后
-
外键依赖(删除被引用的数据)
- 场景:操作 1 改动(或删除)数据 b,改动前
b.a_id = a.id;操作 2 删除了数据 a - 规则:如果回滚操作 1,则必须同时回滚操作 2,否则
b.a_id将无法映射到有效的主键 - 示例:先修改了订单的客户ID为 200,后删除了客户 200。回滚修改订单时,必须同时回滚删除客户,否则订单的客户ID将指向不存在的记录
- 场景:操作 1 改动(或删除)数据 b,改动前
配置方式:
在 op.json 中通过 primary 字段配置主键-外键关系:
{
"table_a": {
"name": "表A",
"db": "core",
"show": ["field1", "field2"],
"primary": {
"id": {
"table_b": "a_id",
"table_c": "a_id"
}
}
}
}配置说明:
primary:定义主键被哪些表的外键引用"id":主键字段名"table_b": "a_id":表 table_b 的外键字段a_id引用了表 table_a 的主键id
检查流程:
- 用户选择要回滚的操作事件
- 框架调用
CheckRely()递归检查所有依赖关系 - 如果发现依赖,自动收集所有需要一起回滚的操作事件
- 前端展示完整的回滚列表,用户确认后统一回滚
- 所有回滚操作在同一事务中执行,保证原子性
设计优势:
- 自动化:无需手动分析依赖关系,框架自动检测
- 安全性:防止因回滚导致的数据不一致问题
- 完整性:递归检查,确保所有相关操作都被正确处理
- 透明性:清晰展示需要回滚的所有操作,用户可确认后再执行
使用场景:
- 数据审计:追踪谁在什么时候修改了什么数据
- 错误恢复:快速回滚误操作,恢复数据到之前的状态
- 合规要求:满足企业级数据变更审计和合规要求
- 问题排查:通过操作历史快速定位问题原因
扩展能力:
- 插件机制:支持自定义插件扩展
- 主题定制:支持主题切换和自定义样式
- 国际化:内置 i18n 支持,轻松实现多语言
- 响应式设计:完美适配 PC、平板、移动端
Go 安装:
- 下载地址:https://golang.org/dl/ 或 https://golang.google.cn/dl/
- 推荐版本:Go 1.25.0 及以上
- 安装后验证:
go version
Node.js 安装:
- 下载地址:https://nodejs.org/
- 推荐版本:Node.js v24.9.0 及以上(包含 npm)
- 安装后验证:
node -v和npm -v
MySQL 安装:
- 下载地址:https://dev.mysql.com/downloads/mysql/
- 或使用 Docker:
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=yourpassword mysql:8.0 - 创建两个数据库实例
base和core分别用于存储基础数据和业务数据 - 执行初始化 SQL(见
docs/sql/init_base.sql和docs/sql/init_core.sql)
Redis 安装:
- Windows:下载 https://github.com/microsoftarchive/redis/releases 或使用 WSL
- Linux/Mac:
sudo apt-get install redis-server或brew install redis - 或使用 Docker:
docker run -d -p 6379:6379 redis:latest - 启动后验证:
redis-cli ping(应返回PONG)
编辑 backend/cfg.json 注意调整数据库和redis链接为你的真实地址
cd backend
go mod tidy
go build
./backend后端默认运行在 http://localhost:3000
cd frontend
npm install
npm run dev -- --host 0.0.0.0前端默认运行在 http://localhost:5173 和 http://{真实服务器IP}:5173
建议使用 http://{真实服务器IP}:5173 登录,管理员账号密码 admin/Admin321!
详细的部署说明,包括生产环境配置、Nginx 配置、Docker 部署等,请查看 部署文档。
gin-vue-web 采用经典的前后端分离架构。理解这个架构是阅读代码的第一步。
前后端分离意味着什么?
简单来说,前端(Vue 3)和后端(Go)是完全独立的两个应用。它们通过 HTTP API 进行通信,前端负责展示和交互,后端负责数据处理和业务逻辑。这种架构的好处是前后端可以独立开发、部署和维护。
项目目录结构
gin-vue-web/
├── backend/ # 后端代码(Go)
│ ├── g/ # 核心框架代码
│ │ ├── x.go # CRUD 核心逻辑(X 结构体)
│ │ ├── xb.go # 批量操作扩展(XB 结构体)
│ │ ├── rule.go # 规则配置处理
│ │ ├── action.go # 路由自动注册
│ │ ├── web.go # Web 基础功能
│ │ └── model.go # 基础模型
│ ├── modules/ # 业务模块
│ │ ├── base/ # 基础模块(用户、角色等)
│ │ │ ├── controllers/ # 控制器
│ │ │ └── models/ # 数据模型
│ │ └── res/ # 资源模块(示例)
│ │ ├── controllers/
│ │ └── models/
│ ├── libs/ # 工具库
│ ├── main.go # 入口文件
│ └── rule.json # 字段规则配置
│
├── frontend/ # 前端代码(Vue 3)
│ ├── src/
│ │ ├── components/ # 通用组件
│ │ │ ├── searcher.vue # 搜索器
│ │ │ ├── table.vue # 数据表格
│ │ │ ├── pager.vue # 分页器
│ │ │ ├── edit.vue # 编辑表单
│ │ │ └── ...
│ │ ├── modules/ # 业务页面
│ │ ├── templates/ # 页面模板
│ │ │ ├── index.vue # 通用列表页模板
│ │ │ ├── layout.vue # 布局模板
│ │ │ └── ...
│ │ ├── libs/ # 工具库
│ │ │ └── lib.ts # 核心工具函数
│ │ └── app.vue # 根组件
│ └── package.json
│
└── docs/ # 文档
这个目录包含了框架的所有核心功能。让我们逐个了解每个文件的作用:
x.go - CRUD 核心逻辑
这是整个框架最重要的文件。X 结构体封装了完整的 CRUD(增删改查)功能。当你创建一个 Controller 并继承 X 结构体时,你就自动获得了列表查询、数据获取、新增、编辑、删除等所有功能。
X 结构体包含了很多字段,每个字段都有特定的作用:
DB:数据库连接,用于执行 SQL 查询Model:数据模型,定义了要操作的数据表结构Rules:字段规则,从rule.json加载,控制字段的显示、验证、搜索等行为Tool:工具栏按钮配置,比如"新增"按钮Option:行操作按钮配置,比如每行的"编辑"、"删除"按钮AndWheres:固定查询条件,比如只显示已发布的数据WrapData:数据处理函数,可以在返回数据前进行自定义处理Dump:开启后在列表页展示"导出"按钮,可将当前搜索结果导出为 Excel,便于离线分析
xb.go - 批量操作扩展
XB 是 X 的扩展版本,专门用于支持批量操作。如果你需要批量编辑或批量删除功能,使用 XB 而不是 X。它会在工具栏自动添加"批量修改"和"批量删除"按钮。
rule.go - 规则配置处理
这个文件负责加载和解析 rule.json 配置文件。rule.json 定义了每个表的字段规则,比如字段是否必填、是否可搜索、下拉选项是什么等等。框架会根据这些规则自动生成搜索表单、数据表格和编辑表单。
action.go - 路由自动注册
这是框架的"魔法"所在。通过 Go 的反射机制,框架会自动扫描所有 Controller 中以 Action 开头的方法,然后自动注册为路由。这意味着你不需要手动编写路由表,只需要定义方法,路由就会自动生成。
web.go - Web 基础功能
提供页面渲染、JSON 响应、Session 管理等基础功能。这些是 Web 应用的基础能力,被 X 结构体继承使用。
业务代码按模块组织,每个模块代表一个业务领域。比如 base 模块包含用户、角色等基础功能,res 模块可能包含资源管理相关的功能。
每个模块通常包含两个目录:
models/:数据模型,定义了数据库表的结构controllers/:控制器,处理 HTTP 请求,调用模型进行数据操作
一个典型的模块结构
以 Service 模块为例,它包含:
models/service.go:定义了 Service 数据模型,包含名称、业务类型、状态等字段controllers/service.go:定义了 Service 控制器,继承g.XB,自动获得所有 CRUD 功能
这种结构清晰明了,模型负责数据结构,控制器负责业务逻辑。
app.vue - 根组件
这是整个前端应用的入口。它监听路由变化,当用户访问不同页面时,它会调用后端 API 获取页面配置,然后动态加载对应的 Vue 组件。这种设计使得页面可以完全由后端控制,前端只需要负责渲染。
libs/lib.ts - 核心工具函数
这个文件提供了前端最常用的工具函数:
curl():调用后端 API,会自动添加/web前缀,处理请求和响应loadModal():加载模态框组件,用于编辑、新增等弹窗操作loadComponent():动态加载 Vue 组件smartUrl():智能处理 URL,将相对路径转换为绝对路径
这些函数封装了前后端交互的细节,让你可以专注于业务逻辑。
templates/index.vue - 通用列表页模板
这是框架提供的通用列表页模板。它根据后端返回的规则配置,自动生成搜索表单、数据表格、分页器等组件。你不需要为每个列表页都写一遍这些代码,框架已经帮你做好了。
框架提供了一系列通用组件,这些组件都是可复用的:
searcher.vue:搜索器组件,根据规则自动生成搜索表单table.vue:数据表格组件,支持排序、选择、行操作pager.vue:分页器组件edit.vue:编辑表单组件,根据规则自动生成表单字段button.vue:按钮组件,支持不同类型的按钮样式
这些组件都是基于 Ant Design Vue 构建的,提供了统一的 UI 风格和交互体验。
阅读代码是一个循序渐进的过程,建议按照以下顺序:
第一步:从入口开始
了解应用的启动流程很重要。后端从 main.go 开始,它会初始化数据库、加载配置、注册路由。前端从 main.ts 开始,它会创建 Vue 应用、注册路由、挂载到 DOM。
第二步:理解核心框架
重点阅读 backend/g/x.go,这是整个框架的核心。理解 X 结构体如何工作,它的每个方法做了什么,这是理解整个框架的关键。
同时,理解 rule.json 如何驱动前端表单和后端验证。这是框架"配置驱动"理念的体现。
第三步:跟踪数据流
选择一个具体的功能(比如列表查询),从前端请求开始,跟踪数据如何流转:
- 前端发起请求
- 后端接收请求
- 构建查询条件
- 执行数据库查询
- 处理返回数据
- 返回给前端
- 前端更新界面
理解这个流程,你就能理解整个系统是如何工作的。
第四步:查看示例代码
参考 modules/base/ 和 modules/res/ 中的示例代码。这些是实际可用的代码,可以帮助你理解如何在实际项目中使用框架。
X 结构体是整个框架的核心,理解它是理解整个框架的关键。
框架采用了"约定优于配置"的设计理念。这意味着框架定义了一套约定,只要你遵循这些约定,框架就能自动帮你完成大部分工作。
比如,你只需要:
- 定义数据模型(Model)
- 配置字段规则(rule.json)
- 创建 Controller 并继承
X
框架就会自动为你生成:
- 列表页
- 搜索功能
- 新增功能
- 编辑功能
- 删除功能
你不需要写大量的样板代码,框架已经帮你做好了。
X 结构体提供了五个核心方法,对应 CRUD 的五个操作:
ActionIndex - 列表页渲染
当用户访问列表页时,这个方法会被调用。它会:
- 从
rule.json加载字段规则 - 构建工具栏按钮和行操作按钮
- 获取 URL 参数(用于搜索条件)
- 渲染前端模板,传递所有配置信息
前端模板会根据这些配置自动生成搜索表单、数据表格等组件。
ActionFetch - 数据获取
这是列表页获取数据的核心方法。当用户搜索、排序、翻页时,前端会调用这个方法。
它的工作流程是:
- 接收前端传递的搜索参数、排序参数、分页参数
- 根据
rule.json中的search配置,构建 SQL 查询条件 - 执行数据库查询,获取总数和数据列表
- 调用
WrapData处理数据(比如翻译外键 ID 为显示名称) - 返回 JSON 格式的数据给前端
ActionEdit - 编辑页渲染
当用户点击"新增"或"编辑"按钮时,这个方法会被调用。它会:
- 判断是新增还是编辑(通过 URL 参数中的
id) - 如果是编辑,从数据库加载现有数据
- 从
rule.json加载字段规则 - 渲染编辑表单模板,传递数据和规则
前端模板会根据规则自动生成表单字段,包括输入框、下拉选择、多行文本等。
ActionSave - 数据保存
当用户提交表单时,这个方法会被调用。它会:
- 判断是新增还是编辑
- 解析请求体中的数据
- 根据
rule.json中的required配置进行验证 - 处理特殊字段(比如 JSON 字段、分隔符字段)
- 保存到数据库(使用事务保证数据一致性)
- 返回成功或失败信息
ActionDelete - 数据删除
当用户点击"删除"按钮时,这个方法会被调用。它会:
- 从 URL 参数获取要删除的数据 ID
- 从数据库查询数据是否存在
- 调用模型的
Delete方法删除数据(使用事务) - 返回成功信息
buildCondition 方法负责根据搜索参数构建 SQL 查询条件。这是框架"规则驱动"的典型体现。
框架会根据 rule.json 中每个字段的 search 配置来决定如何构建查询条件:
search: 0:不搜索,忽略该字段search: 1:精确匹配,生成WHERE field = valuesearch: 2:模糊搜索,生成WHERE field LIKE '%value%'search: 3:IN 查询,生成WHERE field IN (value1, value2, ...)
这样,你只需要在 rule.json 中配置搜索类型,框架就会自动处理,不需要写 SQL 代码。
XB 是 X 的扩展版本,专门用于支持批量操作。
在实际业务中,经常需要对多条数据进行批量操作。比如批量修改状态、批量删除等。如果使用 X,你需要自己实现这些功能。而 XB 已经帮你实现了。
XB 使用 Go 的泛型特性,确保类型安全。它继承自 X,所以拥有 X 的所有功能,同时新增了三个方法:
ActionBatchEdit:批量编辑,显示一个表单,可以选择要修改的字段ActionBatchSave:批量保存,将修改应用到选中的多条数据ActionBatchDelete:批量删除,删除选中的多条数据
当你使用 XB 时,框架会自动:
- 在工具栏添加"批量修改"和"批量删除"按钮
- 在表格中启用多选功能
- 注册批量操作的路由
你不需要写任何额外的代码,只需要将 g.X 改为 g.XB 即可。
rule.json 是框架的核心配置文件,它定义了每个表的字段规则。这是框架"配置驱动"理念的体现。
通过 rule.json,你可以定义:
- 字段的显示名称(用于表单标签、表格列头)
- 字段是否必填(用于表单验证)
- 字段的搜索类型(用于构建查询条件)
- 字段的下拉选项(用于生成下拉选择框)
- 字段的翻译规则(用于将外键 ID 转换为显示名称)
- 字段的验证规则(用于在后端保存前做类型、范围、正则等校验)
框架会根据这些规则自动生成前端表单和后端验证逻辑,你不需要写代码。
基础字段
key:字段名,对应数据库表的列名name:显示名称,用于表单标签、表格列头required:是否必填,true表示该字段在保存时必须填写readonly:是否只读,true表示该字段在编辑页中不可编辑default:默认值,新增数据时自动填充
搜索配置
search 字段控制该字段在列表页的搜索行为:
0:不搜索,该字段不会出现在搜索表单中1:精确匹配,搜索时使用WHERE field = value2:模糊搜索,搜索时使用WHERE field LIKE '%value%'3:IN 查询,支持选择多个值,搜索时使用WHERE field IN (value1, value2, ...)
显示配置
textarea:是否多行文本输入框,true使用<textarea>,false使用<input>json:是否 JSON 字段,需要同时设置textarea: true,框架会自动验证和格式化 JSONbold:是否加粗显示,用于表格列hide:是否在表格中隐藏,true表示该字段不在表格中显示width:列宽度,用于表格列
下拉选项配置
limit 字段用于定义下拉选项列表。每个选项包含:
key:选项的值(存储到数据库的值)label:选项的显示文本(用户看到的文本)badge:选项的徽章样式(用于表格显示,如 "success"、"danger" 等)
翻译配置(Trans)
- 验证配置
validation字段用于配置详细的输入验证规则。你可以声明字段必须是整数/浮点数、设置最小/最大区间、限定为合法 IP(IPv4/IPv6),或提供自定义正则表达式。所有校验在ActionSave中统一执行,保证无效数据无法写入数据库。
trans 字段用于将外键 ID 转换为显示名称。这在关联查询中非常有用。
比如,文章表有一个 category_id 字段,存储的是分类的 ID。但在显示时,我们希望显示分类的名称而不是 ID。
通过配置 trans,框架会自动查询分类表,将 ID 转换为名称。如果数据量很大,可以设置 ajax: true,使用 AJAX 动态加载选项。
框架在启动时会调用 initRules() 加载 rule.json 文件,解析成内存中的数据结构。当创建 X 结构体时,会根据模型的表名(TableName())从规则中查找对应的配置。
当需要使用时,框架会调用 SelfWrap() 方法处理规则,比如:
- 处理下拉选项,生成选项列表和映射
- 处理翻译配置,如果是非 AJAX 模式,会查询数据库生成选项列表
路由自动注册是框架的一大特色,它让你不需要手动维护路由表。
框架通过 Go 的反射机制,自动扫描所有 Controller 中以 Action 开头的方法,然后自动注册为路由。
工作流程是:
- 你调用
RegController()注册 Controller - 框架使用反射获取 Controller 的所有方法
- 筛选出以
Action开头的方法 - 将方法名转换为路由路径(驼峰转短横线)
- 注册为 POST 路由
路由的格式是:/{module}/{controller}/{action}
比如:
ActionIndex→/res/service/indexActionFetch→/res/service/fetchActionBatchEdit→/res/service/batch-edit
方法名必须遵循以下规范:
- 必须以
Action开头 - 使用驼峰命名(如
ActionBatchEdit) - 接收
*gin.Context参数
只要遵循这些规范,框架就能自动识别并注册路由。
框架还会自动将注册的路由保存到数据库的 action 表中。这个表用于权限管理,可以控制哪些用户能访问哪些路由。
理解数据如何在前后端之间流转,是理解整个系统的关键。
让我们跟踪一个完整的请求流程:
第一步:用户访问页面
用户在浏览器中输入 URL,比如 /res/service/index。
第二步:前端路由处理
Vue Router 捕获路由变化,app.vue 组件监听到路由变化。
第三步:前端调用后端 API
app.vue 调用 lib.curl('/res/service/index'),lib.ts 会自动添加 /web 前缀,最终请求 POST /web/res/service/index。
第四步:后端路由匹配
Gin 框架匹配到对应的路由,找到 Service Controller 的 ActionIndex 方法。
第五步:后端处理请求
X.ActionIndex() 方法被调用:
- 从
rule.json加载字段规则 - 构建工具栏按钮和行操作按钮
- 获取 URL 参数(用于搜索条件)
- 渲染前端模板
templates/index.vue,传递所有配置
第六步:前端渲染页面
前端接收到页面配置,动态加载 templates/index.vue 模板。模板根据规则自动生成:
- 搜索表单(根据
search配置) - 数据表格(根据字段规则)
- 工具栏按钮
- 行操作按钮
第七步:前端获取数据
页面渲染完成后,templates/index.vue 自动调用 lib.curl('fetch', params) 获取数据。请求 POST /web/res/service/fetch。
第八步:后端查询数据
X.ActionFetch() 方法被调用:
- 解析请求参数(搜索、排序、分页)
- 根据
rule.json的search配置构建查询条件 - 执行数据库查询
- 调用
WrapData处理数据(翻译外键等) - 返回 JSON 格式的数据
第九步:前端更新界面
前端接收到数据,更新响应式变量,Vue 自动重新渲染表格,显示数据。
当用户在搜索框中输入内容并点击搜索时:
- 前端收集所有搜索字段的值,组成一个对象
- 调用
lib.curl('fetch', {arg: searchParams, sort: sortParams, page: pageParams}) - 后端
ActionFetch接收参数 - 遍历搜索参数,对每个字段:
- 查找对应的规则配置
- 根据
search类型构建查询条件 - 精确匹配用
WHERE field = value - 模糊搜索用
WHERE field LIKE '%value%' - IN 查询用
WHERE field IN (value1, value2, ...)
- 执行 SQL 查询
- 返回结果数据
当用户填写表单并点击保存时:
- 前端收集表单数据,组成一个对象
- 调用
lib.curl('save', formData)或lib.curl('save?id=123', formData)(编辑时) - 后端
ActionSave接收请求 - 判断是新增还是编辑(通过 URL 参数中的
id) - 如果是编辑,先从数据库加载现有数据
- 解析请求体,将 JSON 数据反序列化到模型
- 根据
rule.json的required配置验证必填字段 - 处理特殊字段:
- JSON 字段:验证和格式化 JSON
- 分隔符字段:处理多行文本,去除分隔符
- 调用模型的
Save方法保存到数据库(使用事务) - 返回成功或失败信息
在实际开发中,经常需要根据浏览器的请求找到对应的后端代码。这是一个非常重要的调试技能。
打开浏览器开发者工具(按 F12),切换到 Network(网络)标签。当你执行操作(比如搜索、保存)时,会看到网络请求列表。找到对应的请求,点击查看详情。
框架的请求格式是:POST /web/{module}/{controller}/{action}
比如看到 POST /web/res/service/fetch,可以解析出:
module:rescontroller:serviceaction:fetch
根据解析出的信息,可以快速定位代码:
- 查找 Controller 注册
在 backend/modules/router.go 中搜索 RegController("res", "service",找到注册代码。
- 查找 Controller 文件
根据 module 和 controller 名称,找到文件:backend/modules/res/controllers/service.go
- 查找 Action 方法
如果 Controller 继承自 g.X 或 g.XB,ActionFetch 方法在 backend/g/x.go 中。如果是自定义方法,就在 Controller 文件中。
找到代码后,可以添加日志或断点进行调试:
使用日志调试
在代码中添加 logrus.Infof() 输出关键信息,比如参数值、查询条件等。这是最简单直接的调试方法。
使用调试器
如果使用 GoLand 或 VS Code,可以设置断点进行调试。这是最强大的调试方法,可以查看变量值、单步执行等。
有时候需要根据页面上的元素找到对应的 Vue 组件代码。
打开开发者工具,使用元素选择器(Ctrl+Shift+C 或点击左上角的图标),然后点击页面上的元素。
如果安装了 Vue DevTools 扩展(强烈推荐),可以:
- 切换到 Vue 标签
- 选择元素,查看对应的组件
- 查看组件的 props、data、methods 等
Vue DevTools 是调试 Vue 应用的最佳工具,可以清楚地看到组件树、响应式数据、事件触发等。
通过组件名
在 Vue DevTools 中看到组件名,比如 Searcher,对应的文件是 frontend/src/components/searcher.vue。
通过模板路径
在 templates/index.vue 中可以看到使用了哪些组件,比如 <Searcher>、<Table> 等。
通过源码映射
在浏览器的 Sources 标签中,可以找到 webpack:// 或 vite:// 开头的文件,这些对应到 frontend/src/ 目录。
在组件中添加 console.log() 输出关键信息,或者使用 Vue DevTools 的断点功能。
如果搜索功能不工作,按以下步骤检查:
- 检查 rule.json 配置
确保字段的 search 配置不为 0。如果 search: 0,该字段不会出现在搜索表单中。
- 检查前端请求参数
在 templates/index.vue 的 fetchData 方法中添加 console.log(),查看搜索参数是否正确传递。
- 检查后端查询条件
在 x.go 的 buildCondition 方法中添加日志,查看构建的查询条件是否正确。
如果保存功能失败,检查以下几点:
- 检查必填字段
确保 rule.json 中标记为 required: true 的字段都有值。
- 检查后端验证
在 x.go 的 parsePayload 方法中添加日志,查看解析的数据和验证错误。
- 检查数据库约束
使用 SQL 工具查看表结构,检查是否有 NOT NULL 约束或其他约束导致保存失败。
如果下拉选项不显示,检查:
- 检查 rule.json 配置
确保 limit 或 trans 配置正确。
- 检查翻译配置
如果使用 trans,确保表名、字段名正确,数据库中有数据。
- 检查数据库数据
使用 SQL 查询确认关联表中有数据。
如果访问页面返回 404,检查:
- 检查 Controller 注册
确保在 router.go 中调用了 RegController() 和 BindActions()。
- 检查方法名
确保方法名以 Action 开头,使用驼峰命名。
- 检查路由表
查询数据库的 action 表,确认路由已注册。
有时候需要创建一个简单的页面,不涉及数据库操作,比如帮助页面、关于页面等。
重要:路由规范
框架要求使用三层路由结构:{module}/{controller}/{action}。前端文件路径也必须遵循这个规范。
前端文件路径必须遵循三层结构:frontend/src/modules/{module}/{controller}/{action}.vue
例如,要创建路由 /example/help/index,需要创建文件:
frontend/src/modules/example/help/index.vue
页面内容就是一个普通的 Vue 组件,可以包含任何内容。
在 backend/modules/{module}/controllers/ 下创建控制器文件。
例如,对于路由 /example/help/index,需要创建:
backend/modules/example/controllers/help.go
Controller 需要继承 g.Web(不是 g.X,因为不需要 CRUD 功能)。
定义一个 ActionIndex 方法,调用 Render() 渲染前端页面。
在 backend/modules/router.go 中调用 RegController() 注册 Controller。
注册时需要指定三个参数:module、controller、实例。
例如:g.RegController("example", "help", controllers.NewHelp())
然后调用 BindActions() 绑定路由。
启动服务后,访问对应的 URL 即可看到页面。路由地址就是 /example/help/index。
这是框架的核心功能,只需要三步就能完成一套完整的 CRUD。
创建 Model 文件,定义数据结构。Model 需要:
- 继承
g.Model(包含 id、created、updated 字段) - 定义业务字段
- 实现
ModelX接口的四个方法:TableName()、New()、Save()、Delete()
在 rule.json 中添加表的配置。为每个字段配置:
key:字段名name:显示名称required:是否必填search:搜索类型- 其他需要的配置(如下拉选项、翻译等)
创建 Controller 文件,继承 g.X(或 g.XB 如果需要批量操作)。框架会自动提供所有 CRUD 功能。
如果需要自定义,可以配置 Tool(工具栏按钮)和 Option(行操作按钮)。
在 router.go 中注册 Controller,然后执行 SQL 创建数据库表。
如果需要启用操作日志功能,在 backend/op.json 中添加表的配置:
{
"your_table_name": {
"name": "表的中文名称",
"db": "core",
"show": ["field1", "field2", "field3"],
"primary": {
"id": {
"related_table1": "foreign_key_field1",
"related_table2": "foreign_key_field2"
}
}
}
}配置说明:
name:表的显示名称,用于操作日志展示db:数据库名称,必须为"core"(操作日志仅记录 core 数据库的表)show:操作日志中要显示的字段列表,用于差异对比展示primary:主键关联关系,定义该表的主键被哪些表的外键引用"id":主键字段名(通常是id)"related_table1": "foreign_key_field1":表示related_table1表的foreign_key_field1字段引用了本表的主键id- 可以配置多个关联表,每个关联表占一行
配置示例:
假设有以下表结构:
category表(主键:id)article表(外键:category_id引用category.id)tag表(外键:category_id引用category.id)
则在 op.json 中配置 category 表时:
{
"category": {
"name": "分类",
"db": "core",
"show": ["name", "status"],
"primary": {
"id": {
"article": "category_id",
"tag": "category_id"
}
}
}
}这样配置后,框架在回滚操作时会自动检查依赖关系:
- 如果回滚创建分类的操作,会自动检查是否有文章或标签引用了该分类
- 如果回滚删除分类的操作,会自动检查是否有文章或标签的修改操作依赖于该分类
配置完成后,框架会自动记录该表的所有数据变更(新增、更新、删除),你可以在操作日志页面查看和回滚这些操作。
完成!现在你就有了一个完整的 CRUD 功能,包括列表页、搜索、新增、编辑、删除等所有功能。如果配置了操作日志,还会自动记录所有数据变更。
框架提供了很多扩展点,可以自定义各种功能。
如果需要批量编辑或批量删除,只需要将 g.X 改为 g.XB。框架会自动添加批量操作按钮和功能。
通过配置 AndWheres,可以添加固定的查询条件。比如只显示已发布的数据、只显示当前用户的数据等。
重写 WrapData 方法,可以在返回数据前进行自定义处理。比如添加计算字段、格式化数据等。
重写 buildCondition 方法,可以实现自定义的搜索逻辑。比如日期范围搜索、复杂条件组合等。
重写 ActionSave 方法,可以在保存前进行自定义验证和处理。比如设置默认值、计算字段值等。
在 WrapData 中可以实现关联查询,将外键 ID 转换为关联数据。比如文章列表显示分类名称、作者名称等。
框架内置了完整的操作日志功能,你可以:
查看操作历史:
- 访问
/base/op/index查看所有操作事件 - 支持按数据表、用户、时间等条件搜索
- 点击详情按钮查看具体的变更记录和字段差异
回滚操作:
- 选择需要回滚的操作事件
- 框架会自动检查操作依赖关系
- 确认后执行回滚,数据恢复到变更前的状态
- 回滚操作本身也会被记录,形成完整的审计链
自定义展示字段:
- 在
op.json的show字段中配置要展示的字段 - 框架会根据这些字段计算差异并展示
- 支持字段翻译,自动将外键 ID 转换为显示名称
常见问题的解答,包括自定义列表页、添加验证、关联查询、自定义搜索等,请查看 常见问题文档。
MIT License
gin-vue-web - 快速构建 Web 应用
Made with ❤️ by the gin-vue-web Team











