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

@ -6,13 +6,13 @@
</p>
<p align="center">
<a href="https://goframe.org/pages/viewpage.action?pageId=1114119" target="_blank">
<img src="https://img.shields.io/badge/goframe-2.6-green" alt="goframe">
<img src="https://img.shields.io/badge/goframe-2.7-green" alt="goframe">
</a>
<a href="https://v3.vuejs.org/" target="_blank">
<img src="https://img.shields.io/badge/vue.js-vue3.4-green" alt="vue">
</a>
<a href="https://www.naiveui.com" target="_blank">
<img src="https://img.shields.io/badge/naiveui-%3E2.36.0-blue" alt="naiveui">
<img src="https://img.shields.io/badge/naiveui-%3E2.38.0-blue" alt="naiveui">
</a>
<a href="https://www.tslang.cn/" target="_blank">
<img src="https://img.shields.io/badge/typescript-%3E4.0.0-blue" alt="typescript">
@ -83,24 +83,28 @@
<table>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/1.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/2.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/1.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/2.png"/></td>
</tr>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/3.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/4.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/3.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/4.png"/></td>
</tr>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/5.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/6.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/5.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/6.png"/></td>
</tr>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/7.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/8.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/7.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/8.png"/></td>
</tr>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/9.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/10.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/9.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/10.png"/></td>
</tr>
<tr>
<td><img src="./docs/guide-zh-CN/images/demo/11.png"/></td>
<td><img src="./docs/guide-zh-CN/images/demo/12.png"/></td>
</tr>
</table>

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

View File

@ -13,18 +13,18 @@ import (
// ListReq 查询列表
type ListReq struct {
g.Meta `path:"/table/list" method:"get" tags:"表格" summary:"获取表格列表"`
g.Meta `path:"/table/list" method:"get" tags:"表格例子" summary:"获取表格列表"`
sysin.TableListInp
}
type ListRes struct {
form.PageRes
List []*sysin.TableListModel `json:"list" dc:"数据列表"`
List []*sysin.TableListModel `json:"list" dc:"数据列表"`
}
// ExportReq 导出列表
type ExportReq struct {
g.Meta `path:"/table/export" method:"get" tags:"表格" summary:"导出表格列表"`
g.Meta `path:"/table/export" method:"get" tags:"表格例子" summary:"导出表格列表"`
sysin.TableListInp
}
@ -32,7 +32,7 @@ type ExportRes struct{}
// ViewReq 获取信息
type ViewReq struct {
g.Meta `path:"/table/view" method:"get" tags:"表格" summary:"获取指定信息"`
g.Meta `path:"/table/view" method:"get" tags:"表格例子" summary:"获取指定信息"`
sysin.TableViewInp
}
@ -42,7 +42,7 @@ type ViewRes struct {
// EditReq 修改/新增
type EditReq struct {
g.Meta `path:"/table/edit" method:"post" tags:"表格" summary:"修改/新增表格"`
g.Meta `path:"/table/edit" method:"post" tags:"表格例子" summary:"修改/新增表格"`
sysin.TableEditInp
}
@ -50,7 +50,7 @@ type EditRes struct{}
// DeleteReq 删除
type DeleteReq struct {
g.Meta `path:"/table/delete" method:"post" tags:"表格" summary:"删除表格"`
g.Meta `path:"/table/delete" method:"post" tags:"表格例子" summary:"删除表格"`
sysin.TableDeleteInp
}
@ -58,7 +58,7 @@ type DeleteRes struct{}
// MaxSortReq 最大排序
type MaxSortReq struct {
g.Meta `path:"/table/maxSort" method:"get" tags:"表格" summary:"表格最大排序"`
g.Meta `path:"/table/maxSort" method:"get" tags:"表格例子" summary:"表格最大排序"`
sysin.TableMaxSortInp
}
@ -68,7 +68,7 @@ type MaxSortRes struct {
// StatusReq 更新状态
type StatusReq struct {
g.Meta `path:"/table/status" method:"post" tags:"表格" summary:"更新表格状态"`
g.Meta `path:"/table/status" method:"post" tags:"表格例子" summary:"更新表格状态"`
sysin.TableStatusInp
}
@ -76,7 +76,7 @@ type StatusRes struct{}
// SwitchReq 更新开关状态
type SwitchReq struct {
g.Meta `path:"/table/switch" method:"post" tags:"表格" summary:"更新表格状态"`
g.Meta `path:"/table/switch" method:"post" tags:"表格例子" summary:"更新表格状态"`
sysin.TableSwitchInp
}

View File

@ -0,0 +1,59 @@
// Package tenantorder
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1
package tenantorder
import (
"hotgo/addons/hgexample/model/input/sysin"
"hotgo/internal/model/input/form"
"github.com/gogf/gf/v2/frame/g"
)
// ListReq 查询多租户功能演示列表
type ListReq struct {
g.Meta `path:"/tenantOrder/list" method:"get" tags:"多租户功能演示" summary:"获取多租户功能演示列表"`
sysin.TenantOrderListInp
}
type ListRes struct {
form.PageRes
List []*sysin.TenantOrderListModel `json:"list" dc:"数据列表"`
}
// ExportReq 导出多租户功能演示列表
type ExportReq struct {
g.Meta `path:"/tenantOrder/export" method:"get" tags:"多租户功能演示" summary:"导出多租户功能演示列表"`
sysin.TenantOrderListInp
}
type ExportRes struct{}
// ViewReq 获取多租户功能演示指定信息
type ViewReq struct {
g.Meta `path:"/tenantOrder/view" method:"get" tags:"多租户功能演示" summary:"获取多租户功能演示指定信息"`
sysin.TenantOrderViewInp
}
type ViewRes struct {
*sysin.TenantOrderViewModel
}
// EditReq 修改/新增多租户功能演示
type EditReq struct {
g.Meta `path:"/tenantOrder/edit" method:"post" tags:"多租户功能演示" summary:"修改/新增多租户功能演示"`
sysin.TenantOrderEditInp
}
type EditRes struct{}
// DeleteReq 删除多租户功能演示
type DeleteReq struct {
g.Meta `path:"/tenantOrder/delete" method:"post" tags:"多租户功能演示" summary:"删除多租户功能演示"`
sysin.TenantOrderDeleteInp
}
type DeleteRes struct{}

View File

@ -13,7 +13,7 @@ import (
// ListReq 查询列表
type ListReq struct {
g.Meta `path:"/treeTable/list" method:"get" tags:"表格" summary:"获取表格列表"`
g.Meta `path:"/treeTable/list" method:"get" tags:"树形表格例子" summary:"获取表格列表"`
sysin.TreeTableListInp
}
@ -24,7 +24,7 @@ type ListRes struct {
// ExportReq 导出列表
type ExportReq struct {
g.Meta `path:"/treeTable/export" method:"get" tags:"表格" summary:"导出表格列表"`
g.Meta `path:"/treeTable/export" method:"get" tags:"树形表格例子" summary:"导出表格列表"`
sysin.TableListInp
}
@ -32,7 +32,7 @@ type ExportRes struct{}
// ViewReq 获取信息
type ViewReq struct {
g.Meta `path:"/treeTable/view" method:"get" tags:"表格" summary:"获取指定信息"`
g.Meta `path:"/treeTable/view" method:"get" tags:"树形表格例子" summary:"获取指定信息"`
sysin.TableViewInp
}
@ -42,7 +42,7 @@ type ViewRes struct {
// EditReq 修改/新增
type EditReq struct {
g.Meta `path:"/treeTable/edit" method:"post" tags:"表格" summary:"修改/新增表格"`
g.Meta `path:"/treeTable/edit" method:"post" tags:"树形表格例子" summary:"修改/新增表格"`
sysin.TableEditInp
}
@ -50,7 +50,7 @@ type EditRes struct{}
// DeleteReq 删除
type DeleteReq struct {
g.Meta `path:"/treeTable/delete" method:"post" tags:"表格" summary:"删除表格"`
g.Meta `path:"/treeTable/delete" method:"post" tags:"树形表格例子" summary:"删除表格"`
sysin.TableDeleteInp
}
@ -58,7 +58,7 @@ type DeleteRes struct{}
// MaxSortReq 最大排序
type MaxSortReq struct {
g.Meta `path:"/treeTable/maxSort" method:"get" tags:"表格" summary:"表格最大排序"`
g.Meta `path:"/treeTable/maxSort" method:"get" tags:"树形表格例子" summary:"表格最大排序"`
sysin.TableMaxSortInp
}
@ -68,7 +68,7 @@ type MaxSortRes struct {
// StatusReq 更新状态
type StatusReq struct {
g.Meta `path:"/treeTable/status" method:"post" tags:"表格" summary:"更新表格状态"`
g.Meta `path:"/treeTable/status" method:"post" tags:"树形表格例子" summary:"更新表格状态"`
sysin.TableStatusInp
}
@ -76,7 +76,7 @@ type StatusRes struct{}
// SwitchReq 更新开关状态
type SwitchReq struct {
g.Meta `path:"/treeTable/switch" method:"post" tags:"表格" summary:"更新表格状态"`
g.Meta `path:"/treeTable/switch" method:"post" tags:"树形表格例子" summary:"更新表格状态"`
sysin.TableSwitchInp
}
@ -84,7 +84,7 @@ type SwitchRes struct{}
// SelectReq 树形选项
type SelectReq struct {
g.Meta `path:"/treeTable/select" method:"get" tags:"表格" summary:"树形选项"`
g.Meta `path:"/treeTable/select" method:"get" tags:"树形表格例子" summary:"树形选项"`
}
type SelectRes struct {

View File

@ -12,7 +12,7 @@ import (
// TestReq 测试
type TestReq struct {
g.Meta `path:"/index/test" method:"get" summary:"功能案例" tags:"测试首页"`
g.Meta `path:"/index/test" method:"get" tags:"功能案例" summary:"测试首页"`
sysin.IndexTestInp
}

View File

@ -20,10 +20,10 @@ type cComp struct{}
// ImportExcel 导入Excel
func (c *cComp) ImportExcel(ctx context.Context, req *comp.ImportExcelReq) (res *comp.ImportExcelRes, err error) {
file, err := req.File.Open()
defer file.Close()
if err != nil {
return
}
defer file.Close()
excel, err := excelize.OpenReader(file)
if err != nil {

View File

@ -0,0 +1,67 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1
package sys
import (
"context"
"hotgo/addons/hgexample/api/admin/tenantorder"
"hotgo/addons/hgexample/model/input/sysin"
"hotgo/addons/hgexample/service"
)
var (
TenantOrder = cTenantOrder{}
)
type cTenantOrder struct{}
// List 查看多租户功能演示列表
func (c *cTenantOrder) List(ctx context.Context, req *tenantorder.ListReq) (res *tenantorder.ListRes, err error) {
list, totalCount, err := service.SysTenantOrder().List(ctx, &req.TenantOrderListInp)
if err != nil {
return
}
if list == nil {
list = []*sysin.TenantOrderListModel{}
}
res = new(tenantorder.ListRes)
res.List = list
res.PageRes.Pack(req, totalCount)
return
}
// Export 导出多租户功能演示列表
func (c *cTenantOrder) Export(ctx context.Context, req *tenantorder.ExportReq) (res *tenantorder.ExportRes, err error) {
err = service.SysTenantOrder().Export(ctx, &req.TenantOrderListInp)
return
}
// Edit 更新多租户功能演示
func (c *cTenantOrder) Edit(ctx context.Context, req *tenantorder.EditReq) (res *tenantorder.EditRes, err error) {
err = service.SysTenantOrder().Edit(ctx, &req.TenantOrderEditInp)
return
}
// View 获取指定多租户功能演示信息
func (c *cTenantOrder) View(ctx context.Context, req *tenantorder.ViewReq) (res *tenantorder.ViewRes, err error) {
data, err := service.SysTenantOrder().View(ctx, &req.TenantOrderViewInp)
if err != nil {
return
}
res = new(tenantorder.ViewRes)
res.TenantOrderViewModel = data
return
}
// Delete 删除多租户功能演示
func (c *cTenantOrder) Delete(ctx context.Context, req *tenantorder.DeleteReq) (res *tenantorder.DeleteRes, err error) {
err = service.SysTenantOrder().Delete(ctx, &req.TenantOrderDeleteInp)
return
}

View File

@ -119,7 +119,7 @@ func (s *sSysTable) Export(ctx context.Context, in *sysin.TableListInp) (err err
}
var (
fileName = "表格例子导出-" + gctx.CtxId(ctx) + ".xlsx"
fileName = "表格例子导出-" + gctx.CtxId(ctx)
sheetName = fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list))
exports []sysin.TableExportModel
)

View File

@ -0,0 +1,176 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1
package sys
import (
"context"
"fmt"
"hotgo/addons/hgexample/model/input/sysin"
"hotgo/addons/hgexample/service"
"hotgo/internal/dao"
"hotgo/internal/library/hgorm/handler"
"hotgo/internal/library/hgorm/hook"
"hotgo/internal/model/input/form"
"hotgo/utility/convert"
"hotgo/utility/excel"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/util/gconv"
)
type sSysTenantOrder struct{}
func NewSysTenantOrder() *sSysTenantOrder {
return &sSysTenantOrder{}
}
func init() {
service.RegisterSysTenantOrder(NewSysTenantOrder())
}
// 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...)
}
// List 获取多租户功能演示列表
func (s *sSysTenantOrder) List(ctx context.Context, in *sysin.TenantOrderListInp) (list []*sysin.TenantOrderListModel, totalCount int, err error) {
mod := s.Model(ctx)
// 字段过滤
mod = mod.Fields(sysin.TenantOrderListModel{})
// 查询主键
if in.Id > 0 {
mod = mod.Where(dao.AddonHgexampleTenantOrder.Columns().Id, in.Id)
}
// 查询租户ID
if in.TenantId > 0 {
mod = mod.Where(dao.AddonHgexampleTenantOrder.Columns().TenantId, in.TenantId)
}
// 查询商户ID
if in.MerchantId > 0 {
mod = mod.Where(dao.AddonHgexampleTenantOrder.Columns().MerchantId, in.MerchantId)
}
// 查询用户ID
if in.UserId > 0 {
mod = mod.Where(dao.AddonHgexampleTenantOrder.Columns().UserId, in.UserId)
}
// 查询关联订单号
if in.OrderSn != "" {
mod = mod.Where(dao.AddonHgexampleTenantOrder.Columns().OrderSn, in.OrderSn)
}
// 查询支付状态
if in.Status > 0 {
mod = mod.Where(dao.AddonHgexampleTenantOrder.Columns().Status, in.Status)
}
// 查询创建时间
if len(in.CreatedAt) == 2 {
mod = mod.WhereBetween(dao.AddonHgexampleTenantOrder.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
}
// 分页
mod = mod.Page(in.Page, in.PerPage)
// 排序
mod = mod.OrderDesc(dao.AddonHgexampleTenantOrder.Columns().Id)
// 查询数据
if err = mod.ScanAndCount(&list, &totalCount, false); err != nil {
err = gerror.Wrap(err, "获取多租户功能演示列表失败,请稍后重试!")
return
}
return
}
// Export 导出多租户功能演示
func (s *sSysTenantOrder) Export(ctx context.Context, in *sysin.TenantOrderListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
}
// 字段的排序是依据tags的字段顺序如果你不想使用默认的排序方式可以直接定义 tags = []string{"字段名称", "字段名称2", ...}
tags, err := convert.GetEntityDescTags(sysin.TenantOrderExportModel{})
if err != nil {
return
}
var (
fileName = "导出多租户功能演示-" + gctx.CtxId(ctx)
sheetName = fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list))
exports []sysin.TenantOrderExportModel
)
if err = gconv.Scan(list, &exports); err != nil {
return
}
err = excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
return
}
// 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
})
}
// Delete 删除多租户功能演示
func (s *sSysTenantOrder) Delete(ctx context.Context, in *sysin.TenantOrderDeleteInp) (err error) {
if _, err = s.Model(ctx).WherePri(in.Id).Delete(); err != nil {
err = gerror.Wrap(err, "删除多租户功能演示失败,请稍后重试!")
return
}
return
}
// View 获取多租户功能演示指定信息
func (s *sSysTenantOrder) View(ctx context.Context, in *sysin.TenantOrderViewInp) (res *sysin.TenantOrderViewModel, err error) {
if err = s.Model(ctx).WherePri(in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取多租户功能演示信息,请稍后重试!")
return
}
return
}

View File

@ -0,0 +1,123 @@
// Package sysin
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1
package sysin
import (
"context"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TenantOrderUpdateFields 修改多租户功能演示字段过滤
type TenantOrderUpdateFields struct {
TenantId int64 `json:"tenantId" dc:"租户ID"`
MerchantId int64 `json:"merchantId" dc:"商户ID"`
UserId int64 `json:"userId" dc:"用户ID"`
ProductName string `json:"productName" dc:"购买产品"`
OrderSn string `json:"orderSn" dc:"关联订单号"`
Money float64 `json:"money" dc:"充值金额"`
Remark string `json:"remark" dc:"备注"`
Status int `json:"status" dc:"支付状态"`
}
// TenantOrderInsertFields 新增多租户功能演示字段过滤
type TenantOrderInsertFields struct {
TenantId int64 `json:"tenantId" dc:"租户ID"`
MerchantId int64 `json:"merchantId" dc:"商户ID"`
UserId int64 `json:"userId" dc:"用户ID"`
ProductName string `json:"productName" dc:"购买产品"`
OrderSn string `json:"orderSn" dc:"关联订单号"`
Money float64 `json:"money" dc:"充值金额"`
Remark string `json:"remark" dc:"备注"`
Status int `json:"status" dc:"支付状态"`
}
// TenantOrderEditInp 修改/新增多租户功能演示
type TenantOrderEditInp struct {
entity.AddonHgexampleTenantOrder
}
func (in *TenantOrderEditInp) Filter(ctx context.Context) (err error) {
// 验证充值金额
if err := g.Validator().Rules("required").Data(in.Money).Messages("充值金额不能为空").Run(ctx); err != nil {
return err.Current()
}
return
}
type TenantOrderEditModel struct{}
// TenantOrderDeleteInp 删除多租户功能演示
type TenantOrderDeleteInp struct {
Id interface{} `json:"id" v:"required#主键不能为空" dc:"主键"`
}
func (in *TenantOrderDeleteInp) Filter(ctx context.Context) (err error) {
return
}
type TenantOrderDeleteModel struct{}
// TenantOrderViewInp 获取指定多租户功能演示信息
type TenantOrderViewInp struct {
Id int64 `json:"id" v:"required#主键不能为空" dc:"主键"`
}
func (in *TenantOrderViewInp) Filter(ctx context.Context) (err error) {
return
}
type TenantOrderViewModel struct {
entity.AddonHgexampleTenantOrder
}
// TenantOrderListInp 获取多租户功能演示列表
type TenantOrderListInp struct {
form.PageReq
Id int64 `json:"id" dc:"主键"`
TenantId int64 `json:"tenantId" dc:"租户ID"`
MerchantId int64 `json:"merchantId" dc:"商户ID"`
UserId int64 `json:"userId" dc:"用户ID"`
OrderSn string `json:"orderSn" dc:"关联订单号"`
Status int `json:"status" dc:"支付状态"`
CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
}
func (in *TenantOrderListInp) Filter(ctx context.Context) (err error) {
return
}
type TenantOrderListModel struct {
Id int64 `json:"id" dc:"主键"`
TenantId int64 `json:"tenantId" dc:"租户ID"`
MerchantId int64 `json:"merchantId" dc:"商户ID"`
UserId int64 `json:"userId" dc:"用户ID"`
ProductName string `json:"productName" dc:"购买产品"`
OrderSn string `json:"orderSn" dc:"关联订单号"`
Money float64 `json:"money" dc:"充值金额"`
Remark string `json:"remark" dc:"备注"`
Status int `json:"status" dc:"支付状态"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
}
// TenantOrderExportModel 导出多租户功能演示
type TenantOrderExportModel struct {
Id int64 `json:"id" dc:"主键"`
TenantId int64 `json:"tenantId" dc:"租户ID"`
MerchantId int64 `json:"merchantId" dc:"商户ID"`
UserId int64 `json:"userId" dc:"用户ID"`
ProductName string `json:"productName" dc:"购买产品"`
OrderSn string `json:"orderSn" dc:"关联订单号"`
Money float64 `json:"money" dc:"充值金额"`
Remark string `json:"remark" dc:"备注"`
Status int `json:"status" dc:"支付状态"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
}

View File

@ -0,0 +1,13 @@
// Package genrouter
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1
package genrouter
import "hotgo/addons/hgexample/controller/admin/sys"
func init() {
LoginRequiredRouter = append(LoginRequiredRouter, sys.TenantOrder) // 多租户功能演示
}

View File

@ -47,6 +47,20 @@ type (
// View 获取指定信息
View(ctx context.Context, in *sysin.TableViewInp) (res *sysin.TableViewModel, err error)
}
ISysTenantOrder interface {
// Model 多租户功能演示ORM模型
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
// List 获取多租户功能演示列表
List(ctx context.Context, in *sysin.TenantOrderListInp) (list []*sysin.TenantOrderListModel, totalCount int, err error)
// Export 导出多租户功能演示
Export(ctx context.Context, in *sysin.TenantOrderListInp) (err error)
// Edit 修改/新增多租户功能演示
Edit(ctx context.Context, in *sysin.TenantOrderEditInp) (err error)
// Delete 删除多租户功能演示
Delete(ctx context.Context, in *sysin.TenantOrderDeleteInp) (err error)
// View 获取多租户功能演示指定信息
View(ctx context.Context, in *sysin.TenantOrderViewInp) (res *sysin.TenantOrderViewModel, err error)
}
ISysTreeTable interface {
// Model Orm模型
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
@ -62,10 +76,11 @@ type (
)
var (
localSysConfig ISysConfig
localSysIndex ISysIndex
localSysTable ISysTable
localSysTreeTable ISysTreeTable
localSysConfig ISysConfig
localSysIndex ISysIndex
localSysTable ISysTable
localSysTenantOrder ISysTenantOrder
localSysTreeTable ISysTreeTable
)
func SysConfig() ISysConfig {
@ -101,6 +116,17 @@ func RegisterSysTable(i ISysTable) {
localSysTable = i
}
func SysTenantOrder() ISysTenantOrder {
if localSysTenantOrder == nil {
panic("implement not found for interface ISysTenantOrder, forgot register?")
}
return localSysTenantOrder
}
func RegisterSysTenantOrder(i ISysTenantOrder) {
localSysTenantOrder = i
}
func SysTreeTable() ISysTreeTable {
if localSysTreeTable == nil {
panic("implement not found for interface ISysTreeTable, forgot register?")

View File

@ -12,14 +12,14 @@ import (
// UploadFileReq 上传文件
type UploadFileReq struct {
g.Meta `path:"/upload/file" tags:"上传" method:"post" summary:"上传附件"`
g.Meta `path:"/upload/file" tags:"附件" method:"post" summary:"上传附件"`
}
type UploadFileRes *sysin.AttachmentListModel
// CheckMultipartReq 检查文件分片
type CheckMultipartReq struct {
g.Meta `path:"/upload/checkMultipart" tags:"上传" method:"post" summary:"检查文件分片"`
g.Meta `path:"/upload/checkMultipart" tags:"附件" method:"post" summary:"检查文件分片"`
sysin.CheckMultipartInp
}
@ -29,7 +29,7 @@ type CheckMultipartRes struct {
// UploadPartReq 分片上传
type UploadPartReq struct {
g.Meta `path:"/upload/uploadPart" tags:"上传" method:"post" summary:"分片上传"`
g.Meta `path:"/upload/uploadPart" tags:"附件" method:"post" summary:"分片上传"`
sysin.UploadPartInp
}

View File

@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.12.10
// @AutoGenerate Version 2.13.1
package curddemo
import (
@ -13,9 +13,9 @@ import (
"github.com/gogf/gf/v2/frame/g"
)
// ListReq 查询生成演示列表
// ListReq 查询CURD列表列表
type ListReq struct {
g.Meta `path:"/curdDemo/list" method:"get" tags:"生成演示" summary:"获取生成演示列表"`
g.Meta `path:"/curdDemo/list" method:"get" tags:"CURD列表" summary:"获取CURD列表列表"`
sysin.CurdDemoListInp
}
@ -24,17 +24,17 @@ type ListRes struct {
List []*sysin.CurdDemoListModel `json:"list" dc:"数据列表"`
}
// ExportReq 导出生成演示列表
// ExportReq 导出CURD列表列表
type ExportReq struct {
g.Meta `path:"/curdDemo/export" method:"get" tags:"生成演示" summary:"导出生成演示列表"`
g.Meta `path:"/curdDemo/export" method:"get" tags:"CURD列表" summary:"导出CURD列表列表"`
sysin.CurdDemoListInp
}
type ExportRes struct{}
// ViewReq 获取生成演示指定信息
// ViewReq 获取CURD列表指定信息
type ViewReq struct {
g.Meta `path:"/curdDemo/view" method:"get" tags:"生成演示" summary:"获取生成演示指定信息"`
g.Meta `path:"/curdDemo/view" method:"get" tags:"CURD列表" summary:"获取CURD列表指定信息"`
sysin.CurdDemoViewInp
}
@ -42,25 +42,25 @@ type ViewRes struct {
*sysin.CurdDemoViewModel
}
// EditReq 修改/新增生成演示
// EditReq 修改/新增CURD列表
type EditReq struct {
g.Meta `path:"/curdDemo/edit" method:"post" tags:"生成演示" summary:"修改/新增生成演示"`
g.Meta `path:"/curdDemo/edit" method:"post" tags:"CURD列表" summary:"修改/新增CURD列表"`
sysin.CurdDemoEditInp
}
type EditRes struct{}
// DeleteReq 删除生成演示
// DeleteReq 删除CURD列表
type DeleteReq struct {
g.Meta `path:"/curdDemo/delete" method:"post" tags:"生成演示" summary:"删除生成演示"`
g.Meta `path:"/curdDemo/delete" method:"post" tags:"CURD列表" summary:"删除CURD列表"`
sysin.CurdDemoDeleteInp
}
type DeleteRes struct{}
// MaxSortReq 获取生成演示最大排序
// MaxSortReq 获取CURD列表最大排序
type MaxSortReq struct {
g.Meta `path:"/curdDemo/maxSort" method:"get" tags:"生成演示" summary:"获取生成演示最大排序"`
g.Meta `path:"/curdDemo/maxSort" method:"get" tags:"CURD列表" summary:"获取CURD列表最大排序"`
sysin.CurdDemoMaxSortInp
}
@ -68,17 +68,9 @@ type MaxSortRes struct {
*sysin.CurdDemoMaxSortModel
}
// StatusReq 更新生成演示状态
type StatusReq struct {
g.Meta `path:"/curdDemo/status" method:"post" tags:"生成演示" summary:"更新生成演示状态"`
sysin.CurdDemoStatusInp
}
type StatusRes struct{}
// SwitchReq 更新生成演示开关状态
// SwitchReq 更新CURD列表开关状态
type SwitchReq struct {
g.Meta `path:"/curdDemo/switch" method:"post" tags:"生成演示" summary:"更新生成演示状态"`
g.Meta `path:"/curdDemo/switch" method:"post" tags:"CURD列表" summary:"更新CURD列表状态"`
sysin.CurdDemoSwitchInp
}

View File

@ -9,6 +9,7 @@ import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/form"
"hotgo/utility/tree"
)
// ListReq 查询列表
@ -55,17 +56,9 @@ type MaxSortRes struct {
*adminin.DeptMaxSortModel
}
// StatusReq 更新部门状态
type StatusReq struct {
g.Meta `path:"/dept/status" method:"post" tags:"部门" summary:"更新部门状态"`
adminin.DeptStatusInp
}
type StatusRes struct{}
// OptionReq 获取部门选项树
// OptionReq 获取当前登录用户可选的部门选项
type OptionReq struct {
g.Meta `path:"/dept/option" method:"get" tags:"部门" summary:"获取部门选项"`
g.Meta `path:"/dept/option" method:"get" tags:"部门" summary:"获取当前登录用户可选的部门选项"`
adminin.DeptOptionInp
}
@ -73,3 +66,10 @@ type OptionRes struct {
*adminin.DeptOptionModel
form.PageRes
}
// TreeOptionReq 获取部门关系树选项
type TreeOptionReq struct {
g.Meta `path:"/dept/treeOption" method:"get" tags:"部门" summary:"获取部门关系树选项"`
}
type TreeOptionRes []tree.Node

View File

@ -39,14 +39,14 @@ type DataListRes struct {
}
type DataSelectReq struct {
g.Meta `path:"/dictData/option/{Type}" method:"get" summary:"字典数据" tags:"获取指定字典选项"`
g.Meta `path:"/dictData/option/{Type}" method:"get" tags:"字典数据" summary:"获取指定字典选项"`
sysin.DataSelectInp
}
type DataSelectRes sysin.DataSelectModel
type DataSelectsReq struct {
g.Meta `path:"/dictData/options" method:"get" summary:"字典数据" tags:"获取多个字典选项"`
g.Meta `path:"/dictData/options" method:"get" tags:"字典数据" summary:"获取多个字典选项"`
Types []string `json:"types"`
}

View File

@ -13,14 +13,14 @@ import (
// ClearReq 清空日志
type ClearReq struct {
g.Meta `path:"/log/clear" method:"post" tags:"日志" summary:"清空日志"`
g.Meta `path:"/log/clear" method:"post" tags:"访问日志" summary:"清空日志"`
}
type ClearRes struct{}
// ExportReq 导出
type ExportReq struct {
g.Meta `path:"/log/export" method:"get" tags:"日志" summary:"导出日志"`
g.Meta `path:"/log/export" method:"get" tags:"访问日志" summary:"导出日志"`
sysin.LogListInp
}
@ -28,18 +28,18 @@ type ExportRes struct{}
// ListReq 获取菜单列表
type ListReq struct {
g.Meta `path:"/log/list" method:"get" tags:"日志" summary:"获取日志列表"`
g.Meta `path:"/log/list" method:"get" tags:"访问日志" summary:"获取日志列表"`
sysin.LogListInp
}
type ListRes struct {
List []*sysin.LogListModel `json:"list" dc:"数据列表"`
List []*sysin.LogListModel `json:"list" dc:"数据列表"`
form.PageRes
}
// DeleteReq 删除
type DeleteReq struct {
g.Meta `path:"/log/delete" method:"post" tags:"日志" summary:"删除日志"`
g.Meta `path:"/log/delete" method:"post" tags:"访问日志" summary:"删除日志"`
sysin.LogDeleteInp
}
@ -47,7 +47,7 @@ type DeleteRes struct{}
// ViewReq 获取指定信息
type ViewReq struct {
g.Meta `path:"/log/view" method:"get" tags:"日志" summary:"获取指定信息"`
g.Meta `path:"/log/view" method:"get" tags:"访问日志" summary:"获取指定信息"`
sysin.LogViewInp
}

View File

@ -0,0 +1,69 @@
// Package normaltreedemo
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1
package normaltreedemo
import (
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
"hotgo/utility/tree"
"github.com/gogf/gf/v2/frame/g"
)
// ListReq 查询普通树表列表
type ListReq struct {
g.Meta `path:"/normalTreeDemo/list" method:"get" tags:"普通树表" summary:"获取普通树表列表"`
sysin.NormalTreeDemoListInp
}
type ListRes struct {
form.PageRes
List []*sysin.NormalTreeDemoListModel `json:"list" dc:"数据列表"`
}
// ViewReq 获取普通树表指定信息
type ViewReq struct {
g.Meta `path:"/normalTreeDemo/view" method:"get" tags:"普通树表" summary:"获取普通树表指定信息"`
sysin.NormalTreeDemoViewInp
}
type ViewRes struct {
*sysin.NormalTreeDemoViewModel
}
// EditReq 修改/新增普通树表
type EditReq struct {
g.Meta `path:"/normalTreeDemo/edit" method:"post" tags:"普通树表" summary:"修改/新增普通树表"`
sysin.NormalTreeDemoEditInp
}
type EditRes struct{}
// DeleteReq 删除普通树表
type DeleteReq struct {
g.Meta `path:"/normalTreeDemo/delete" method:"post" tags:"普通树表" summary:"删除普通树表"`
sysin.NormalTreeDemoDeleteInp
}
type DeleteRes struct{}
// MaxSortReq 获取普通树表最大排序
type MaxSortReq struct {
g.Meta `path:"/normalTreeDemo/maxSort" method:"get" tags:"普通树表" summary:"获取普通树表最大排序"`
sysin.NormalTreeDemoMaxSortInp
}
type MaxSortRes struct {
*sysin.NormalTreeDemoMaxSortModel
}
// TreeOptionReq 获取普通树表关系树选项
type TreeOptionReq struct {
g.Meta `path:"/normalTreeDemo/treeOption" method:"get" tags:"普通树表" summary:"获取普通树表关系树选项"`
}
type TreeOptionRes []tree.Node

View File

@ -0,0 +1,69 @@
// Package optiontreedemo
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1
package optiontreedemo
import (
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
"hotgo/utility/tree"
"github.com/gogf/gf/v2/frame/g"
)
// ListReq 查询选项树表列表
type ListReq struct {
g.Meta `path:"/optionTreeDemo/list" method:"get" tags:"选项树表" summary:"获取选项树表列表"`
sysin.OptionTreeDemoListInp
}
type ListRes struct {
form.PageRes
List []*sysin.OptionTreeDemoListModel `json:"list" dc:"数据列表"`
}
// ViewReq 获取选项树表指定信息
type ViewReq struct {
g.Meta `path:"/optionTreeDemo/view" method:"get" tags:"选项树表" summary:"获取选项树表指定信息"`
sysin.OptionTreeDemoViewInp
}
type ViewRes struct {
*sysin.OptionTreeDemoViewModel
}
// EditReq 修改/新增选项树表
type EditReq struct {
g.Meta `path:"/optionTreeDemo/edit" method:"post" tags:"选项树表" summary:"修改/新增选项树表"`
sysin.OptionTreeDemoEditInp
}
type EditRes struct{}
// DeleteReq 删除选项树表
type DeleteReq struct {
g.Meta `path:"/optionTreeDemo/delete" method:"post" tags:"选项树表" summary:"删除选项树表"`
sysin.OptionTreeDemoDeleteInp
}
type DeleteRes struct{}
// MaxSortReq 获取选项树表最大排序
type MaxSortReq struct {
g.Meta `path:"/optionTreeDemo/maxSort" method:"get" tags:"选项树表" summary:"获取选项树表最大排序"`
sysin.OptionTreeDemoMaxSortInp
}
type MaxSortRes struct {
*sysin.OptionTreeDemoMaxSortModel
}
// TreeOptionReq 获取选项树表关系树选项
type TreeOptionReq struct {
g.Meta `path:"/optionTreeDemo/treeOption" method:"get" tags:"选项树表" summary:"获取选项树表关系树选项"`
}
type TreeOptionRes []tree.Node

View File

@ -98,7 +98,7 @@ type UniqueIdRes struct {
// SelectReq 省市区选项
type SelectReq struct {
g.Meta `path:"/provinces/select" method:"get" summary:"省市区" tags:"省市区选项"`
g.Meta `path:"/provinces/select" method:"get" tags:"省市区" summary:"省市区选项"`
sysin.ProvincesSelectInp
}
@ -108,7 +108,7 @@ type SelectRes struct {
// CityLabelReq 获取指定城市标签
type CityLabelReq struct {
g.Meta `path:"/provinces/cityLabel" method:"get" summary:"省市区" tags:"获取指定城市标签"`
g.Meta `path:"/provinces/cityLabel" method:"get" tags:"省市区" summary:"获取指定城市标签" `
sysin.ProvincesCityLabelInp
}

View File

@ -25,7 +25,7 @@ type ListRes struct {
// DynamicReq 动态路由
type DynamicReq struct {
g.Meta `path:"/role/dynamic" method:"get" tags:"路由" summary:"获取动态路由" description:"获取登录用户动态路由"`
g.Meta `path:"/role/dynamic" method:"get" tags:"角色" summary:"获取动态路由" description:"获取登录用户动态路由"`
}
type DynamicRes struct {
@ -66,7 +66,7 @@ type DeleteRes struct{}
// DataScopeSelectReq 获取数据权限选项
type DataScopeSelectReq struct {
g.Meta `path:"/role/dataScope/select" method:"get" summary:"角色" tags:"获取数据权限选项"`
g.Meta `path:"/role/dataScope/select" method:"get" tags:"角色" summary:"获取数据权限选项"`
}
type DataScopeSelectRes struct {

View File

@ -13,7 +13,7 @@ import (
// ListReq 查询列表
type ListReq struct {
g.Meta `path:"/smsLog/list" method:"get" tags:"短信记录" summary:"获取短信记录列表"`
g.Meta `path:"/smsLog/list" method:"get" tags:"短信" summary:"获取短信记录列表"`
sysin.SmsLogListInp
}
@ -24,7 +24,7 @@ type ListRes struct {
// ViewReq 获取指定信息
type ViewReq struct {
g.Meta `path:"/smsLog/view" method:"get" tags:"短信记录" summary:"获取指定信息"`
g.Meta `path:"/smsLog/view" method:"get" tags:"短信" summary:"获取指定短信信息"`
sysin.SmsLogViewInp
}
@ -32,26 +32,10 @@ type ViewRes struct {
*sysin.SmsLogViewModel
}
// EditReq 修改/新增数据
type EditReq struct {
g.Meta `path:"/smsLog/edit" method:"post" tags:"短信记录" summary:"修改/新增短信记录"`
sysin.SmsLogEditInp
}
type EditRes struct{}
// DeleteReq 删除
type DeleteReq struct {
g.Meta `path:"/smsLog/delete" method:"post" tags:"短信记录" summary:"删除短信记录"`
g.Meta `path:"/smsLog/delete" method:"post" tags:"短信" summary:"删除短信记录"`
sysin.SmsLogDeleteInp
}
type DeleteRes struct{}
// StatusReq 更新状态
type StatusReq struct {
g.Meta `path:"/smsLog/status" method:"post" tags:"短信记录" summary:"更新短信记录状态"`
sysin.SmsLogStatusInp
}
type StatusRes struct{}

View File

@ -0,0 +1,69 @@
// Package testcategory
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1
package testcategory
import (
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
"github.com/gogf/gf/v2/frame/g"
)
// ListReq 查询测试分类列表
type ListReq struct {
g.Meta `path:"/testCategory/list" method:"get" tags:"测试分类" summary:"获取测试分类列表"`
sysin.TestCategoryListInp
}
type ListRes struct {
form.PageRes
List []*sysin.TestCategoryListModel `json:"list" dc:"数据列表"`
}
// ViewReq 获取测试分类指定信息
type ViewReq struct {
g.Meta `path:"/testCategory/view" method:"get" tags:"测试分类" summary:"获取测试分类指定信息"`
sysin.TestCategoryViewInp
}
type ViewRes struct {
*sysin.TestCategoryViewModel
}
// EditReq 修改/新增测试分类
type EditReq struct {
g.Meta `path:"/testCategory/edit" method:"post" tags:"测试分类" summary:"修改/新增测试分类"`
sysin.TestCategoryEditInp
}
type EditRes struct{}
// DeleteReq 删除测试分类
type DeleteReq struct {
g.Meta `path:"/testCategory/delete" method:"post" tags:"测试分类" summary:"删除测试分类"`
sysin.TestCategoryDeleteInp
}
type DeleteRes struct{}
// MaxSortReq 获取测试分类最大排序
type MaxSortReq struct {
g.Meta `path:"/testCategory/maxSort" method:"get" tags:"测试分类" summary:"获取测试分类最大排序"`
sysin.TestCategoryMaxSortInp
}
type MaxSortRes struct {
*sysin.TestCategoryMaxSortModel
}
// StatusReq 更新测试分类状态
type StatusReq struct {
g.Meta `path:"/testCategory/status" method:"post" tags:"测试分类" summary:"更新测试分类状态"`
sysin.TestCategoryStatusInp
}
type StatusRes struct{}

View File

@ -1,19 +0,0 @@
// Package user
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package user
import (
"github.com/gogf/gf/v2/frame/g"
)
type HelloReq struct {
g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
Name string `json:"name" d:"hotgo" dc:"名字"`
}
type HelloRes struct {
Tips string `json:"tips"`
}

View File

@ -1,6 +1,8 @@
module hotgo
go 1.19
go 1.21
toolchain go1.22.1
require (
github.com/Shopify/sarama v1.34.1
@ -9,20 +11,20 @@ require (
github.com/alibabacloud-go/tea v1.1.20
github.com/alibabacloud-go/tea-utils/v2 v2.0.1
github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible
github.com/apache/rocketmq-client-go/v2 v2.1.0
github.com/apache/rocketmq-client-go/v2 v2.1.2
github.com/casbin/casbin/v2 v2.55.0
github.com/forgoer/openssl v1.4.0
github.com/go-pay/gopay v1.5.91
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.6.4
github.com/gogf/gf/contrib/nosql/redis/v2 v2.6.4
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.6.4
github.com/gogf/gf/v2 v2.6.4
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.7.0
github.com/gogf/gf/contrib/nosql/redis/v2 v2.7.0
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.7.0
github.com/gogf/gf/v2 v2.7.0
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/gorilla/websocket v1.5.1
github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794
github.com/minio/minio-go/v7 v7.0.63
github.com/mojocn/base64Captcha v1.3.5
github.com/mojocn/base64Captcha v1.3.6
github.com/olekukonko/tablewriter v0.0.5
github.com/qiniu/go-sdk/v7 v7.14.0
github.com/shirou/gopsutil/v3 v3.23.3
@ -32,14 +34,16 @@ require (
github.com/tencentyun/cos-go-sdk-v5 v0.7.45
github.com/ufilesdk-dev/ufile-gosdk v1.0.3
github.com/xuri/excelize/v2 v2.6.0
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel v1.25.0
golang.org/x/mod v0.9.0
golang.org/x/net v0.24.0
golang.org/x/tools v0.7.0
gopkg.in/yaml.v3 v3.0.1
)
require (
aead.dev/minisign v0.2.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
@ -50,7 +54,7 @@ require (
github.com/alibabacloud-go/tea-xml v1.1.2 // indirect
github.com/aliyun/credentials-go v1.1.2 // indirect
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clbanning/mxj v1.8.4 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
@ -67,7 +71,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
@ -98,6 +102,7 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/mozillazg/go-httpheader v0.2.1 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
@ -120,17 +125,17 @@ require (
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.25.0 // indirect
go.opentelemetry.io/otel/sdk v1.25.0 // indirect
go.opentelemetry.io/otel/trace v1.25.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/image v0.1.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/image v0.13.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
stathat.com/c/consistent v1.0.0 // indirect
)

View File

@ -33,7 +33,10 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@ -80,22 +83,24 @@ github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible h1:KXeJoM1wo9I/6xPTyt6qC
github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/aliyun/credentials-go v1.1.2 h1:qU1vwGIBb3UJ8BwunHDRFtAhS6jnQLnde/yk0+Ih2GY=
github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
github.com/apache/rocketmq-client-go/v2 v2.1.0 h1:3eABKfxc1WmS2lLTTbKMe1gZfZV6u1Sx9orFnOfABV0=
github.com/apache/rocketmq-client-go/v2 v2.1.0/go.mod h1:oEZKFDvS7sz/RWU0839+dQBupazyBV7WX5cP6nrio0Q=
github.com/apache/rocketmq-client-go/v2 v2.1.2 h1:yt73olKe5N6894Dbm+ojRf/JPiP0cxfDNNffKwhpJVg=
github.com/apache/rocketmq-client-go/v2 v2.1.2/go.mod h1:6I6vgxHR3hzrvn+6n/4mrhS+UTulzK/X9LB2Vk1U5gE=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw=
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/casbin/casbin/v2 v2.55.0 h1:RyU+OacnVzjxof1U3bmxHM7oCRdx9+gNnkclrvof/zI=
github.com/casbin/casbin/v2 v2.55.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@ -166,18 +171,18 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.6.4 h1:ScG3YcYMDEP/UrwNtwQPt2noySa5ZpoV7BxrwaeBaro=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.6.4/go.mod h1:oFFE9u1zHkxVXk7ZkNipXQR9JFyDZDiixZy243ywhfQ=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.6.4 h1:43517FF//GKgGpb4pxHl3NWLxW/inTAQ7rUFnfUIoYY=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.6.4/go.mod h1:9qNdKgqB+tHC9XczIoMzfSHmWkphQMXqxJXF6g9Icr4=
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.6.4 h1:PV0V2CPspwC+qgmqMC7qjCFkxH/SkfLwC0fg26ZTY54=
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.6.4/go.mod h1:Wnu7ASD+BWWlPn9NlSNOmCip7tHnYSXRSSjFJ5cCTEo=
github.com/gogf/gf/v2 v2.6.4 h1:w7HXdH9mcTsn/aE13CkaDbRArmAL1KS3FuQqDi6u74Y=
github.com/gogf/gf/v2 v2.6.4/go.mod h1:x2XONYcI4hRQ/4gMNbWHmZrNzSEIg20s2NULbzom5k0=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.7.0 h1:5Igvtz4gy5UMvH+Ut4kLIpwSzggV9ZgDVBsIiOctH5E=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.7.0/go.mod h1:0+flZ0clMKjtH1sTI7YD2KG4FPr8xz0L9h1WMd5M2Z8=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.7.0 h1:hJxshC0gZyFZaGo2HItXd5XMzIMbCRcgShr1ljMYwUc=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.7.0/go.mod h1:is3Q3ItZSPMZ1RBJ3xIcEasyGZnOg8eNeG9dubOx/zc=
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.7.0 h1:P75Jfq5rP8TUUTyobAooULJDDCaSOkgL14gnXudgY1E=
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.7.0/go.mod h1:hRnwcGAFG8c6+9rg//zbr0Ve3XZVzAuALfzfbz3xBBk=
github.com/gogf/gf/v2 v2.7.0 h1:CjxhbMiE7oqf6K8ZtGuKt3dQEwK4vL6LhiI+dI7tJGU=
github.com/gogf/gf/v2 v2.7.0/go.mod h1:Qu8nimKt9aupJQcdUL85tWF4Mfxocz97zUt8UC4abVI=
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f h1:7xfXR/BhG3JDqO1s45n65Oyx9t4E/UqDOXep6jXdLCM=
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f/go.mod h1:HnYoio6S7VaFJdryKcD/r9HgX+4QzYfr00XiXUo/xz0=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@ -232,6 +237,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -288,7 +294,6 @@ github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZ
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@ -350,8 +355,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
github.com/mojocn/base64Captcha v1.3.6 h1:gZEKu1nsKpttuIAQgWHO+4Mhhls8cAKyiV2Ew03H+Tw=
github.com/mojocn/base64Captcha v1.3.6/go.mod h1:i5CtHvm+oMbj1UzEPXaA8IH/xHFZ3DGY3Wh3dBpZ28E=
github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@ -374,6 +379,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
@ -436,7 +443,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
github.com/silenceper/wechat/v2 v2.1.4 h1:X+G9C/EiBET5AK0zhrflX3ESCP/yxhJUvoRoSXHm0js=
github.com/silenceper/wechat/v2 v2.1.4/go.mod h1:F0PKqImb15THnwoqRNrZO1z3vpwyWuiHr5zzfnjdECY=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
@ -446,7 +453,6 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.1.0 h1:MkTeG1DMwsrdH7QtLXy5W+fUxWq+vmb6cLmyJ7aRtF0=
github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
@ -466,7 +472,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.633 h1:Yj8s35IjbgaHp4Ic9BZLVGWdN2gXBMtwYi1JJ+qYbrc=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.633/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
@ -475,13 +482,11 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.633 h1:rtgRqgZ
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.633/go.mod h1:9q29WcGkZ7R0uQjoY10Tzb8A18C2cNggbq2ZC2HRXZE=
github.com/tencentyun/cos-go-sdk-v5 v0.7.45 h1:5/ZGOv846tP6+2X7w//8QjLgH2KcUK+HciFbfjWquFU=
github.com/tencentyun/cos-go-sdk-v5 v0.7.45/go.mod h1:DH9US8nB+AJXqwu/AMOrCFN1COv3dpytXuJWHgdg7kE=
github.com/tidwall/gjson v1.2.1/go.mod h1:c/nTNbUr0E0OrXEhq1pwa8iEgc2DOt4ZZqAt1HtCkPA=
github.com/tidwall/gjson v1.13.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo=
github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v0.0.0-20190325153808-1166b9ac2b65/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM=
@ -516,16 +521,16 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k=
go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg=
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA=
go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s=
go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo=
go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw=
go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM=
go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I=
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
@ -544,8 +549,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -557,11 +562,10 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.1.0 h1:r8Oj8ZA2Xy12/b5KZYj3tuv7NG/fBz3TwQVvpJ9l8Rk=
golang.org/x/image v0.1.0/go.mod h1:iyPr49SD/G/TBxYVB/9RRtGUT5eNbo2u4NamWeQcD5c=
golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg=
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -582,6 +586,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -623,8 +628,9 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -705,11 +711,12 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -717,7 +724,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -770,6 +778,7 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -865,6 +874,8 @@ gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaD
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -22,7 +22,7 @@ gfcli:
gen:
dao:
- 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"
group: "default" # 分组 使用hotgo代码生成功能时必须填
# tables: "" # 指定当前数据库中需要执行代码生成的数据表如果为空表示数据库的所有表都会生成
tablesEx: "hg_sys_addons_install" # 指定当前数据库中需要排除代码生成的数据表

View File

@ -36,6 +36,8 @@ var (
---------------------------------------------------------------------------------
工具
>> 释放casbin权限用于清理无效的权限设置 [go run main.go tools -m=casbin -a1=refresh]
>> 打印所有打包的资源文件列表 [go run main.go tools -m=gres -a1=dump]
>> 打印指定打包的资源文件内容 [go run main.go tools -m=gres -a1=content -a2=resource/template/home/index.html]
---------------------------------------------------------------------------------
升级更新
>> 修复菜单关系树 [go run main.go up -m=fix -a1=menuTree]

View File

@ -23,8 +23,8 @@ var (
// signalHandlerForOverall 关闭信号处理
func signalHandlerForOverall(sig os.Signal) {
serverCloseSignal <- struct{}{}
serverCloseEvent(gctx.GetInitCtx())
serverCloseSignal <- struct{}{}
}
// signalListen 信号监听

View File

@ -7,9 +7,11 @@ package cmd
import (
"context"
"fmt"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/gogf/gf/v2/os/gres"
"hotgo/internal/library/casbin"
)
@ -35,6 +37,8 @@ var (
switch method {
case "casbin":
err = handleCasbin(ctx, args)
case "gres":
err = handleGRes(ctx, args)
default:
err = gerror.Newf("tools method[%v] does not exist", method)
}
@ -66,3 +70,38 @@ func handleCasbin(ctx context.Context, args map[string]string) (err error) {
}
return
}
func handleGRes(ctx context.Context, args map[string]string) (err error) {
a1, ok := args["a1"]
if !ok {
err = gerror.New("gres args cannot be empty.")
return
}
switch a1 {
case "dump":
gres.Dump()
case "content":
path, ok := args["a2"]
if !ok {
err = gerror.New("缺少查看文件路径参数:`a2`")
return
}
if !gres.Contains(path) {
err = gerror.Newf("没有找到资源文件:%v", path)
return
}
content := string(gres.GetContent(path))
if len(content) == 0 {
err = gerror.Newf("没有找到资源文件内容,请确认传入`a2`参数是一个文件a2:%v", path)
return
}
fmt.Println("以下是资源文件内容:")
fmt.Println(content)
default:
err = gerror.Newf("handleGRes a1 is invalid, a1:%v", a1)
}
return
}

View File

@ -22,3 +22,10 @@ const (
DefaultPageSize = 1 // 默认列表分页加载页码
MaxSortIncr = 10 // 最大排序值增量
)
// TenantField 租户字段
const (
TenantId = "tenant_id" // 租户ID
MerchantId = "merchant_id" // 商户ID
UserId = "user_id" // 用户ID
)

View File

@ -0,0 +1,30 @@
// Package consts
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package consts
import (
"hotgo/internal/library/dict"
"hotgo/internal/model"
)
func init() {
dict.RegisterEnums("deptType", "部门类型选项", DeptTypeOptions)
}
const (
DeptTypeCompany = "company" // 公司
DeptTypeTenant = "tenant" // 租户
DeptTypeMerchant = "merchant" // 商户
DeptTypeUser = "user" // 用户
)
// DeptTypeOptions 部门类型选项
var DeptTypeOptions = []*model.Option{
dict.GenSuccessOption(DeptTypeCompany, "公司"),
dict.GenErrorOption(DeptTypeTenant, "租户"),
dict.GenInfoOption(DeptTypeMerchant, "商户"),
dict.GenWarningOption(DeptTypeUser, "用户"),
}

View File

@ -3,9 +3,13 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package consts
import (
"hotgo/internal/library/dict"
"hotgo/internal/model"
)
// 生成代码类型
const (
GenCodesTypeCurd = 10 // 增删改查列表
@ -16,7 +20,7 @@ const (
var GenCodesTypeNameMap = map[int]string{
GenCodesTypeCurd: "增删改查列表",
GenCodesTypeTree: "关系树列表(未实现)",
GenCodesTypeTree: "关系树列表",
GenCodesTypeQueue: "队列消费者(未实现)",
GenCodesTypeCron: "定时任务(未实现)",
}
@ -79,3 +83,14 @@ const (
GenCodesIndexPK = "PRI" // 主键索引
GenCodesIndexUNI = "UNI" // 唯一索引
)
const (
GenCodesTreeStyleTypeNormal = 1 // 普通树表格
GenCodesTreeStyleTypeOption = 2 // 选项式树表
)
// GenCodesTreeStyleTypeOptions 树表样式选项
var GenCodesTreeStyleTypeOptions = []*model.Option{
dict.GenSuccessOption(GenCodesTreeStyleTypeNormal, "普通树表格"),
dict.GenInfoOption(GenCodesTreeStyleTypeOption, "选项式树表"),
}

View File

@ -14,6 +14,7 @@ import (
func init() {
dict.RegisterEnums("payType", "支付方式", PayTypeOptions)
dict.RegisterEnums("payStatus", "支付状态", PayStatusOptions)
}
const (
@ -72,6 +73,12 @@ const (
PayStatusOk = 2 // 已支付
)
// PayStatusOptions 支付状态选项
var PayStatusOptions = []*model.Option{
dict.GenDefaultOption(PayStatusWait, "待支付"),
dict.GenSuccessOption(PayStatusOk, "已支付"),
}
// 退款状态
const (

View File

@ -7,5 +7,5 @@ package consts
// VersionApp HotGo版本
const (
VersionApp = "2.13.1"
VersionApp = "2.15.1"
)

View File

@ -54,12 +54,6 @@ func (c *cDept) List(ctx context.Context, req *dept.ListReq) (res *dept.ListRes,
return
}
// Status 更新部门状态
func (c *cDept) Status(ctx context.Context, req *dept.StatusReq) (res *dept.StatusRes, err error) {
err = service.AdminDept().Status(ctx, &req.DeptStatusInp)
return
}
// Option 获取部门选项树
func (c *cDept) Option(ctx context.Context, req *dept.OptionReq) (res *dept.OptionRes, err error) {
list, totalCount, err := service.AdminDept().Option(ctx, &req.DeptOptionInp)
@ -72,3 +66,10 @@ func (c *cDept) Option(ctx context.Context, req *dept.OptionReq) (res *dept.Opti
res.PageRes.Pack(req, totalCount)
return
}
// TreeOption 获取部门管理关系树选项
func (c *cDept) TreeOption(ctx context.Context, req *dept.TreeOptionReq) (res *dept.TreeOptionRes, err error) {
data, err := service.AdminDept().TreeOption(ctx)
res = (*dept.TreeOptionRes)(&data)
return
}

View File

@ -8,7 +8,6 @@ package admin
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/text/gstr"
"hotgo/api/admin/monitor"
@ -103,12 +102,10 @@ func (c *cMonitor) UserOnlineList(ctx context.Context, req *monitor.UserOnlineLi
return clients[i].FirstTime < clients[j].FirstTime
})
isDemo := g.Cfg().MustGet(ctx, "hotgo.isDemo", false).Bool()
_, perPage, offset := form.CalPage(req.Page, req.PerPage)
for k, v := range clients {
if k >= offset && i <= perPage {
if isDemo {
if simple.IsDemo(ctx) {
v.IP = consts.DemoTips
}
res.List = append(res.List, v)

View File

@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.12.10
// @AutoGenerate Version 2.13.1
package sys
import (
@ -19,7 +19,7 @@ var (
type cCurdDemo struct{}
// List 查看生成演示列表
// List 查看CURD列表列表
func (c *cCurdDemo) List(ctx context.Context, req *curddemo.ListReq) (res *curddemo.ListRes, err error) {
list, totalCount, err := service.SysCurdDemo().List(ctx, &req.CurdDemoListInp)
if err != nil {
@ -36,19 +36,19 @@ func (c *cCurdDemo) List(ctx context.Context, req *curddemo.ListReq) (res *curdd
return
}
// Export 导出生成演示列表
// Export 导出CURD列表列表
func (c *cCurdDemo) Export(ctx context.Context, req *curddemo.ExportReq) (res *curddemo.ExportRes, err error) {
err = service.SysCurdDemo().Export(ctx, &req.CurdDemoListInp)
return
}
// Edit 更新生成演示
// Edit 更新CURD列表
func (c *cCurdDemo) Edit(ctx context.Context, req *curddemo.EditReq) (res *curddemo.EditRes, err error) {
err = service.SysCurdDemo().Edit(ctx, &req.CurdDemoEditInp)
return
}
// MaxSort 获取生成演示最大排序
// MaxSort 获取CURD列表最大排序
func (c *cCurdDemo) MaxSort(ctx context.Context, req *curddemo.MaxSortReq) (res *curddemo.MaxSortRes, err error) {
data, err := service.SysCurdDemo().MaxSort(ctx, &req.CurdDemoMaxSortInp)
if err != nil {
@ -60,7 +60,7 @@ func (c *cCurdDemo) MaxSort(ctx context.Context, req *curddemo.MaxSortReq) (res
return
}
// View 获取指定生成演示信息
// View 获取指定CURD列表信息
func (c *cCurdDemo) View(ctx context.Context, req *curddemo.ViewReq) (res *curddemo.ViewRes, err error) {
data, err := service.SysCurdDemo().View(ctx, &req.CurdDemoViewInp)
if err != nil {
@ -72,19 +72,13 @@ func (c *cCurdDemo) View(ctx context.Context, req *curddemo.ViewReq) (res *curdd
return
}
// Delete 删除生成演示
// Delete 删除CURD列表
func (c *cCurdDemo) Delete(ctx context.Context, req *curddemo.DeleteReq) (res *curddemo.DeleteRes, err error) {
err = service.SysCurdDemo().Delete(ctx, &req.CurdDemoDeleteInp)
return
}
// Status 更新生成演示状态
func (c *cCurdDemo) Status(ctx context.Context, req *curddemo.StatusReq) (res *curddemo.StatusRes, err error) {
err = service.SysCurdDemo().Status(ctx, &req.CurdDemoStatusInp)
return
}
// Switch 更新生成演示开关状态
// Switch 更新CURD列表开关状态
func (c *cCurdDemo) Switch(ctx context.Context, req *curddemo.SwitchReq) (res *curddemo.SwitchRes, err error) {
err = service.SysCurdDemo().Switch(ctx, &req.CurdDemoSwitchInp)
return

Some files were not shown because too many files have changed in this diff Show More