This commit is contained in:
孟帅
2024-04-22 23:08:40 +08:00
parent 82483bd7b9
commit e144b12580
445 changed files with 17457 additions and 6708 deletions

View File

@@ -20,17 +20,16 @@
- [WebHook](sys-webhook.md)
- [权限控制](sys-auth.md)
- [支付网关](sys-payment.md)
- [数据库](sys-db.md)
- [代码生成](sys-code.md)
- [定时任务](sys-cron.md)
- [消息队列](sys-queue.md)
- [功能扩展库](sys-library.md)
- [工具方法](sys-utility.md)
- [WebSocket服务器](sys-websocket-server.md)
- [TCP服务器](sys-tcp-server.md)
- [SaaS多租户](sys-tenant.md)
- [单元测试](sys-test.md)
#### 插件模块开发
- [模块介绍及目录](addon-introduce-catalog.md)
@@ -38,6 +37,18 @@
- [模块辅助说明](addon-helper.md)
#### 生成代码
- [使用前提](code-start.md)
- [数据库](sys-db.md)
- [生成配置](code-config.md)
- [生成CURD](code-curd.md)
- [生成关联表CURD](code-curd-join.md)
- [生成树型CURD](code-tree.md)
- [生成业务模板](code-business.md)
- [生成模板开发](code-template-dev.md)
- [生成常见问题](code-help.md)
### 前端开发
- [表单组件](web-form.md)
- [WebSocket客户端](sys-websocket-client.md)

View File

@@ -25,6 +25,7 @@ HotGo 入口文件->隐式注入(hotgo/addons/modules)->注册所有插件->初
│ ├── modules
│ ├── xxx插件
│ | ├── api
│ | ├── consts
│ | ├── controller
│ | ├── crons
│ | ├── global

View File

@@ -0,0 +1,5 @@
## 生成业务模板
根据`api`接口文件一键生成业务模板api、controller、logic、service
待写。

View File

@@ -0,0 +1,170 @@
## 生成配置
目录
- 模板配置
- CLI配置
- 多数据库使用
### 模板配置
- 配置路径server/manifest/config/config.yaml
```yaml
# 生成代码
hggen:
allowedIPs: [ "127.0.0.1", "*" ] # 白名单,*代表所有只有允许的IP后台才能使用生成代码功能
selectDbs: [ "default" ] # 可选生成表的数据库配置名称,支持多库
disableTables: [ "hg_sys_gen_codes","hg_admin_role_casbin" ] # 禁用的表,禁用以后将不会在选择表中看到
delimiters: [ "@{", "}" ] # 模板引擎变量分隔符号
# 生成应用模型所有生成模板允许自定义可以参考default模板进行改造
application:
# CRUD和关系树列表模板
crud:
templates:
# 默认的主包模板
- group: "default" # 分组名称
isAddon: false # 是否为插件模板 falsetrue
masterPackage: "sys" # 主包名称需和controllerPath、logicPath、inputPath保持关联
templatePath: "./resource/generate/default/curd" # 模板路径
apiPath: "./api/admin" # goApi生成路径
controllerPath: "./internal/controller/admin/sys" # 控制器生成路径
logicPath: "./internal/logic/sys" # 主要业务生成路径
inputPath: "./internal/model/input/sysin" # 表单过滤器生成路径
routerPath: "./internal/router/genrouter" # 生成路由表路径
sqlPath: "./storage/data/generate" # 生成sql语句路径
webApiPath: "../web/src/api" # webApi生成路径
webViewsPath: "../web/src/views" # web页面生成路径
# 默认的插件包模板,{$name}会自动替换成实际的插件名称
- group: "addon" # 分组名称
isAddon: true # 是否为插件模板 falsetrue
masterPackage: "sys" # 主包名称需和controllerPath、logicPath、inputPath保持关联
templatePath: "./resource/generate/default/curd" # 模板路径
apiPath: "./addons/{$name}/api/admin" # goApi生成路径
controllerPath: "./addons/{$name}/controller/admin/sys" # 控制器生成路径
logicPath: "./addons/{$name}/logic/sys" # 主要业务生成路径
inputPath: "./addons/{$name}/model/input/sysin" # 表单过滤器生成路径
routerPath: "./addons/{$name}/router/genrouter" # 生成路由表路径
sqlPath: "./storage/data/generate/addons" # 生成sql语句路径
webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径
webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径
# 消息队列模板
queue:
templates:
- group: "default"
templatePath: "./resource/generate/default/queue"
# 定时任务模板
cron:
templates:
- group: "default"
templatePath: "./resource/generate/default/cron"
# 生成插件模块通过后台创建新插件时使用的模板允许自定义可以参考default模板进行改造
addon:
srcPath: "./resource/generate/default/addon" # 生成模板路径
webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径
webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径
```
### CLI配置
- hotgo在生成dao、service配置时默认了和gf官方一致的配置方式和代码生成规则。所以无论你是通过hotgo亦或gf命令生成最终代码格式完全一致遵循一致的代码规范。
- 配置路径:[server/hack/config.yaml](../../server/hack/config.yaml)
```yaml
gfcli:
build:
name: "hotgo" # 编译后的可执行文件名称
# arch: "all" #不填默认当前系统架构可选386,amd64,arm,all
# system: "all" #不填默认当前系统平台可选linux,darwin,windows,all
mod: "none"
cgo: 0
packSrc: "resource" # 将resource目录打包进可执行文件静态资源无需单独部署
packDst: "internal/packed/packed.go" # 打包后生成的Go文件路径一般使用相对路径指定到本项目目录中
version: ""
output: "./temp/hotgo" # 可执行文件生成路径
extra: ""
gen:
dao:
- link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true"
group: "default" # 分组 使用hotgo代码生成功能时必须填
# tables: "" # 指定当前数据库中需要执行代码生成的数据表。如果为空,表示数据库的所有表都会生成。
tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。
removePrefix: "hg_"
descriptionTag: true
noModelComment: true
jsonCase: "CamelLower"
gJsonSupport: true
clear: true
service: # 生成业务配置
srcFolder: "internal/logic"
dstFolder: "internal/service"
dstFileNameCase: "CamelLower"
clear: true
```
### 多数据库使用
- 假设我们要增加一个库名为`hotgo2`、分组为`default2`的数据库,并要为其生成代码
1. 配置[server/hack/config.yaml](../../server/hack/config.yaml) 如下:
```yaml
gen:
dao:
- link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true"
group: "default" # 分组 使用hotgo代码生成功能时必须填
tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。
removePrefix: "hg_"
descriptionTag: true
noModelComment: true
jsonCase: "CamelLower"
gJsonSupport: true
clear: false
- link: "mysql:hotgo2:hg123456.@tcp(127.0.0.1:3306)/hotgo2?loc=Local&parseTime=true"
group: "default2" # 分组 使用hotgo代码生成功能时必须填
tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。
removePrefix: ""
descriptionTag: true
noModelComment: true
jsonCase: "CamelLower"
gJsonSupport: true
clear: false
```
2. 配置`server/manifest/config/config.yaml`,
`database`配置如下:
```yaml
database:
logger:
level: "all"
stdout: true
default:
link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true"
debug: true
Prefix: "hg_"
default2:
link: "mysql:hotgo2:hg123456.@tcp(127.0.0.1:3306)/hotgo2?loc=Local&parseTime=true"
debug: true
Prefix: ""
```
`hggen`配置如下:
```yaml
hggen:
allowedIPs: ["127.0.0.1", "*"] # 白名单,*代表所有只有允许的IP后台才能使用生成代码功能
selectDbs: [ "default", "default2" ] # 可选生成表的数据库配置名称,支持多库
disableTables : ["hg_sys_gen_codes","hg_admin_role_casbin"] # 禁用的表,禁用以后将不会在选择表中看到
delimiters: ["@{", "}"] # 模板引擎变量分隔符号
```
3. 登录HotGo后台 -> 开发工具 -> 代码生成 -> 找到立即生成按钮并打开,就会发现`数据库`选项增加了一个`default2`,后续生成步骤和生成例子完全一样
> 注意:上述的配置中所有的`default2`名称必须保持一致

View File

@@ -0,0 +1,115 @@
## 生成关联表CURD
### 热编译启动
- 推荐使用热编译方式启动HotGo这样生成完成页面自动刷新即可看到新生成内容无需手动重启
```shell
# 服务端
cd server
gf run main.go
# web端
cd web
yarn dev
```
以下是一个关联表的CURD生成流程
### 创建表结构
- 以下表结构和数据为了方便功能演示已经内置无需再次创建
- 创建主表hg_sys_gen_curd_demo
```sql
CREATE TABLE `hg_sys_gen_curd_demo` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`category_id` bigint(20) DEFAULT '0' COMMENT '分类ID',
`title` varchar(64) NOT NULL COMMENT '标题',
`description` varchar(255) DEFAULT '' COMMENT '描述',
`content` text COMMENT '内容',
`image` varchar(255) DEFAULT NULL COMMENT '单图',
`attachfile` varchar(255) DEFAULT NULL COMMENT '附件',
`city_id` bigint(20) DEFAULT '0' COMMENT '所在城市',
`switch` int(11) DEFAULT '1' COMMENT '显示开关',
`sort` int(11) DEFAULT NULL COMMENT '排序',
`status` tinyint(1) DEFAULT '1' COMMENT '状态',
`created_by` bigint(20) DEFAULT '0' COMMENT '创建者',
`updated_by` bigint(20) DEFAULT '0' COMMENT '更新者',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '修改时间',
`deleted_at` datetime DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COMMENT='系统_生成curd演示';
```
创建关联表hg_test_category
```sql
CREATE TABLE `hg_test_category` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类ID',
`name` varchar(255) NOT NULL COMMENT '分类名称',
`short_name` varchar(128) DEFAULT NULL COMMENT '简称',
`description` varchar(255) DEFAULT NULL COMMENT '描述',
`sort` int(11) NOT NULL COMMENT '排序',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`status` tinyint(1) DEFAULT '1' COMMENT '状态',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '修改时间',
`deleted_at` datetime DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='测试分类';
```
### 表字段要求
- 使用生成时,表中必须具有以下字段和属性
| 字段名称 | 字段含义 | 字段类型 | 可为空 |
|--------|----------------------|---------------------|-----|
| id | 主键ID | bigint(20) | 否 |
### 创建生成配置
- 登录HotGo后台 -> 开发工具 -> 代码生成 -> 找到立即生成按钮并打开,选择和填写如下参数:
![](images/code/join-add.png)
### 基本设置
- 确认无误后,点击生成配置会跳转到生成配置页面,如下:
- 你可以在该页面调整生成表格表头/表列的接口功能、菜单权限、高级设置和关联表设置
![](images/code/join-init.png)
### 主表字段设置
- 在该页面你可以调整生成表格字段名称、表单组件、表单编辑/验证项、列表展示/查询项、字段排序、重置和同步字段
![](images/code/join-fields.png)
### 关联表字段设置
- 在该页面你可以调整生成表格关联表字段名称、列表展示/查询项、字段排序、重置和同步字段
- 如果存在多个关联表,也可以对多个关联表字段进行设置
![](images/code/join-fields2.png)
### 预览并生成
点击`预览代码`查看生成的代码内容。如果无需继续调整直接点击`提交生成`即可,以下是预览代码效果:
![](images/code/join-preview.png)
- 如果你使用的热编译,那么页面会在生成成功后立即刷新,刷新完成你即可在后台菜单栏中看到`测试表格`菜单。如果不是使用热编译启动,请手动重启服务后刷新。
### 生成完成
- 让我们看看生成的表格页面,效果如下:
![](images/code/join-list.png)
### 常见问题
- [生成常见问题](code-help.md)

View File

@@ -0,0 +1,84 @@
## 生成CURD
### 热编译启动
- 推荐使用热编译方式启动HotGo这样生成完成页面自动刷新即可看到新生成内容无需手动重启
```shell
# 服务端
cd server
gf run main.go
# web端
cd web
yarn dev
```
以下是一个基本的CURD生成流程
### 创建表结构
- 以下表结构和数据为了方便功能演示已经内置无需再次创建
```sql
CREATE TABLE `hg_test_category` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类ID',
`name` varchar(255) NOT NULL COMMENT '分类名称',
`short_name` varchar(128) DEFAULT NULL COMMENT '简称',
`description` varchar(255) DEFAULT NULL COMMENT '描述',
`sort` int(11) NOT NULL COMMENT '排序',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`status` tinyint(1) DEFAULT '1' COMMENT '状态',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '修改时间',
`deleted_at` datetime DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='测试分类';
```
### 表字段要求
- 使用生成时,表中必须具有以下字段和属性
| 字段名称 | 字段含义 | 字段类型 | 可为空 |
|--------|----------------------|---------------------|-----|
| id | 主键ID | bigint(20) | 否 |
### 创建生成配置
- 登录HotGo后台 -> 开发工具 -> 代码生成 -> 找到立即生成按钮并打开,选择和填写如下参数:
![](images/code/curd-add.png)
### 基本设置
- 确认无误后,点击生成配置会跳转到生成配置页面,如下:
- 你可以在该页面调整生成表格表头/表列的接口功能、菜单权限、高级设置和关联表设置
![](images/code/curd-init.png)
### 表字段设置
- 在该页面你可以调整生成表格字段名称、表单组件、表单编辑/验证项、列表展示/查询项、字段排序、重置和同步字段
![](images/code/curd-fields.png)
### 预览并生成
点击`预览代码`查看生成的代码内容。如果无需继续调整直接点击`提交生成`即可,以下是预览代码效果:
![](images/code/curd-preview.png)
- 如果你使用的热编译,那么页面会在生成成功后立即刷新,刷新完成你即可在后台菜单栏中看到`测试表格`菜单。如果不是使用热编译启动,请手动重启服务后刷新。
### 生成完成
- 让我们看看生成的表格页面,效果如下:
![](images/code/curd-list.png)
### 常见问题
- [生成常见问题](code-help.md)

View File

@@ -0,0 +1,18 @@
## 生成常见问题
### 生成完后页面提示:服务器错误,请稍候重试!
- 热编译环境下web端往往会快于服务端重启并加载完成此时接口访问会出现`服务器错误,请稍候重试!``404`。这是服务端正在重启导致的,一般稍等几秒就好,如果不行就手动重启下服务端。
### fetching tables failed: SHOW TABLES: Error 1045 (28000): Access denied for user * (using password: YES)
- 请去确认`server/manifest/config/config.yaml``server/hack/config.yaml`下的数据库配置一致并且权限正确
- 参考:[生成配置](code-config.md)
### 为什么后台找不到开发工具菜单
- 请去确认`server/manifest/config/config.yaml`中的`system.mode`不为`product`。product模式下后台【开发工具】菜单自动隐藏

View File

@@ -0,0 +1,20 @@
## 使用前提
在HotGo中可以通过后台开发工具快速的一键生成CRUD自动生成Api、控制器、业务逻辑、Web页面、表单组件、菜单权限等。
- hotgo 版本号 >= 2.13.1
- 使用前必须配置 [生成配置](code-config.md)
- 使用前必须了解 [数据库](sys-db.md)
相关目录
- [生成配置](code-config.md)
- [生成CURD](code-curd.md)
- [生成关联表CURD](code-curd-join.md)
- [生成树型CURD](code-tree.md)
- [生成业务模板](code-business.md)
- [生成模板开发](code-template-dev.md)
- [生成常见问题](code-help.md)

View File

@@ -0,0 +1,59 @@
## 生成模板开发
### 自定义生成模板
- HotGo允许你新建新的模板分组来满足你的需求模板可根据现有模板基础拷贝一份出来做改造默认模板目录[server/resource/generate/default](../../server/resource/generate/default)
- 系统内置了两组CURD生成模板请参考[生成模板配置](sys-code.md#生成模板配置)。default是默认的生成到主模块下addon是默认生成到指定的插件下
### 内置gf-cli
- 为了确保生成代码的依赖稳定性,在面对`gf`版本更新可能导致向下不兼容情况时HotGo将`gf-cli`工具内置到系统中并进行在线执行调整,从而提供更可靠和一致的生成代码功能。
- 后续我们也将开放在线运行`gf gen ...`功能。在做插件开发时也会支持到在线生成插件下的service接口这将会使得插件开发更加方便
### 指定gf-cli版本
- HotGo多数情况下会和最新版本的gf-cli保持同步如果更新不及时或你不想使用最新版本的gf-cli来生成代码可以找到自己想要的版本进行替换即可。
- 下面大致做一些替换步骤说明:
1. 打开`github.com/gogf/gf` 找到你想要使用的版本`clone`下来
2.`clone`代码中`gf/cmd/gf/internal/`目录覆盖到`server/internal/library/hggen/internal`
3. 将覆盖过来的目录文件中引入包名`github.com/gogf/gf/cmd/gf/v2/`批量改为`hotgo/internal/library/hggen/`
4. 运行`go mod tidy`
5. 运行`go run main.go`,如果没有报错,那么恭喜你已经完成了。如果有报错一般都是版本差异带来的影响,需要根据情况自行调整
### 指定数据库驱动
> HotGo默认使用mysql驱动如果你想用其他数据库驱动打开下方文件中注释即可
- 修改文件路径:[server/internal/library/hggen/internal/cmd/cmd_gen_dao.go](../../server/internal/library/hggen/internal/cmd/cmd_gen_dao.go)
```go
package cmd
import (
//_ "github.com/gogf/gf/contrib/drivers/clickhouse/v2"
//_ "github.com/gogf/gf/contrib/drivers/mssql/v2"
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
//_ "github.com/gogf/gf/contrib/drivers/oracle/v2"
//_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
//_ "github.com/gogf/gf/contrib/drivers/sqlite/v2"
"hotgo/internal/library/hggen/internal/cmd/gendao"
)
type (
cGenDao = gendao.CGenDao
)
```
修改完成后运行`go mod tidy`

View File

@@ -0,0 +1,93 @@
## 生成树型CURD
### 热编译启动
- 推荐使用热编译方式启动HotGo这样生成完成页面自动刷新即可看到新生成内容无需手动重启
```shell
# 服务端
cd server
gf run main.go
# web端
cd web
yarn dev
```
以下是一个基本的树形CURD生成流程
### 创建表结构
- 以下表结构和数据为了方便功能演示已经内置无需再次创建
```sql
CREATE TABLE `hg_sys_gen_tree_demo` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`pid` bigint(20) DEFAULT NULL COMMENT '上级ID',
`level` int(11) DEFAULT '1' COMMENT '关系树级别',
`tree` varchar(512) COMMENT '关系树',
`category_id` bigint(20) DEFAULT '0' COMMENT '分类ID',
`title` varchar(64) NOT NULL COMMENT '标题',
`description` varchar(255) DEFAULT '' COMMENT '描述',
`sort` int(11) DEFAULT NULL COMMENT '排序',
`status` tinyint(1) DEFAULT '1' COMMENT '状态',
`created_by` bigint(20) DEFAULT '0' COMMENT '创建者',
`updated_by` bigint(20) DEFAULT '0' COMMENT '更新者',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '修改时间',
`deleted_at` datetime DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COMMENT='系统_生成树表演示';
```
### 表字段要求
- 使用生成时,表中必须具有以下字段和属性
| 字段名称 | 字段含义 | 字段类型 | 可为空 |
|--------|----------------------|---------------------|-----|
| id | 主键ID | bigint(20) | 否 |
| pid | 上级树ID | bigint(20) | 是 |
| level | 关系树级别 | int(11) | 否 |
| tree | 关系树 | varchar(512) | 是 |
### 创建生成配置
- 登录HotGo后台 -> 开发工具 -> 代码生成 -> 找到立即生成按钮并打开,选择和填写如下参数:
![](images/code/tree-add.png)
### 基本设置
- 确认无误后,点击生成配置会跳转到生成配置页面,如下:
- 你可以在该页面调整生成表格表头/表列的接口功能、菜单权限、高级设置和关联表设置
- 相比普通CURD这里多了`树名称字段``树表格样式`选项
![](images/code/tree-init.png)
### 表字段设置
- 在该页面你可以调整生成表格字段名称、表单组件、表单编辑/验证项、列表展示/查询项、字段排序、重置和同步字段
- 树表中的pid、level、tree字段由系统维护单独设置编辑表单功能无效
![](images/code/tree-fields.png)
### 预览并生成
点击`预览代码`查看生成的代码内容。如果无需继续调整直接点击`提交生成`即可,以下是预览代码效果:
![](images/code/tree-preview.png)
- 如果你使用的热编译,那么页面会在生成成功后立即刷新,刷新完成你即可在后台菜单栏中看到`测试表格`菜单。如果不是使用热编译启动,请手动重启服务后刷新。
### 生成完成
- 让我们看看生成的表格页面,效果如下:
- 普通树表
![](images/code/tree-list.png)
- 选项式树表
![](images/code/tree-list2.png)
### 常见问题
- [生成常见问题](code-help.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@@ -15,7 +15,7 @@
5. 命令行运行 `yarn -v` 若控制台输出版本号则前端环境搭建成功
### 后端环境
1. 下载golang安装 版本号需>=1.19
1. 下载golang安装 版本号需>=1.21
2. 国际: https://golang.org/dl/
3. 国内: https://golang.google.cn/dl/
4. 命令行运行 go 若控制台输出各类提示命令 则安装成功 输入 `go version` 确认版本大于1.19
@@ -26,6 +26,6 @@
> 需要本地具有 git node golang 环境
- node版本 >= 16.0.0
- golang版本 >= 1.19
- golang版本 >= 1.21
- mysql版本 >= 5.7,引擎需要是 innoDB
- IDE推荐Goland

View File

@@ -8,8 +8,8 @@
### 环境要求
- node版本 >= v16.0.0
- golang版本 >= v1.19
- goframe版本 >=v2.6.4
- golang版本 >= v1.21
- goframe版本 >=v2.7.0
- mysql版本 >=5.7
> 必须先看[环境搭建文档](start-environment.md),如果安装遇到问题务必先查看[常见问题文档](start-issue.md)
@@ -28,18 +28,37 @@ git clone https://github.com/bufanyun/hotgo.git && cd hotgo
1、服务端
- 项目数据库文件 `storage/data/hotgo.sql` 创建数据库并导入
- 将配置文件 `manifest/config/config.yaml.bak` 复制后改为`manifest/config/config.yaml`
-`manifest/config/config.yaml`中的数据库配置改为你自己的:
-`manifest/config/config.yaml`中的`database.default.link`数据库配置改为你自己的:
```yaml
# Database. 配置参考https://goframe.org/pages/viewpage.action?pageId=1114245
database:
logger:
level: "all"
path: "logs/database" # 日志文件路径。默认为空,表示关闭,仅输出到终端
<<: *defaultLogger
stdout: true
default:
link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true"
link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true&charset=utf8mb4"
debug: true
Prefix: "hg_"
```
-`hack/config.yaml`中的`gfcli.gen.dao[0].link`数据库配置改为你自己的:
```yaml
gfcli:
gen:
dao:
- link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true&charset=utf8mb4"
group: "default" # 分组 使用hotgo代码生成功能时必须填
# tables: "" # 指定当前数据库中需要执行代码生成的数据表。如果为空,表示数据库的所有表都会生成。
tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。
removePrefix: "hg_"
descriptionTag: true
noModelComment: true
jsonCase: "CamelLower"
gJsonSupport: true
clear: false
```
2、web前端
- 配置服务端地址,包含在以下文件中:
* /hotgo/web/.env.development

View File

@@ -45,6 +45,13 @@
详细请参考 - [系统安装](start-installation.md)
#### 3、cannot find "hack/config.yaml" in following paths:
> 报错信息get cli configuration file:hack/config.yaml, err:cannot find "hack/config.yaml" in following paths:
系统运行目录下配置hack/config.yaml文件。如果是生产环境运行并且不需要开发工具相关功能可以将`manifest/config/config.yaml`配置文件中的`system.mode`值改为`product`,这样启动时不会加载开发工具相关功能
### 四、前端相关
#### 1、Error: connect ECONNREFUSED ::1:8000

View File

@@ -11,6 +11,31 @@
> 如果升级(覆盖)代码后打开会出现 sql 报错, 请检查更新的数据库格式或自行调整
### v2.15.1
updated 2024.4.22
- 增加:生成代码增加树表生成、字段排序、字段重置、操作人维护,调整关联表生成方式
- 增加:角色菜单权限增加一键导入支持
- 增加:访问日志增加忽略请求方式
- 增加:插件生成增加`consts`目录维护
- 增加IP归属地定位增加默认重试增加新的缓存机制
- 增加登录日志增加UA信息、IP归属信息解藕访问日志
- 增加:消息队列`rocketmq`驱动更新版本问题,增加延迟队列,支持自动创建主题
- 增加:部门增加类型支持,通过部门类型实现多租户业务支持
- 增加:增加多租户业务开发演示
- 修复:修复部门列表搜索算法在部分情况下无效问题
- 修复修复短信、邮件IP发送数量限制
- 修复:修复分布式锁内存泄漏问题
- 优化gf版本升级到v2.7.0
- 优化naive-ui版本升级到2.38.1
- 优化:优化`cmd`服务退出流程
- 优化:优化生成代码格式化和移除未使用的包
- 优化:服务端配置文件参数`hotgo`改为`system`
- 优化web端表格/表单增加自适应宽度计算
- 优化:日期选择组件不再使用默认值
- 优化:优化菜单添加/编辑表单,使其操作更加简单方便
### v2.13.1
updated 2024.3.7

View File

@@ -70,6 +70,7 @@
| --- --- --- api | 前台通用接口包含PC端、移动端接口等 |
| --- --- --- home | 前台PC端、H5端页面 |
| --- --- --- websocket | 可同时为多应用提供websocket接口 |
| --- --- consts | 插件内主要的常量定义 |
| --- --- controller | 接收/解析用户输入参数的入口/接口层,也可以理解为控制器 |
| --- --- crons | 项目中由系统统一接管的定时任务处理 |
| --- --- global | 项目内主要的全局变量和系统的一些初始化操作 |

View File

@@ -3,13 +3,15 @@
目录
- 使用条件
- 生成配置
- 一个生成增删改查列表例子
- 多数据库生成配置
- 模板配置
- CLI配置
- 生成CRUD表格
- 生成树形表格
- 多数据库使用
- 自定义生成模板
- 内置gf-cli
- 指定gf-cli版本
- 指定数据库驱动类型
- 指定数据库驱动
> 在HotGo中可以通过后台开发工具快速的一键生成CRUD自动生成Api、控制器、业务逻辑、Web页面、表单组件、菜单权限等。
@@ -17,33 +19,23 @@
### 使用条件
- hotgo 版本号 >= 2.2.10
- hotgo 版本号 >= 2.13.1
- 使用前必须先看 [数据库](sys-db.md)
#### 增删改查列表
- 表自增长字段为 `id`
#### 关系树列表
- 表自增长字段为 `id`
### 生成模板配置
- 注意:线上环境务必将`allowedIPs`参数设为空,考虑到项目安全问题请勿线上生成使用!
- 默认配置路径server/manifest/config/config.yaml
- 配置路径server/manifest/config/config.yaml
```yaml
# 生成代码
hggen:
allowedIPs: ["127.0.0.1", "*"] # 白名单,*代表所有只有允许的IP后台才能使用生成代码功能
selectDbs: [ "default" ] # 可选生成表的数据库配置名称,支持多库
disableTables : ["hg_sys_gen_codes","hg_admin_role_casbin"] # 禁用的表,禁用以后将不会在选择表中看到
delimiters: ["@{", "}"] # 模板引擎变量分隔符号
allowedIPs: [ "127.0.0.1", "*" ] # 白名单,*代表所有只有允许的IP后台才能使用生成代码功能
selectDbs: [ "default" ] # 可选生成表的数据库配置名称,支持多库
disableTables: [ "hg_sys_gen_codes","hg_admin_role_casbin" ] # 禁用的表,禁用以后将不会在选择表中看到
delimiters: [ "@{", "}" ] # 模板引擎变量分隔符号
# 生成应用模型所有生成模板允许自定义可以参考default模板进行改造
application:
# CRUD模板
# CRUD和关系树列表模板
crud:
templates:
# 默认的主包模板
@@ -51,34 +43,28 @@ hggen:
isAddon: false # 是否为插件模板 falsetrue
masterPackage: "sys" # 主包名称需和controllerPath、logicPath、inputPath保持关联
templatePath: "./resource/generate/default/curd" # 模板路径
apiPath: "./api/admin" # gfApi生成路径
apiPath: "./api/admin" # goApi生成路径
controllerPath: "./internal/controller/admin/sys" # 控制器生成路径
logicPath : "./internal/logic/sys" # 主要业务生成路径
logicPath: "./internal/logic/sys" # 主要业务生成路径
inputPath: "./internal/model/input/sysin" # 表单过滤器生成路径
routerPath : "./internal/router/genrouter" # 生成路由表路径
sqlPath : "./storage/data/generate" # 生成sql语句路径
routerPath: "./internal/router/genrouter" # 生成路由表路径
sqlPath: "./storage/data/generate" # 生成sql语句路径
webApiPath: "../web/src/api" # webApi生成路径
webViewsPath : "../web/src/views" # web页面生成路径
webViewsPath: "../web/src/views" # web页面生成路径
# 默认的插件包模板
# 默认的插件包模板{$name}会自动替换成实际的插件名称
- group: "addon" # 分组名称
isAddon: true # 是否为插件模板 falsetrue
masterPackage: "sys" # 主包名称需和controllerPath、logicPath、inputPath保持关联
templatePath: "./resource/generate/default/curd" # 模板路径
apiPath: "./addons/{$name}/api/admin" # gfApi生成路径
apiPath: "./addons/{$name}/api/admin" # goApi生成路径
controllerPath: "./addons/{$name}/controller/admin/sys" # 控制器生成路径
logicPath : "./addons/{$name}/logic/sys" # 主要业务生成路径
logicPath: "./addons/{$name}/logic/sys" # 主要业务生成路径
inputPath: "./addons/{$name}/model/input/sysin" # 表单过滤器生成路径
routerPath : "./addons/{$name}/router/genrouter" # 生成路由表路径
sqlPath : "./storage/data/generate/addons" # 生成sql语句路径
routerPath: "./addons/{$name}/router/genrouter" # 生成路由表路径
sqlPath: "./storage/data/generate/addons" # 生成sql语句路径
webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径
webViewsPath : "../web/src/views/addons/{$name}" # web页面生成路径
# 关系树列表模板
tree:
templates:
- group: "default"
templatePath: "./resource/generate/default/tree"
webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径
# 消息队列模板
queue:
@@ -91,14 +77,19 @@ hggen:
templates:
- group: "default"
templatePath: "./resource/generate/default/cron"
# 生成插件模块通过后台创建新插件时使用的模板允许自定义可以参考default模板进行改造
addon:
srcPath: "./resource/generate/default/addon" # 生成模板路径
webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径
webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径
```
### 生成dao、service配置
### 生成CLI配置
- hotgo在生成dao、service配置时默认了和gf官方一致的配置方式和代码生成规则。所以无论你是通过hotgo亦或gf命令生成最终代码格式完全一致遵循一致的代码规范。
- 默认配置路径server/hack/config.yaml
- 配置路径:[server/hack/config.yaml](../../server/hack/config.yaml)
```yaml
gfcli:
@@ -134,14 +125,14 @@ gfcli:
clear: true
```
### 一个生成增删改查列表例子
### 生成CRUD表格
- 推荐使用热编译方式启动HotGo这样生成完成页面自动刷新即可看到新生成内容无需手动重启
- 服务端热编译启动:`gf run main.go`, web前端启动`yarn dev`
1、创建数据表
1.1 创建测试表格表`hg_test_table`
1.1 创建测试表格表`hg_test_table`
```mysql
CREATE TABLE `hg_test_table` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
@@ -221,7 +212,7 @@ INSERT INTO `hg_test_table` (`id`, `category_id`, `title`, `description`, `conte
- 如果你使用的热编译,那么页面会在生成成功后立即刷新,刷新完成你即可在后台菜单栏中看到`测试表格`菜单。如果不是使用热编译启动,请手动重启服务后刷新。
#### 注意热编译环境下web端往往会快于服务端重启并加载完成此时访问新生成的菜单页面可能会存在某接口请求超时或404问题这是服务端正在重启导致的属于正常现象一般稍等几秒再试即可。
- 注意热编译环境下web端往往会快于服务端重启并加载完成此时访问新生成的菜单页面可能会存在某接口请求超时或404问题这是服务端正在重启导致的属于正常现象一般稍等几秒再试即可。
- 接下来让我们看看生成的表格页面,效果如下:
@@ -263,19 +254,20 @@ INSERT INTO `hg_test_table` (`id`, `category_id`, `title`, `description`, `conte
- 至此生成增删改查列表示例结束!
### 生成树形表格
待写。
## 多数据库生成配置
### 多数据库使用
#### 假设我们要增加一个库名为`hotgo2`、分组为`default2`的数据库,并要为其生成代码
- 假设我们要增加一个库名为`hotgo2`、分组为`default2`的数据库,并要为其生成代码
1. 配置`server/hack/config.yaml`,如下:
1. 配置[server/hack/config.yaml](../../server/hack/config.yaml) 如下:
```yaml
gen:
dao:
- link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo?loc=Local&parseTime=true"
group: "default" # 分组 使用hotgo代码生成功能时必须填
# tables: "" # 指定当前数据库中需要执行代码生成的数据表。如果为空,表示数据库的所有表都会生成。
tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。
removePrefix: "hg_"
descriptionTag: true
@@ -285,8 +277,7 @@ INSERT INTO `hg_test_table` (`id`, `category_id`, `title`, `description`, `conte
clear: false
- link: "mysql:hotgo2:hg123456.@tcp(127.0.0.1:3306)/hotgo2?loc=Local&parseTime=true"
group: "default2" # 分组 使用hotgo代码生成功能时必须填
# tables: "" # 指定当前数据库中需要执行代码生成的数据表。如果为空,表示数据库的所有表都会生成。
tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。
tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表。
removePrefix: ""
descriptionTag: true
noModelComment: true
@@ -297,7 +288,6 @@ INSERT INTO `hg_test_table` (`id`, `category_id`, `title`, `description`, `conte
2. 配置`server/manifest/config/config.yaml`,
`database`配置如下:
```yaml
database:
@@ -318,21 +308,21 @@ database:
```yaml
hggen:
allowedIPs: ["127.0.0.1", "*"] # 白名单,*代表所有只有允许的IP后台才能使用生成代码功能
selectDbs: [ "default", "default2" ] # 可选生成表的数据库配置名称,支持多库
selectDbs: [ "default", "default2" ] # 可选生成表的数据库配置名称,支持多库
disableTables : ["hg_sys_gen_codes","hg_admin_role_casbin"] # 禁用的表,禁用以后将不会在选择表中看到
delimiters: ["@{", "}"] # 模板引擎变量分隔符号
```
3. 登录HotGo后台 -> 开发工具 -> 代码生成 -> 找到立即生成按钮并打开,就会发现`数据库`选项增加了一个`default2`,后续生成步骤和生成例子完全一样
> 注意:上述的配置中所有的`default2`名称必须保持一致
### 自定义生成模板
> 系统内置了两组CURD生成模板请参考[生成配置]。default是默认的生成到主模块下addon是默认生成到指定的插件下
> 系统内置了两组CURD生成模板请参考[生成模板配置](sys-code.md#生成模板配置)。default是默认的生成到主模块下addon是默认生成到指定的插件下
- 如果你在实际的开发过程中默认模板需要调整的地方较多时,HotGo允许你新建新的模板分组来满足你的需求。新的模板可根据现有模板基础拷贝一份出来做改造,默认模板目录:[server/resource/generate/default](../../server/resource/generate/default)
- HotGo允许你新建新的模板分组来满足你的需求模板可根据现有模板基础拷贝一份出来做改造,默认模板目录:[server/resource/generate/default](../../server/resource/generate/default)
@@ -358,7 +348,7 @@ hggen:
### 指定数据库驱动类型
### 指定数据库驱动
> HotGo默认使用mysql驱动如果你想用其他数据库驱动打开下方文件中注释即可

View File

@@ -6,8 +6,7 @@
- 特殊字段默认表单组件
- 特殊字段默认表单验证器
- SQL默认查询方式
- 其他默认选项
- 常见问题
- 其他
### 字段类型
@@ -85,7 +84,7 @@
### 其他默认选项
### 其他
#### 默认字典选项
@@ -94,8 +93,8 @@
#### 默认属性
- 默认必填,当数据库字段存在非空`IS_NULLABLE`属性时,默认勾选必填验证
- 默认唯一,当数据库字段属性存在`UNI`时,默认勾选唯一值验证
- 默认主键,当数据库字段属性存在`PRI`时,默认为主键,不允许编辑
- 默认唯一,当数据库字段索引存在`UNI`时,默认勾选唯一值验证
- 默认主键,当数据库字段索引存在`PRI`时,默认为主键,不允许编辑
- 默认排序,当数据库字段存在`sort`时,默认开启排序,添加表单自动获取最大排序增量值并填充表单
- 默认列名,默认使用字段注释作为表格的列名。当数据库字段未设置注释时,默认使用字段名称作为列名
@@ -106,10 +105,45 @@
- 软删除,表存在字段`deleted_at`使用表的Orm模型查询条件将会自动加入[ `deleted_at` IS NULL ],删除时只更新删除时间而不会真的删除数据
- 树表:不论更新插入,都会根据表中字段`pid`(上级ID)自动维护`level`(树等级)和`tree`(关系树)
#### 操作人字段维护
- 生成列表中存在并且勾选展示字段`created_by`(创建者)、`updated_by`(修改者)、`deleted_by`(删除者)时,会自动到表`hg_admin_member`中获取操作人的基本信息摘要,并渲染到列表中,效果如下:
![](images/sys-db-by.png)
- 生成列表中存在并且勾选查询字段`created_by`(创建者)、`updated_by`(修改者)、`deleted_by`(删除者)时,会强制将查询表单改为关键词查询,从`hg_admin_member`查询操作人。效果如下:
![](images/sys-db-by2.png)
- 查询代码片段,参考路径:[server/internal/logic/admin/member.go](../../server/internal/logic/admin/member.go)
```go
// 查询创建者
if in.CreatedBy != "" {
ids, err := service.AdminMember().GetIdsByKeyword(ctx, in.CreatedBy)
if err != nil {
return nil, 0, err
}
mod = mod.WhereIn(dao.SysGenCurdDemo.Columns().CreatedBy, ids)
}
// GetIdsByKeyword 根据关键词查找符合条件的用户ID
func (s *sAdminMember) GetIdsByKeyword(ctx context.Context, ks string) (res []int64, err error) {
ks = gstr.Trim(ks)
if len(ks) == 0 {
return
}
array, err := dao.AdminMember.Ctx(ctx).Fields("id").
Where("`id` = ? or `real_name` = ? or `username` = ? or `mobile` = ?", ks, ks, ks, ks).
Array()
if err != nil {
err = gerror.Wrap(err, "根据关键词获取用户ID失败请稍后重试")
}
res = gvar.New(array).Int64s()
return
}
```
> 这里只列举了较为常用的默认规则,其他更多默认规则请参考:[server/internal/library/hggen/views/column_default.go](../../server/internal/library/hggen/views/column_default.go)
#### 常见问题
#### 1、生成表格字段如何排序
表格字端排序默认使用的是数据库物理字段的排序位置,所以如果你对字段的位置顺序有要求,请在生成前调整数据库物理字段位置

View File

@@ -154,7 +154,7 @@ func test(ctx context.Context) {
### 数据字典
- hotgo增加了对枚举字典和自定义方法字典的内置支持从而在系统中经常使用的一些特定数据维护基础上做出了增强。
- hotgo增加了对枚举字典和自定义方法字典的内置支持从而在系统中经常使用的一些特定数据上做出了增强。
#### 字典数据选项
- 文件路径server/internal/model/dict.go

View File

@@ -14,33 +14,33 @@
- 配置文件server/manifest/config/config.yaml
```yaml
#消息队列
# 消息队列
queue:
switch: true # 队列开关可选true|false默认为true
driver: "disk" # 队列驱动可选redis|rocketmq|kafka默认为disk
retry: 2 # 重试次数仅rocketmq|redis支持
driver: "disk" # 队列驱动,可选:disk|redis|rocketmq|kafka默认为disk
groupName: "hotgo" # mq群组名称
#磁盘队列
# 磁盘队列
disk:
path: "./storage/diskqueue" # 数据存放路径
batchSize: 100 # 每100条消息同步一次batchSize和batchTime满足其一就会同步一次
batchTime: 1 # 每1秒消息同步一次
segmentSize: 10485760 # 每个topic分片数据文件最大字节默认10M
segmentLimit: 3000 # 每个topic最大分片数据文件数量超出部分将会丢弃
# redis默认使用全局redis运行队列
redis:
address: "127.0.0.1:6379" # redis服务地址默认为127.0.0.1:6379
db: 2 # 指定redis库
pass: "" # redis密码
timeout: 0 # 队列超时时间(s) 0为永不超时当队列一直没有被消费到达超时时间则队列会被销毁
timeout: 0 # 队列超时时间以秒为单位0表示永不超时。如果队列在设定的超时时间内没有被消费则会被销毁
rocketmq:
address: "127.0.0.1:9876" # brocker地址+端口
logLevel: "all" # 系统日志级别可选all|close|debug|info|warn|error|fatal
nameSrvAdders: ["127.0.0.1:9876"] # nameSrvAdder+端口,支持多个
accessKey: "" # 选填。如果开启了acl控制就必填
secretKey: "" # 选填。如果开启了acl控制就必填
brokerAddr: "127.0.0.1:10911" # brokerAddr+端口选填。用于消费者订阅主题前会检查主题是否存在不存在会自动创建。你也可以在rocketmq控制台手动创建主题
retry: 0 # 重试次数
logLevel: "info" # 系统日志级别可选all|close|debug|info|warn|error|fatal
kafka:
address: "127.0.0.1:9092" # kafka地址+端口
version: "2.0.0.0" # kafka专属配置默认2.0.0.0
randClient: true # 开启随机生成clientID可以实现启动多实例同时一起消费相同topic加速消费能力的特性默认为true
multiConsumer: true # 是否支持创建多个消费者
```
### 实现接口
@@ -123,7 +123,7 @@ func test() {
```
延迟队列目前只有redis驱动支持:
延迟队列目前只有redis、rocketmq驱动支持:
```go
package main
@@ -140,10 +140,19 @@ func test() {
//...
}
// 延迟10秒
// redis 延迟10秒
if err := queue.SendDelayMsg(consts.QueueLogTopic, data, 10); err != nil {
fmt.Printf("queue.Push err:%+v", err)
}
// rocketmq 延迟5秒
// 注意rocketmq这里传入的是延迟级别而不是秒
// 消息的延时级别level一共有18级分别为
// 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
// 参考https://github.com/apache/rocketmq-client-go/blob/0e19ee654819bda396a08d950c883f9008b8222b/primitive/message.go#L174
if err := queue.SendDelayMsg(consts.QueueLogTopic, data, 2); err != nil {
fmt.Printf("queue.Push err:%+v", err)
}
}
```
@@ -178,10 +187,10 @@ type MqMsg struct {
Body []byte `json:"body"`
}
type MqProducer interface {
SendMsg(topic string, body string) (mqMsg MqMsg, err error)
SendByteMsg(topic string, body []byte) (mqMsg MqMsg, err error)
SendDelayMsg(topic string, body string, delay int64) (mqMsg MqMsg, err error)
}
type MqConsumer interface {

View File

@@ -0,0 +1,172 @@
## SaaS多租户
目录
- 介绍
- 职责划分
- 如何在HotGo开发多租户业务
- 多租户数据库设计
- 多租户功能演示
### 介绍
SaaS系统多租户多应用设计已成为互联网企业的重要发展建设方向。核心在于多租户SAAS系统独立前台、共享后台、共享数据库的平台应用架构。
> 目前HotGo的部分基础功能并不完全支持多租户设计但这并不妨碍开发者基于HotGo构建自己的多租户产品
### 职责划分
在SaaS系统多租户中不同身份用户的职责功能划分假设可以是这样
> 这只是一个粗略的概念,实际开发时应根据业务来进行调整,每个身份也都不是必须的。
| 身份 | 标识 | 职责和功能划分 |
|-----------------|----------|-------------------------------------------------------|
| 公司| company | 管理整个平台,包括商户和用户账户、系统设置以及其他全局性业务流程。 |
| 租户 | tenant | 多租户系统中顶层实体客户、组织或实体。有自己的多个商户、用户、产品、订单等。拥有独立的数据隔离和安全边界。 |
| 商户 | merchant | 受租户的监管和管理,可独立经营的实体。提供产品或服务,管理自己的业务,包括库存管理、订单处理、结算等。 |
| 用户 | user | 真正购买产品或享受服务的人,与商户互动,管理个人信息等个性化功能。 |
### 如何在HotGo开发多租户业务
#### 一、应用功能
根据角色来划分用户的后台功能,在创建用户时为其绑定角色,然后为不同角色分配不同的功能菜单
请参考: [权限控制](sys-auth.md)
#### 二、 数据隔离
根据部门来划定用户的数据权限范围,在创建用户时为其绑定部门
- 在用户登录成功后server端可通过上下文来获取用户部门类型来确定用户身份
- 文件路径server/internal/library/contexts/context.go
```go
package contexts
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/internal/consts"
"hotgo/internal/model"
)
// GetDeptType 获取用户部门类型
func GetDeptType(ctx context.Context) string {
user := GetUser(ctx)
if user == nil {
return ""
}
return user.DeptType
}
// IsCompanyDept 是否为公司部门
func IsCompanyDept(ctx context.Context) bool {
return GetDeptType(ctx) == consts.DeptTypeCompany
}
// IsTenantDept 是否为租户部门
func IsTenantDept(ctx context.Context) bool {
return GetDeptType(ctx) == consts.DeptTypeTenant
}
// IsMerchantDept 是否为商户部门
func IsMerchantDept(ctx context.Context) bool {
return GetDeptType(ctx) == consts.DeptTypeMerchant
}
// IsUserDept 是否为普通用户部门
func IsUserDept(ctx context.Context) bool {
return GetDeptType(ctx) == consts.DeptTypeUser
}
```
- 在用户登录成功后web端可通`useUserStore`来获取用户部门类型来确定用户身份
- 文件路径web/src/store/modules/user.ts
```vue
<script lang="ts" setup>
import { useUserStore } from '@/store/modules/user';
const userStore = useUserStore();
console.log('用户部门类型:' + userStore.info?.deptType);
console.log('是否为公司:' + userStore.isCompanyDept);
console.log('是否为租户:' + userStore.isTenantDept);
console.log('是否为商户:' + userStore.isMerchantDept);
console.log('是否为用户:' + userStore.isUserDept);
</script>
```
### 多租户数据库设计
HotGo定位是中小型应用开发推荐采用一套数据库不同Schema。就是在多租户业务表中加入用户标识字段来区分不同用户的数据`tenant_id`
- 参考文章https://blog.csdn.net/haponchang/article/details/104246317
### 多租户功能演示
请登录后台【插件应用】-【功能案例】-【多租户功能演示】查看
#### 自动维护租户关系
- 只需在表设计时包含以下字段即可使用handler和hook实现租户权限过滤和租户关系维护
| 字段名称 | 数据类型 | 字段注释 | 必选 |
|------|----------|------|-----------------------------------------------------|
| tenant_id | bigint(20) | 租户ID | 否 |
| merchant_id | bigint(20) | 商户ID | 否 |
| user_id | bigint(20) | 用户ID | 否 |
下面是多租户功能演示例子代码中的使用片段
- 封装查询Model
```go
// Model 多租户功能演示ORM模型
func (s *sSysTenantOrder) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
if len(option) == 0 {
// 过滤多租户数据权限
option = append(option, &handler.Option{
FilterTenant: true,
//FilterAuth: true, // 如果还需要维护created_by、member_id等部门数据权限范围可放开注释
})
}
return handler.Model(dao.AddonHgexampleTenantOrder.Ctx(ctx), option...)
}
```
- 增改数据自动维护租户关系
```go
// Edit 修改/新增多租户功能演示
func (s *sSysTenantOrder) Edit(ctx context.Context, in *sysin.TenantOrderEditInp) (err error) {
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
// 修改
if in.Id > 0 {
if _, err = s.Model(ctx).
Fields(sysin.TenantOrderUpdateFields{}).
WherePri(in.Id).Data(in).
Hook(hook.SaveTenant). // 自动维护租户关系更新
Update(); err != nil {
}
return
}
// 新增
if _, err = dao.AddonHgexampleTenantOrder.Ctx(ctx).
Fields(sysin.TenantOrderInsertFields{}).
Hook(hook.SaveTenant). // 自动维护租户关系更新
Data(in).
Insert(); err != nil {
}
return
})
}
```
相关代码文件:/server/addons/hgexample/logic/sys/tenant_order.go