基于golang的后台管理系统,力求适中简化后台开发过程,满足中小项目开发需要。 使用到的主要技术框架: Gin、TypeScript、React18、Ant-design5等
备注
:本文档中,如果没有特殊明确,app目录
均是指app/app/
的第二层目录
关于前端技术我解释下
:
- 由于业务和环境的变化,原本vue2.0前端的维护压力越来越大。再三考虑后,使用React对前端进行了重构,借此也对golang接口端的各种问题进行了集中处理。
- vue2.0版的最终完整版本,我单独设置了一个分支,该分支仅做永久备份,不再进行更新和维护。后续将只会迭代新的react版
- react版分为内部版和开源版,内部版源码不对外开放,但为了开源版的完整性,我借用了第三方开源项目框架Hooks-Admin 来实现。
- 所有涉及业务接口的页面,都是从内部版完整迁移到这个框架,这些页面一行代码也没改
- 该框架原本使用的是ant-design4.x,为了兼容业务页面,我变更为5.x,框架本身针对性的做了一些调整
- 最终目的是让迁移的页面能在不改代码的情况下正常运行,而框架本身的基础功能非必要我不做调整
- 该开源框架本身其实已经很老,很多细节实现上也需要完善或者重构,由于个人精力有限,这个只能是使用者根据自身情况自行迭代完善了。
初衷
:
有很多开源的go-admin,但其实都是在别的开源项目的基础上各种迭代的,代码冗余,功能冗余,结构上也不尽人意。
为了满足个人日常需要(统计数据、中小单体项目开发等),我经过多个项目的磨合,对该项目做了大量的精简和调整,也对很多功能做了重新规划和设计。
对很多人而言,仅仅需要最基础的功能,剩下的根据需要自行迭代,而这套框架也刚好满足你。
我的开发准则:
大道至简
在线体验:
go-admin react开源版入口
内置两个默认账户:
账户:admin 密码:123456 顶级账户
账户:test 密码:123456 菜单权限受限的账户
注:
:该项目没有任何商业行为,只作为公开分享和交流,请友善体验,不要非法攻击该在线地址。所有功能对外开放,期间可能有小伙伴无意间操作导致页面显示异常,我发现后会及时恢复数据库,或者可以发Issues提醒我处理。
项目本身功能细节很多,这里我把我认为需要表述的功能介绍下,剩下的大家进一步看代码来逐步理解吧
前后端都放在一个项目了,对于中小项目,这个管理反而会很方便。
其实它本质还是前后端分离。
这里我解释下几个主要目录
- 后端(golang端):
- 所有业务内容,均在
app根目录
下完成,而该目录下,分为3个子目录:admin子目录
:后台管理系统通用功能,能够确保框架正常运行的基础业务,如登录、日志、系统管理、菜单等等app子目录
:个性化业务层,也就是你具体业务均放在该目录下,大多数情况下,你的所有业务都是在该目录下完成的,plugins子目录
:存放一些独立插件功能,方便根据自身需要选择删掉或者增加。如消息管理、文章管理等等
- 上面虽然说,一般情况下都是在第二层
app
子目录中完成业务,但一些业务常量和国际化为了方便统一管理,我将其归纳到config/base目录
中,自己根据已有的内容,根据业务需要在其中添加就行。- 国际化默认都是中文的,要对不同语言翻译,就得在
config/lang
目录中多语言翻译了 - 目前框架多语言只支持中英文,如果需要根多语言,只需要在
core/lang/lang.go
中添加需要的语言就行
- 国际化默认都是中文的,要对不同语言翻译,就得在
- 所有业务内容,均在
- 前端(ts+react18+ant5+vite+xxx)
web
目录是前端根目录,完全独立,可以独立开发和部署。除了该目录,剩下的都属于后台接口的- 同后端目录功能类似,前端的业务目录主要有两个:
src/api目录
:用于存放和后端交互的业务接口,其中也分为三个子目录:admin
、app
、plugins
src/views目录
:存放所有业务页面,其中也分为三个子目录:admin
、app
、plugins
- 前面我提到过,目前我开源的react版,业务页面是原封不动的迁移进来的,也就是说,
src/api目录
中的内容和我内部版是完全一样的,而src/views目录
除了其中的/admin/sys/login
,其余也是完全一样的
基础功能:
- 登录身份鉴权,支持session和jwt两种方式、支持单点登录
- 部门、岗位、角色(子账户)、管理员等基本通用功能
- 数据权限管理,该功能虽已完成,因使用频率低,暂未调试 [后续完善]
- 字典管理、业务参数管理、登录日志、操作日志等
- 根据模板一键
生成/下载/预览
前端页面以及后端相应业务代码,满足常用的增删改 - 插件化管理,尽可能独立化每个功能
- 支持mysql
- 接口支持多语言i18n
- 支持后端接口自动扫描及录入
扩展业务功能(我简单实现的一些基础业务功能,可进行二次开发)
- app用户管理,包括对应配置管理里
- 等级管理
- 账变记录
- 国际区号
- 插件(基本的CMS内容管理、App安装包管理、消息管理)
备注
:截止目前,我也不打算提供定时任务和swagger功能,对我而言,我认为完全没必要。首先定时任务和后台耦合,每次后台发布,很容易引起定时任务的异常,定时任务完全可以搞成一个独立的脚本去运行彻底解耦。而swagger我只感觉鸡肋,除了给自己增加工作量,眼前还没发现任何优势。这两个功能谁如果需要,完全可以自行在现有框架中加进去。
- 数据库表
- 分为3类表:
- 系统基础表,以
admin_子业务名_xxx
为前缀,后面衔接模块业务名 - 插件表,以
plugins_子业务名_xxx
为前缀,后面衔接模块业务名 - 主业务项目,以
app_子业务名_xxx
为前缀,后面衔接模块业务名
- 系统基础表,以
- 这里我简单举例说明下,比如
app_user_level
,表示我是要开发自己的业务,需要用app
标记,而具体的子业务是user
,具体功能是level
,直到子业务
的命名一定要规范,这是为了后续一键生成代码体验更好
- 分为3类表:
- 尽可能按照已有功能的文件结构和命名方式来开发项目,模板本身就是按照该规则实现的,尽量约束自己的开发范围
- 注释规范:因为
接口同步
需要录入接口功能说明,每个方法前都需要按规范写上注释(功能说明),尤其路由接口上,规范是:// 方法名 功能说明
- 按钮权限规范:
菜单管理
中,会涉及到按钮的权限配置,此时你配置的权限内容要和页面中permission
属性配置内容保持一致,命名规则最好按我这样:业务名:包名:作用
,同样以app_user_level
表为例,新增按钮
权限命名为:app:user_level:add
;删除按钮
权限命名为:app:user_level:del``更新按钮
权限命名为:app:user_level:edit
;查询
权限命名为:app:user_level:query
。权限这个很灵活,你根据自己实际场景来尝试,比如有时候你可以不用在页面设置permisson
,一样能达到权限控制效果 - 菜单管理中,新添加的
目录
或菜单
,其路由路径一定要满足目录/菜单
层级逻辑,这牵涉到后面主页面左侧的体验,这个其实也是目前此类功能的通用规则。
分为数据库、后端、前端部署
- 我亲测的环境:10.7.3-MariaDB 或者 8.0.40-Mysql
- 直接自建数据库,用
字符集:utf8_mb4
、排序规则:utf8_mb4_bin
- 建好数据库后,直接把我根目录的sql脚本
app.sql
导入即可
- 环境:golang版本-1.23.2
- 编译项目,项目根目录执行如下:
go mod tidy
# 直接编译
go generate && go build -a -o go-admin-api main.go
# 交叉编译为linux amd64:
go generate && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o go-admin-api main.go
注
go generate
命令一定要执行(无论打包前还是本地运行),它可以扫描保存你新增的路由,用于后续接口同步
3. 项目根目录,找到conf/
,可以直接再settings.yml
中配置数据库,或者可以拷贝一份,重新命名,比如:settings.dev.yml
,具体的配置信息,请自行去文件中参考,里面写的很详细,我这里就不再解释了
4. 启动项目,参考如下两种方式:
# 将会默认读取conf/目录中settings.yml配置,并启动接口
./admin server
# 读取自定义配置
./admin server -c=config/settings.dev.yml
- 依赖安装:
cd ./web
# 常规安装
npm install
# 上面不灵的话,加上--force 或者 --legacy-peer-deps
npm install --force
npm install --legacy-peer-deps
# 注:由于开源版新旧包依赖问题,导致依赖安装时,需要始终使用--legacy-peer-deps,比如安装md5:
npm install --legacy-peer-deps md5
- 本地启动:
npm run dev
浏览器打开:http://127.0.0.1:1688
- 生产编译:
npm run build:prod
- 该功能用好了可以极大减少代码开发效率
- 整体上的使用步骤就是,先把数据库表导入到系统,然后编辑每个字段的规则,保存。接着就是你下载代码还是直接生成到你代码里都行
- 前端生成位置,需要你在配置中指定
- 生成的golang文件中,会有一个
router.go.bk
文件,具体我还是用例子说明吧:- 比如你要针对
app_user_level
表 - 当你第一次在
app
子目录中生成第一个子业务user
时,也就是说原先app
目录下没有user
目录 - 你生成代码后,会自动产生个
user
目录,该目录下的router
目录中会有个router.go.bk
文件,这时,你把.bk
后缀去掉 - 然后回到
app目录
下,在init.go
文件中,按照已有的样例,把自己的业务路由append
加上去,也就是注入路由 - 至此你的业务模块就能和项目框架关联上了
- 比如你要针对
- 接口数据同步,可以将当前程序中的所有接口录入数据库,方便后续从后台绑定菜单,具体可以查看下一节讲述
- 我的目的是能够自动扫描注释,然后将接口和注释自动录入库中,但这会衍生一个问题,注释的扫描需要源码文件,但程序发布后是没法扫的。为了解决这个问题,我目前是使用
go generate
命令在每次打包、运行前,生成一个接口常量文件。 - 有了最新接口常量文件后,即可参与到程序编译,程序启动后,后台点击
接口数据同步
即可完成和库的对接。 - 具体和权限相关的操作,请查看下文
如果你想让某个管理员只能操作指定的菜单,那就需要该功能了,具体这样逻辑:
- 先
角色管理
菜单中,创建一个角色,并指定该角色能操控哪些菜单 - 给你指定的管理员分配上刚创建的角色
- 这时,那个管理员登录后,就只能看到你刚分配的菜单了
- 你会发现,此时点击菜单会提示无权限,这是因为还没给菜单分配对应的接口,无法获取相应数据
- 为了安全,我后台服务端是需要根据角色判断该管理员是否有权限访问接口的,因此,接口需要和菜单绑定,具体需要这样操作
- 在
接口管理
中,你点击接口数据同步
,此时服务端会通过Handler将所有接口信息录入到表中 - 你在
菜单管理
中,将接口绑定到对应菜单/按钮
上, - 此时,那个管理员就能访问他的菜单了,而其余菜单,哪怕他跳过页面去调试接口,也会提示无权限的。
- 在
- 之所以要点击
接口数据同步
是因为,新发布的项目,可能程序中新增了接口,但库中没有捕获到;也有可能新部署的程序删掉了某些接口。这时候点击同步,可以自动删除表中无效接口并增加程序新增的接口。这样就方便你绑定菜单了。 - 我没有在程序启动时,自动去录入接口,是因为不喜欢那种方式,总感觉那样耦合度太高,容易出问题。还是直接在页面上操作,不论成功还是失败,一目了然。
说实话,这个开源的react前端无论体验和代码实现上,都还有很大提升空间,包括需要使用的技术等等都有很多地方可以替代下,这些更改只能是留给使用者来酌情调整了,我也会抽时间尽量把一些严重的页面问题给完善下。
这里只是大概讲了下基本情况,具体更多内容,还是需要大家在使用中一点点去发现。