diff --git a/README.md b/README.md
index bd68f71..3a755e1 100644
--- a/README.md
+++ b/README.md
@@ -68,8 +68,8 @@
15. 代码生成:支持自动化生成前后端代码。CURD关联表、树表、消息队列、定时任务一键生成等。
16. 插件应用:支持一键生成插件模板,每个插件之间开发隔离,拥有独立多应用入口、独立配置。完美支持多人协同开发、插件插拔不会对原系统产生影响等。
17. 服务监控:监视当前系统CPU、内存、磁盘、网络、堆栈等相关信息。
-18. 附件管理:文件图片上传,支持本地、阿里云oss、腾讯云cos、ucloud对象存储、七牛云对象存储等多种上传驱动,后台一键切换配置。
-19. TCP服务:基于gtcp的应用实例,支持长连接、断线重连、自动维护心跳、签名、服务登录、服务授权等。主要用于C/S服务器和服务进程之间的数据通讯。
+18. 附件管理:文件图片上传,支持本地、阿里云oss、腾讯云cos、ucloud对象存储、七牛云对象存储等多种上传驱动,后台一键切换配置,并集成了文件选择器。
+19. TCP服务:基于gtcp的服务应用,支持长连接、断线重连、服务认证、路由分发、RPC消息、拦截器和数据绑定等。简化和规范了服务器开发流程。
20. 消息队列:同时兼容 kafka、redis、rocketmq、磁盘队列,一键配置切换到场景适用的MQ。
21. 通知公告:采用websocket实时推送在线用户最新通知、公告、私信消息。
22. 地区编码:整合国内通用省市区编码,运用于项目于一身,支持动态省市区选项。
diff --git a/docs/guide-zh-CN/README.md b/docs/guide-zh-CN/README.md
index b9291e9..3c2721b 100644
--- a/docs/guide-zh-CN/README.md
+++ b/docs/guide-zh-CN/README.md
@@ -22,15 +22,16 @@
- [支付网关](sys-payment.md)
- [数据库](sys-db.md)
- [代码生成](sys-code.md)
-- 定时任务
+- [定时任务](sys-cron.md)
- [消息队列](sys-queue.md)
- [功能扩展库](sys-library.md)
-- 工具方法
+- [工具方法](sys-utility.md)
- RESTful Api
- Websocket服务器
-- TCP服务器
-- 单元测试
+- [TCP服务器](sys-tcp-server.md)
+- [单元测试](sys-test.md)
+
#### 插件模块开发
- [模块介绍及目录](addon-introduce-catalog.md)
@@ -38,16 +39,12 @@
- [模块辅助说明](addon-helper.md)
-#### 实战开发
-- 服务端
-- web前端
-
-
### 前端开发
- [表单组件](web-form.md)
- Websocket客户端
- 工具库
- [独立部署](web-deploy.md)
+
#### 附录
- [网址收录](append-website.md)
\ No newline at end of file
diff --git a/docs/guide-zh-CN/images/sys-middleware-com-response.png b/docs/guide-zh-CN/images/sys-middleware-com-response.png
index 86e86d0..26d46a5 100644
Binary files a/docs/guide-zh-CN/images/sys-middleware-com-response.png and b/docs/guide-zh-CN/images/sys-middleware-com-response.png differ
diff --git a/docs/guide-zh-CN/start-update-log.md b/docs/guide-zh-CN/start-update-log.md
index 67888b0..b865c7c 100644
--- a/docs/guide-zh-CN/start-update-log.md
+++ b/docs/guide-zh-CN/start-update-log.md
@@ -12,6 +12,19 @@
> 如果升级(覆盖)代码后打开会出现 sql 报错, 请检查更新的数据库格式或自行调整
+### v2.8.4
+updated 2023.07.22
+
+- 增加:增加输入预处理中间件
+- 增加:增加文件选择器
+- 增加:增加在线服务监控,服务许可证管理
+- 增加:TCP服务器增加RPC路由消息注册、路由分发、拦截器注册,更方便的进行应用开发
+- 优化:gf版本升级到v2.5.0
+- 优化:优化CURD代码生成,简化控制器代码逻辑,升级列表数据查询方式
+- 修复:修复角色菜单子权限取消导致父级权限失效问题
+- 修复:修复上传驱动路径错误
+- 修复:修复CURD代码生成时间类型字段默认值获取异常
+
### v2.7.6
updated 2023.06.19
@@ -19,7 +32,6 @@ updated 2023.06.19
- 修复:部门管理查询空指针问题
- 优化:附件md5生成方式调整(与更新前已上传的文件md5不兼容,如果业务有影响请注意调整)
-
### v2.7.3
updated 2023.05.14
diff --git a/docs/guide-zh-CN/sys-code.md b/docs/guide-zh-CN/sys-code.md
index 5d9e9b6..c233d2a 100644
--- a/docs/guide-zh-CN/sys-code.md
+++ b/docs/guide-zh-CN/sys-code.md
@@ -5,9 +5,11 @@
- 使用条件
- 生成配置
- 一个生成增删改查列表例子
-- 内置gf-cli
- 多数据库生成配置
- 自定义生成模板
+- 内置gf-cli
+- 指定gf-cli版本
+- 指定数据库驱动类型
> 在HotGo中可以通过后台开发工具快速的一键生成CRUD,自动生成Api、控制器、业务逻辑、Web页面、表单组件、菜单权限等。
@@ -263,13 +265,6 @@ INSERT INTO `hg_test_table` (`id`, `category_id`, `title`, `description`, `conte
-### 内置gf-cli
-
-> 由于gf版本更新较常出现向下不兼容的情况,所以我们为了保证生成代码的依赖稳定性,我们将gf-cli工具内置到了系统中并做了一些在线执行的调整。
-
-- 后续我们也将开放在线运行`gf gen dao`、`gf gen service`功能。在做插件开发时也会支持到在线生成插件下的service接口,这将会使得插件开发更加方便
-
-
## 多数据库生成配置
#### 假设我们要增加一个库名为`hotgo2`、分组为`default2`的数据库,并要为其生成代码
@@ -339,3 +334,53 @@ hggen:
- 如果你在实际的开发过程中默认模板需要调整的地方较多时,HotGo允许你新建新的模板分组来满足你的需求。新的模板可根据现有模板基础拷贝一份出来做改造,默认模板目录:[server/resource/generate/default](../../server/resource/generate/default)
+
+
+### 内置gf-cli
+
+> 为了确保生成代码的依赖稳定性,在面对`gf`版本更新可能导致向下不兼容情况时,HotGo将`gf-cli`工具内置到系统中并进行在线执行调整,从而提供更可靠和一致的生成代码功能。
+
+- 后续我们也将开放在线运行`gf gen ...`功能。在做插件开发时也会支持到在线生成插件下的service接口,这将会使得插件开发更加方便
+
+
+
+### 指定gf-cli版本
+
+> HotGo多数情况下会和最新版本的gf-cli保持同步,如果更新不及时或你不想使用最新版本的gf-cli来生成代码,可以找到自己想要的版本进行替换即可。
+
+- 下面大致做一些替换步骤说明:
+
+1. 打开https://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
+```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`
diff --git a/docs/guide-zh-CN/sys-cron.md b/docs/guide-zh-CN/sys-cron.md
new file mode 100644
index 0000000..10835d7
--- /dev/null
+++ b/docs/guide-zh-CN/sys-cron.md
@@ -0,0 +1,71 @@
+## 定时任务
+
+目录
+
+- 实现接口
+- 一个例子
+- 更多
+
+> 在实际的项目开发中,定时任务几乎成为不可或缺的一部分。HotGo为定时任务提供一个方便的后台操作界面,让您能够轻松地进行在线启停、修改和立即执行等操作。这样的设计可以极大地改善您在使用定时任务过程中的体验,让整个过程更加顺畅、高效。
+
+
+### 实现接口
+- 为了提供高度的扩展性,定时任务在设计上采用了接口化的思路。只需要实现以下接口,您就可以在任何地方注册和使用定时任务功能,从而实现更大的灵活性和可扩展性。
+
+```go
+// Cron 定时任务接口
+type Cron interface {
+ // GetName 获取任务名称
+ GetName() string
+ // Execute 执行一次任务
+ Execute(ctx context.Context)
+}
+```
+
+
+### 一个例子
+
+定时任务的文件结构可以根据具体需要进行调整,以下是一个常见的参考结构:
+
+- 文件路径:server/internal/crons/test.go
+
+```go
+package crons
+
+import (
+ "context"
+ "hotgo/internal/library/cron"
+ "time"
+)
+
+func init() {
+ cron.Register(Test)
+}
+
+// Test 测试任务(无参数)
+var Test = &cTest{name: "test"}
+
+type cTest struct {
+ name string
+}
+
+func (c *cTest) GetName() string {
+ return c.name
+}
+
+// Execute 执行任务
+func (c *cTest) Execute(ctx context.Context) {
+ cron.Logger().Infof(ctx, "cron test Execute:%v", time.Now())
+}
+
+
+```
+
+继续在后台系统设置-定时任务-添加任务,填写的任务名称需要和上面的名称保持一致,再进行简单的策略配置以后,一个后台可控的定时任务就添加好了!
+
+
+### 更多
+
+定时任务源码路径:server/internal/library/cron/cron.go
+
+更多文档请参考:https://goframe.org/pages/viewpage.action?pageId=1114187
\ No newline at end of file
diff --git a/docs/guide-zh-CN/sys-middleware.md b/docs/guide-zh-CN/sys-middleware.md
index 01deb94..53e49b7 100644
--- a/docs/guide-zh-CN/sys-middleware.md
+++ b/docs/guide-zh-CN/sys-middleware.md
@@ -33,6 +33,9 @@ func main() {
// 演示系統操作限制,当开启演示模式时,所有POST请求将被拒绝
service.Middleware().DemoLimit()
+
+ // 请求输入预处理,api使用gf规范路由并且XxxReq结构体实现了validate.Filter接口即可隐式预处理
+ service.Middleware().PreFilter()
// HTTP响应预处理,在业务处理完成后,对响应结果进行格式化和错误过滤,将处理后的数据发送给请求方
service.Middleware().ResponseHandler()
@@ -143,7 +146,6 @@ func main() {
2. 在`server/internal/logic/middleware/response.go`中根据请求的独有特征进行单独的处理,兼容后续http处理。
-
#### 重写响应错误提示
- 在实际开发中,我们可能想要隐藏一些敏感错误,返回给客户端友好的错误提示,但开发者同时又想需要看到真实的敏感错误。对此hotgo已经进行了过滤处理,下面是一个简单的例子:
diff --git a/docs/guide-zh-CN/sys-tcp-server.md b/docs/guide-zh-CN/sys-tcp-server.md
new file mode 100644
index 0000000..8ef612f
--- /dev/null
+++ b/docs/guide-zh-CN/sys-tcp-server.md
@@ -0,0 +1,271 @@
+## TCP服务器
+
+目录
+
+- 配置文件
+- 一个基本的消息收发例子
+- 注册路由
+- 拦截器
+- 服务认证
+- 更多
+
+> HotGo基于GF框架的TCP服务器组件,提供了一个简单而灵活的方式快速搭建基于TCP的服务应用。集成了许多常用功能,如长连接、服务认证、路由分发、RPC消息、拦截器和数据绑定等,大大简化和规范了服务器开发流程。
+
+### 配置文件
+- 配置文件:server/manifest/config/config.yaml
+
+```yaml
+tcp:
+ # 服务器
+ server:
+ address: ":8099"
+ # 客户端
+ client:
+ # 定时任务
+ cron:
+ group: "cron" # 分组名称
+ name: "cron1" # 客户端名称
+ address: "127.0.0.1:8099" # 服务器地址
+ appId: "1002" # 应用名称
+ secretKey: "hotgo" # 密钥
+ # 系统授权
+ auth:
+ group: "auth" # 分组名称
+ name: "auth1" # 客户端名称
+ address: "127.0.0.1:8099" # 服务器地址
+ appId: "mengshuai" # 应用名称
+ secretKey: "123456" # 密钥
+
+```
+- 可以看到,除了服务器配置外,还有两个客户端配置`cron` 和`auth`
+- `cron`是HotGo内置的定时任务服务,和http服务通过RPC通讯以实现和后台交互,使其可以独立、集群部署。
+- `auth`可以为第三方平台提供授权服务。如果你需要他,可以将它部署在第三方程序中,在重要的位置进行授权验证。
+
+### 一个基本的消息收发测试用例
+
+- 文件路径:server/internal/library/network/tcp/tcp_example_test.go
+
+```go
+package tcp_test
+
+import (
+ "context"
+ "fmt"
+ "github.com/gogf/gf/v2/os/gctx"
+ "github.com/gogf/gf/v2/test/gtest"
+ "hotgo/internal/library/network/tcp"
+ "testing"
+ "time"
+)
+
+var T *testing.T // 声明一个全局的 *testing.T 变量
+
+type TestMsgReq struct {
+ Name string `json:"name"`
+}
+
+type TestMsgRes struct {
+ tcp.ServerRes
+}
+
+type TestRPCMsgReq struct {
+ Name string `json:"name"`
+}
+
+type TestRPCMsgRes struct {
+ tcp.ServerRes
+}
+
+func onTestMsg(ctx context.Context, req *TestMsgReq) {
+ fmt.Printf("服务器收到消息 ==> onTestMsg:%+v\n", req)
+ conn := tcp.ConnFromCtx(ctx)
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNE(conn, nil)
+ })
+
+ res := new(TestMsgRes)
+ res.Message = fmt.Sprintf("你的名字:%v", req.Name)
+ conn.Send(ctx, res)
+}
+
+func onResponseTestMsg(ctx context.Context, req *TestMsgRes) {
+ fmt.Printf("客户端收到响应消息 ==> TestMsgRes:%+v\n", req)
+ err := req.GetError()
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+}
+
+func onTestRPCMsg(ctx context.Context, req *TestRPCMsgReq) (res *TestRPCMsgRes, err error) {
+ fmt.Printf("服务器收到消息 ==> onTestRPCMsg:%+v\n", req)
+ res = new(TestRPCMsgRes)
+ res.Message = fmt.Sprintf("你的名字:%v", req.Name)
+ return
+}
+
+func startTCPServer() {
+ serv := tcp.NewServer(&tcp.ServerConfig{
+ Name: "hotgo",
+ Addr: ":8002",
+ })
+
+ // 注册路由
+ serv.RegisterRouter(
+ onTestMsg,
+ )
+
+ // 注册RPC路由
+ serv.RegisterRPCRouter(
+ onTestRPCMsg,
+ )
+
+ // 服务监听
+ err := serv.Listen()
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+}
+
+// 一个基本的消息收发
+func TestSendMsg(t *testing.T) {
+ T = t
+ go startTCPServer()
+
+ ctx := gctx.New()
+ client := tcp.NewClient(&tcp.ClientConfig{
+ Addr: "127.0.0.1:8002",
+ })
+
+ // 注册路由
+ client.RegisterRouter(
+ onResponseTestMsg,
+ )
+
+ go func() {
+ err := client.Start()
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+ }()
+
+ // 确保服务都启动完成
+ time.Sleep(time.Second * 1)
+
+ // 拿到客户端的连接
+ conn := client.Conn()
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNE(conn, nil)
+ })
+
+ // 向服务器发送tcp消息,不会阻塞程序执行
+ err := conn.Send(ctx, &TestMsgReq{Name: "Tom"})
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+
+ // 向服务器发送rpc消息,会等待服务器响应结果,直到拿到结果或响应超时才会继续
+ var res TestRPCMsgRes
+ if err = conn.RequestScan(ctx, &TestRPCMsgReq{Name: "Tony"}, &res); err != nil {
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+ }
+
+ fmt.Printf("客户端收到RPC消息响应 ==> TestRPCMsgRes:%+v\n", res)
+ time.Sleep(time.Second * 1)
+}
+
+```
+
+
+### 注册路由
+
+- 从上面的例子可以看到,不管是普通TCP消息和RPC消息的请求/响应结构体都采用类似GF框架的规范路由的结构,请求`XxxRes`/响应`XxxRes`的格式,是不是很亲切?
+
+
+### 拦截器
+
+- 不管是服务端还是客户端,在初始化时都可以注册多个拦截器来满足更多场景的服务开发,下面是一个使用例子:
+
+```go
+package main
+
+import (
+ "context"
+ "github.com/gogf/gf/v2/frame/g"
+ "hotgo/internal/library/network/tcp"
+)
+
+func main() {
+ serv = tcp.NewServer(&tcp.ServerConfig{
+ Name: "hotgo",
+ Addr: ":8002",
+ })
+
+ // 注册拦截器
+ // 执行顺序是从前到后,即Interceptor -> Interceptor2 -> Interceptor3。如果中间有任意一个抛出错误,则会中断后续处理
+ serv.RegisterInterceptor(Interceptor, Interceptor2, Interceptor3)
+
+ // 服务监听
+ if err := serv.Listen(); err != nil {
+ if !serv.IsClose() {
+ g.Log().Warningf(ctx, "TCPServer Listen err:%v", err)
+ }
+ }
+}
+
+func Interceptor(ctx context.Context, msg *tcp.Message) (err error) {
+ // 可以在拦截器中通过上下文拿到连接
+ conn := tcp.ConnFromCtx(ctx)
+
+ // 拿到原始请求消息
+ g.Dump(msg)
+
+ // 如果想要中断后续处理只需返回一个错误即可,但注意两种情况
+ // tcp消息:如果你还想对该消息进行回复应在拦截器中进行处理,例如:conn.Send(ctx, 回复消息内容)
+ // rpc消息:返回一个错误后系统会将错误自动回复到rpc响应中,无需单独处理
+ return
+}
+
+func Interceptor2(ctx context.Context, msg *tcp.Message) (err error) {
+ // ...
+ return
+}
+
+func Interceptor3(ctx context.Context, msg *tcp.Message) (err error) {
+ // ...
+ return
+}
+
+```
+
+
+### 服务认证
+
+- 一般情况下,建议客户端连接到服务器时都通过`授权许可证`的方式进行登录认证,当初始化客户端配置认证数据时,连接成功后会自动进行登录认证。
+
+```go
+ // 创建客户端配置
+ clientConfig := &tcp.ClientConfig{
+ Addr: "127.0.0.1:8002",
+ AutoReconnect: true,
+ // 认证数据
+ // 认证数据可以在后台-系统监控-在线服务-许可证列表中添加,同一个授权支持多个服务使用,但多个服务不能使用相同的名称进行连接
+ Auth: &tcp.AuthMeta{
+ Name: "服务名称",
+ Group: "服务分组",
+ AppId: "APPID",
+ SecretKey: "SecretKey",
+ },
+ }
+
+ // 初始化客户端
+ client = tcp.NewClient(clientConfig)
+```
+
+
+### 更多
+
+TCP服务器源码路径:server/internal/library/network/tcp
+
+更多文档请参考:https://goframe.org/pages/viewpage.action?pageId=1114625
diff --git a/docs/guide-zh-CN/sys-test.md b/docs/guide-zh-CN/sys-test.md
new file mode 100644
index 0000000..0e19710
--- /dev/null
+++ b/docs/guide-zh-CN/sys-test.md
@@ -0,0 +1,3 @@
+## 单元测试
+
+请参考:https://goframe.org/pages/viewpage.action?pageId=1114153
\ No newline at end of file
diff --git a/docs/guide-zh-CN/sys-utility.md b/docs/guide-zh-CN/sys-utility.md
new file mode 100644
index 0000000..ee5ef2e
--- /dev/null
+++ b/docs/guide-zh-CN/sys-utility.md
@@ -0,0 +1,20 @@
+## 工具方法
+
+HotGo还提供一些系统中常用的工具库方法,在这里简单说明:
+
+```
+/server
+├── utility
+│ ├── charset # 字符串处理
+│ ├── convert # 数据类型转换
+│ ├── encrypt # 数据加密/解密
+│ ├── excel # 电子表格导出/导入
+│ ├── file # 文件/目录处理
+│ ├── format # 数据格式化
+│ ├── simple # 一些简捷函数
+│ ├── tree # 树形结构
+│ ├── url # URL处理
+│ ├── useragent # 请求头代理处理
+└── └── validate # 数据验证
+```
+
diff --git a/docs/guide-zh-CN/web-form.md b/docs/guide-zh-CN/web-form.md
index 243ba1d..d23b812 100644
--- a/docs/guide-zh-CN/web-form.md
+++ b/docs/guide-zh-CN/web-form.md
@@ -20,6 +20,7 @@
- 多图上传 UploadImage
- 单文件上传 UploadFile
- 多文件上传 UploadFile
+- 文件选择器 FileChooser
- 开关 Switch
- 评分 Rate
- 省市区选择器 CitySelector
@@ -765,6 +766,35 @@ const value = ref(null);
```
+### 文件选择器 FileChooser
+- 基础用法
+```vue
+
+
+
+
+
+```
+
+- 指定fileType,支持多种选择器类型,默认情况是全部都可以选择
+```ts
+type FileType = 'image' | 'doc' | 'audio' | 'video' | 'zip' | 'other' | 'default';
+```
+
+- 图片选择器
+```vue
+
+```
+
+- 多选支持,指定`maxNumber`多选数量
+```vue
+
+```
+
### 开关 Switch
```vue
diff --git a/server/Makefile b/server/Makefile
index dc2fa85..5765cb1 100644
--- a/server/Makefile
+++ b/server/Makefile
@@ -12,63 +12,52 @@ build:
@cd ../web && yarn build && \cp -rf ./dist/* ../server$(ADMIN_RESOURCE_PATH)
@echo "y" | gf build
-
# 通过热编译启动所有服务
.PHONY: all
all:
gf run main.go --args "all"
-
.PHONY: http
http:
gf run main.go --args "http"
-
.PHONY: queue
queue:
gf run main.go --args "queue"
-
.PHONY: cron
cron:
gf run main.go --args "cron"
-
.PHONY: auth
auth:
gf run main.go --args "auth"
-
# 启动web服务
.PHONY: web
web:
@cd ../web && yarn dev
-
# 刷新casbin权限
.PHONY: refresh
refresh:
@go run main.go tools -m=casbin -a1=refresh
-
# 清理casbin权限
.PHONY: clear
clear:
@go run main.go tools -m=casbin -a1=clear
-
# 运行代码质量分析工具
# https://github.com/ywanbing/golangci
-.PHONY: ci
-ci:
+.PHONY: lint
+lint:
golangci-lint run
-
.PHONY: killmain
killmain:
@kill -9 $(ps -ef|grep main|grep -v grep|awk '{print $2}')
-
# Install/Update to the latest CLI tool.
.PHONY: cli
cli:
@@ -78,7 +67,6 @@ cli:
./gf install -y && \
rm ./gf
-
# Check and install CLI tool.
.PHONY: cli.install
cli.install:
@@ -88,19 +76,16 @@ cli.install:
make cli; \
fi;
-
# Generate Go files for DAO/DO/Entity.
.PHONY: dao
dao: cli.install
@gf gen dao
-
# Generate Go files for Service.
.PHONY: service
service: cli.install
@gf gen service
-
# Build image, deploy image and yaml to current kubectl environment and make port forward to local machine.
.PHONY: start
start:
@@ -109,27 +94,19 @@ start:
make deploy; \
make port;
-
# Build docker image and commit to the repository.
# example: make image tag=v0.0.1
.PHONY: image
image:
@echo "y" | gf docker main.go -p -tn hotgo:$(tag)
-
# Deploy image and yaml to current kubectl environment.
.PHONY: deploy
deploy:
$(eval _TAG = $(if ${TAG}, ${TAG}, develop))
-
@set -e; \
mkdir -p $(ROOT_DIR)/temp/kustomize;\
cd $(ROOT_DIR)/manifest/deploy/kustomize/overlays/${_TAG};\
kustomize build > $(ROOT_DIR)/temp/kustomize.yaml;\
kubectl apply -f $(ROOT_DIR)/temp/kustomize.yaml; \
kubectl patch -n $(NAMESPACE) deployment/$(DEPLOY_NAME) -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"$(shell date +%s)\"}}}}}";
-
-
-.PHONY: push
-push:
- @cd $(ROOT_DIR) && cd .. && ./push.sh
diff --git a/server/addons/hgexample/api/admin/config/config.go b/server/addons/hgexample/api/admin/config/config.go
index 690a335..83b431f 100644
--- a/server/addons/hgexample/api/admin/config/config.go
+++ b/server/addons/hgexample/api/admin/config/config.go
@@ -15,6 +15,7 @@ type GetReq struct {
g.Meta `path:"/config/get" method:"get" tags:"配置" summary:"获取指定分组的配置"`
sysin.GetConfigInp
}
+
type GetRes struct {
*sysin.GetConfigModel
}
@@ -24,5 +25,6 @@ type UpdateReq struct {
g.Meta `path:"/config/update" method:"post" tags:"配置" summary:"获取指定分组的配置"`
sysin.UpdateConfigInp
}
+
type UpdateRes struct {
}
diff --git a/server/addons/hgexample/api/admin/index/index.go b/server/addons/hgexample/api/admin/index/index.go
index f8aaf38..764eaa8 100644
--- a/server/addons/hgexample/api/admin/index/index.go
+++ b/server/addons/hgexample/api/admin/index/index.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package index
import (
diff --git a/server/addons/hgexample/api/admin/table/table.go b/server/addons/hgexample/api/admin/table/table.go
index c142f42..32f8b85 100644
--- a/server/addons/hgexample/api/admin/table/table.go
+++ b/server/addons/hgexample/api/admin/table/table.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package table
import (
@@ -36,6 +35,7 @@ type ViewReq struct {
g.Meta `path:"/table/view" method:"get" tags:"表格" summary:"获取指定信息"`
sysin.TableViewInp
}
+
type ViewRes struct {
*sysin.TableViewModel
}
@@ -45,6 +45,7 @@ type EditReq struct {
g.Meta `path:"/table/edit" method:"post" tags:"表格" summary:"修改/新增表格"`
sysin.TableEditInp
}
+
type EditRes struct{}
// DeleteReq 删除
@@ -52,12 +53,15 @@ type DeleteReq struct {
g.Meta `path:"/table/delete" method:"post" tags:"表格" summary:"删除表格"`
sysin.TableDeleteInp
}
+
type DeleteRes struct{}
// MaxSortReq 最大排序
type MaxSortReq struct {
g.Meta `path:"/table/maxSort" method:"get" tags:"表格" summary:"表格最大排序"`
+ sysin.TableMaxSortInp
}
+
type MaxSortRes struct {
*sysin.TableMaxSortModel
}
@@ -67,6 +71,7 @@ type StatusReq struct {
g.Meta `path:"/table/status" method:"post" tags:"表格" summary:"更新表格状态"`
sysin.TableStatusInp
}
+
type StatusRes struct{}
// SwitchReq 更新开关状态
@@ -74,4 +79,5 @@ type SwitchReq struct {
g.Meta `path:"/table/switch" method:"post" tags:"表格" summary:"更新表格状态"`
sysin.TableSwitchInp
}
+
type SwitchRes struct{}
diff --git a/server/addons/hgexample/api/api/index/index.go b/server/addons/hgexample/api/api/index/index.go
index f8aaf38..764eaa8 100644
--- a/server/addons/hgexample/api/api/index/index.go
+++ b/server/addons/hgexample/api/api/index/index.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package index
import (
diff --git a/server/addons/hgexample/api/home/index/index.go b/server/addons/hgexample/api/home/index/index.go
index 8eb20c0..3a876ed 100644
--- a/server/addons/hgexample/api/home/index/index.go
+++ b/server/addons/hgexample/api/home/index/index.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package index
import (
diff --git a/server/addons/hgexample/api/websocket/index/index.go b/server/addons/hgexample/api/websocket/index/index.go
index f8aaf38..764eaa8 100644
--- a/server/addons/hgexample/api/websocket/index/index.go
+++ b/server/addons/hgexample/api/websocket/index/index.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package index
import (
diff --git a/server/addons/hgexample/controller/admin/sys/config.go b/server/addons/hgexample/controller/admin/sys/config.go
index 0d91c50..ef40a69 100644
--- a/server/addons/hgexample/controller/admin/sys/config.go
+++ b/server/addons/hgexample/controller/admin/sys/config.go
@@ -7,11 +7,8 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
- "hotgo/addons/hgexample/model/input/sysin"
+ "hotgo/addons/hgexample/api/admin/config"
"hotgo/addons/hgexample/service"
- "hotgo/api/admin/config"
- isysin "hotgo/internal/model/input/sysin"
)
var (
@@ -22,25 +19,15 @@ type cConfig struct{}
// GetConfig 获取指定分组的配置
func (c *cConfig) GetConfig(ctx context.Context, req *config.GetReq) (res *config.GetRes, err error) {
- var in sysin.GetConfigInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- data, err := service.SysConfig().GetConfigByGroup(ctx, in)
+ data, err := service.SysConfig().GetConfigByGroup(ctx, &req.GetConfigInp)
res = new(config.GetRes)
- res.GetConfigModel = (*isysin.GetConfigModel)(data)
+ res.GetConfigModel = data
return
}
// UpdateConfig 更新指定分组的配置
func (c *cConfig) UpdateConfig(ctx context.Context, req *config.UpdateReq) (res *config.UpdateRes, err error) {
- var in sysin.UpdateConfigInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysConfig().UpdateConfigByGroup(ctx, in)
+ err = service.SysConfig().UpdateConfigByGroup(ctx, &req.UpdateConfigInp)
return
}
diff --git a/server/addons/hgexample/controller/admin/sys/index.go b/server/addons/hgexample/controller/admin/sys/index.go
index 502e990..b378b1d 100644
--- a/server/addons/hgexample/controller/admin/sys/index.go
+++ b/server/addons/hgexample/controller/admin/sys/index.go
@@ -3,16 +3,12 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/hgexample/api/admin/index"
- "hotgo/addons/hgexample/model/input/sysin"
"hotgo/addons/hgexample/service"
- "hotgo/utility/validate"
)
var (
@@ -23,16 +19,7 @@ type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
- var in sysin.IndexTestInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return nil, err
- }
-
- data, err := service.SysIndex().Test(ctx, in)
+ data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
diff --git a/server/addons/hgexample/controller/admin/sys/table.go b/server/addons/hgexample/controller/admin/sys/table.go
index 50d9fb1..03188cf 100644
--- a/server/addons/hgexample/controller/admin/sys/table.go
+++ b/server/addons/hgexample/controller/admin/sys/table.go
@@ -3,17 +3,12 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/hgexample/api/admin/table"
- "hotgo/addons/hgexample/model/input/sysin"
"hotgo/addons/hgexample/service"
- "hotgo/internal/model/input/form"
- "hotgo/utility/validate"
)
var (
@@ -24,57 +19,32 @@ type cTable struct{}
// List 查看列表
func (c *cTable) List(ctx context.Context, req *table.ListReq) (res *table.ListRes, err error) {
- var in sysin.TableListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysTable().List(ctx, in)
+ list, totalCount, err := service.SysTable().List(ctx, &req.TableListInp)
if err != nil {
return
}
res = new(table.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Export 导出列表
func (c *cTable) Export(ctx context.Context, req *table.ExportReq) (res *table.ExportRes, err error) {
- var in sysin.TableListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysTable().Export(ctx, in)
+ err = service.SysTable().Export(ctx, &req.TableListInp)
return
}
// Edit 更新
func (c *cTable) Edit(ctx context.Context, req *table.EditReq) (res *table.EditRes, err error) {
- var in sysin.TableEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysTable().Edit(ctx, in)
+ err = service.SysTable().Edit(ctx, &req.TableEditInp)
return
}
// MaxSort 最大排序
func (c *cTable) MaxSort(ctx context.Context, req *table.MaxSortReq) (res *table.MaxSortRes, err error) {
- data, err := service.SysTable().MaxSort(ctx, sysin.TableMaxSortInp{})
+ data, err := service.SysTable().MaxSort(ctx, &req.TableMaxSortInp)
if err != nil {
return
}
@@ -86,12 +56,7 @@ func (c *cTable) MaxSort(ctx context.Context, req *table.MaxSortReq) (res *table
// View 获取指定信息
func (c *cTable) View(ctx context.Context, req *table.ViewReq) (res *table.ViewRes, err error) {
- var in sysin.TableViewInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- data, err := service.SysTable().View(ctx, in)
+ data, err := service.SysTable().View(ctx, &req.TableViewInp)
if err != nil {
return
}
@@ -103,33 +68,18 @@ func (c *cTable) View(ctx context.Context, req *table.ViewReq) (res *table.ViewR
// Delete 删除
func (c *cTable) Delete(ctx context.Context, req *table.DeleteReq) (res *table.DeleteRes, err error) {
- var in sysin.TableDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysTable().Delete(ctx, in)
+ err = service.SysTable().Delete(ctx, &req.TableDeleteInp)
return
}
// Status 更新状态
func (c *cTable) Status(ctx context.Context, req *table.StatusReq) (res *table.StatusRes, err error) {
- var in sysin.TableStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysTable().Status(ctx, in)
+ err = service.SysTable().Status(ctx, &req.TableStatusInp)
return
}
// Switch 更新开关状态
func (c *cTable) Switch(ctx context.Context, req *table.SwitchReq) (res *table.SwitchRes, err error) {
- var in sysin.TableSwitchInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysTable().Switch(ctx, in)
+ err = service.SysTable().Switch(ctx, &req.TableSwitchInp)
return
}
diff --git a/server/addons/hgexample/controller/api/index.go b/server/addons/hgexample/controller/api/index.go
index f36b8c8..c604f1d 100644
--- a/server/addons/hgexample/controller/api/index.go
+++ b/server/addons/hgexample/controller/api/index.go
@@ -3,16 +3,12 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package api
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/hgexample/api/api/index"
- "hotgo/addons/hgexample/model/input/sysin"
"hotgo/addons/hgexample/service"
- "hotgo/utility/validate"
)
var (
@@ -23,16 +19,7 @@ type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
- var in sysin.IndexTestInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return nil, err
- }
-
- data, err := service.SysIndex().Test(ctx, in)
+ data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
diff --git a/server/addons/hgexample/controller/home/index.go b/server/addons/hgexample/controller/home/index.go
index 3dd7e47..668fc74 100644
--- a/server/addons/hgexample/controller/home/index.go
+++ b/server/addons/hgexample/controller/home/index.go
@@ -8,13 +8,10 @@ package home
import (
"context"
"github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/hgexample/api/home/index"
- "hotgo/addons/hgexample/model/input/sysin"
"hotgo/addons/hgexample/service"
"hotgo/internal/model"
isc "hotgo/internal/service"
- "hotgo/utility/validate"
)
// Index 基础
@@ -23,16 +20,7 @@ var Index = cIndex{}
type cIndex struct{}
func (a *cIndex) Index(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
- var in sysin.IndexTestInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return nil, err
- }
-
- data, err := service.SysIndex().Test(ctx, in)
+ data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
diff --git a/server/addons/hgexample/controller/websocket/index.go b/server/addons/hgexample/controller/websocket/index.go
index a0425be..37b9bbf 100644
--- a/server/addons/hgexample/controller/websocket/index.go
+++ b/server/addons/hgexample/controller/websocket/index.go
@@ -3,16 +3,12 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package websocket
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/hgexample/api/websocket/index"
- "hotgo/addons/hgexample/model/input/sysin"
"hotgo/addons/hgexample/service"
- "hotgo/utility/validate"
)
var (
@@ -23,16 +19,7 @@ type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
- var in sysin.IndexTestInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return nil, err
- }
-
- data, err := service.SysIndex().Test(ctx, in)
+ data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
diff --git a/server/addons/hgexample/crons/crons.go b/server/addons/hgexample/crons/crons.go
index cbcbe05..e20bf6c 100644
--- a/server/addons/hgexample/crons/crons.go
+++ b/server/addons/hgexample/crons/crons.go
@@ -1,3 +1,8 @@
+// Package crons
+// @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 crons
// 定时任务.
diff --git a/server/addons/hgexample/logic/sys/config.go b/server/addons/hgexample/logic/sys/config.go
index 378af85..73620b2 100644
--- a/server/addons/hgexample/logic/sys/config.go
+++ b/server/addons/hgexample/logic/sys/config.go
@@ -1,3 +1,8 @@
+// Package sys
+// @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 sys
import (
@@ -25,7 +30,7 @@ func (s *sSysConfig) GetBasic(ctx context.Context) (conf *model.BasicConfig, err
var in sysin.GetConfigInp
in.GetAddonsConfigInp.AddonName = global.GetSkeleton().Name
in.GetAddonsConfigInp.Group = "basic"
- models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, in.GetAddonsConfigInp)
+ models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, &in.GetAddonsConfigInp)
if err != nil {
return
}
@@ -35,9 +40,9 @@ func (s *sSysConfig) GetBasic(ctx context.Context) (conf *model.BasicConfig, err
}
// GetConfigByGroup 获取指定分组配置
-func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error) {
+func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in *sysin.GetConfigInp) (res *sysin.GetConfigModel, err error) {
in.GetAddonsConfigInp.AddonName = global.GetSkeleton().Name
- models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, in.GetAddonsConfigInp)
+ models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, &in.GetAddonsConfigInp)
if err != nil {
return
}
@@ -48,7 +53,7 @@ func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp
}
// UpdateConfigByGroup 更新指定分组的配置
-func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error {
+func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateConfigInp) error {
in.UpdateAddonsConfigInp.AddonName = global.GetSkeleton().Name
- return isc.SysAddonsConfig().UpdateConfigByGroup(ctx, in.UpdateAddonsConfigInp)
+ return isc.SysAddonsConfig().UpdateConfigByGroup(ctx, &in.UpdateAddonsConfigInp)
}
diff --git a/server/addons/hgexample/logic/sys/index.go b/server/addons/hgexample/logic/sys/index.go
index 2b2359f..d3e8ccd 100644
--- a/server/addons/hgexample/logic/sys/index.go
+++ b/server/addons/hgexample/logic/sys/index.go
@@ -26,7 +26,7 @@ func init() {
}
// Test 测试
-func (s *sSysIndex) Test(ctx context.Context, in sysin.IndexTestInp) (res *sysin.IndexTestModel, err error) {
+func (s *sSysIndex) Test(ctx context.Context, in *sysin.IndexTestInp) (res *sysin.IndexTestModel, err error) {
res = new(sysin.IndexTestModel)
res.Name = in.Name
res.Module = fmt.Sprintf("当前插件模块是:%s,当前应用模块是:%s", global.GetSkeleton().Name, contexts.Get(ctx).Module)
diff --git a/server/addons/hgexample/logic/sys/table.go b/server/addons/hgexample/logic/sys/table.go
index 6ffbc23..2125a62 100644
--- a/server/addons/hgexample/logic/sys/table.go
+++ b/server/addons/hgexample/logic/sys/table.go
@@ -15,7 +15,6 @@ import (
"github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/hgexample/model/input/sysin"
"hotgo/addons/hgexample/service"
- "hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm"
@@ -42,54 +41,55 @@ func (s *sSysTable) Model(ctx context.Context, option ...*handler.Option) *gdb.M
}
// List 获取列表
-func (s *sSysTable) List(ctx context.Context, in sysin.TableListInp) (list []*sysin.TableListModel, totalCount int, err error) {
+func (s *sSysTable) List(ctx context.Context, in *sysin.TableListInp) (list []*sysin.TableListModel, totalCount int, err error) {
mod := s.Model(ctx)
+ cols := dao.AddonHgexampleTable.Columns()
if in.Title != "" {
- mod = mod.WhereLike(dao.AddonHgexampleTable.Columns().Title, "%"+in.Title+"%")
+ mod = mod.WhereLike(cols.Title, "%"+in.Title+"%")
}
if in.Content != "" {
- mod = mod.WhereLike(dao.AddonHgexampleTable.Columns().Content, "%"+in.Content+"%")
+ mod = mod.WhereLike(cols.Content, "%"+in.Content+"%")
}
if in.Status > 0 {
- mod = mod.Where(dao.AddonHgexampleTable.Columns().Status, in.Status)
+ mod = mod.Where(cols.Status, in.Status)
}
if in.Switch > 0 {
- mod = mod.Where(dao.AddonHgexampleTable.Columns().Switch, in.Switch)
+ mod = mod.Where(cols.Switch, in.Switch)
}
if len(in.Price) > 0 {
- if in.Price[0] > float64(0) && in.Price[1] > float64(0) {
- mod = mod.WhereBetween(dao.AddonHgexampleTable.Columns().Price, in.Price[0], in.Price[1])
- } else if in.Price[0] > float64(0) && in.Price[1] == float64(0) {
- mod = mod.WhereGTE(dao.AddonHgexampleTable.Columns().Price, in.Price[0])
- } else if in.Price[0] == float64(0) && in.Price[1] > float64(0) {
- mod = mod.WhereLTE(dao.AddonHgexampleTable.Columns().Price, in.Price[1])
+ if in.Price[0] > 0 && in.Price[1] > 0 {
+ mod = mod.WhereBetween(cols.Price, in.Price[0], in.Price[1])
+ } else if in.Price[0] > 0 && in.Price[1] == 0 {
+ mod = mod.WhereGTE(cols.Price, in.Price[0])
+ } else if in.Price[0] == 0 && in.Price[1] > 0 {
+ mod = mod.WhereLTE(cols.Price, in.Price[1])
}
}
if in.ActivityAt != nil {
- mod = mod.Where(dao.AddonHgexampleTable.Columns().ActivityAt, in.ActivityAt)
+ mod = mod.Where(cols.ActivityAt, in.ActivityAt)
}
if len(in.CreatedAt) == 2 {
- mod = mod.WhereBetween(dao.AddonHgexampleTable.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
+ mod = mod.WhereBetween(cols.CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
}
if !in.Flag.IsNil() {
- mod = mod.Where(fmt.Sprintf(`JSON_CONTAINS(%s,'%v')`, dao.AddonHgexampleTable.Columns().Flag, in.Flag))
+ mod = mod.Where(fmt.Sprintf(`JSON_CONTAINS(%s,'%v')`, cols.Flag, in.Flag))
}
if !in.Hobby.IsNil() {
- mod = mod.Where(fmt.Sprintf(`JSON_CONTAINS(%s,'%v')`, dao.AddonHgexampleTable.Columns().Hobby, in.Hobby))
+ mod = mod.Where(fmt.Sprintf(`JSON_CONTAINS(%s,'%v')`, cols.Hobby, in.Hobby))
}
//// 关联表testCategory
//mod = mod.LeftJoin(hgorm.GenJoinOnRelation(
- // dao.AddonHgexampleTable.Table(), dao.AddonHgexampleTable.Columns().CategoryId, // 主表表名,关联条件
+ // dao.AddonHgexampleTable.Table(), cols.CategoryId, // 主表表名,关联条件
// dao.AddonHgexampleTableCategory.Table(), "testCategory", dao.AddonHgexampleTableCategory.Columns().Id, // 关联表表名,别名,关联条件
//)...)
//
@@ -97,7 +97,7 @@ func (s *sSysTable) List(ctx context.Context, in sysin.TableListInp) (list []*sy
totalCount, err = mod.Clone().Count(1)
if err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
+ err = gerror.Wrap(err, "获取表格数据行失败,请稍后重试!")
return
}
@@ -105,15 +105,15 @@ func (s *sSysTable) List(ctx context.Context, in sysin.TableListInp) (list []*sy
return
}
- if err = mod.Fields(sysin.TableListModel{}).Page(in.Page, in.PerPage).OrderAsc(dao.AddonHgexampleTable.Columns().Sort).OrderDesc(dao.AddonHgexampleTable.Columns().Id).Scan(&list); err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
+ if err = mod.Fields(sysin.TableListModel{}).Page(in.Page, in.PerPage).OrderAsc(cols.Sort).OrderDesc(cols.Id).Scan(&list); err != nil {
+ err = gerror.Wrap(err, "获取表格列表失败,请稍后重试!")
return
}
return
}
// Export 导出
-func (s *sSysTable) Export(ctx context.Context, in sysin.TableListInp) (err error) {
+func (s *sSysTable) Export(ctx context.Context, in *sysin.TableListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
@@ -142,57 +142,56 @@ func (s *sSysTable) Export(ctx context.Context, in sysin.TableListInp) (err erro
}
// Edit 修改/新增
-func (s *sSysTable) Edit(ctx context.Context, in sysin.TableEditInp) (err error) {
- if err = hgorm.IsUnique(ctx, &dao.AddonHgexampleTable, g.Map{dao.AddonHgexampleTable.Columns().Qq: in.Qq}, "QQ号码已存在,请换一个", in.Id); err != nil {
+func (s *sSysTable) Edit(ctx context.Context, in *sysin.TableEditInp) (err error) {
+ cols := dao.AddonHgexampleTable.Columns()
+ if err = hgorm.IsUnique(ctx, &dao.AddonHgexampleTable, g.Map{cols.Qq: in.Qq}, "QQ号码已存在,请换一个", in.Id); err != nil {
return
}
// 修改
if in.Id > 0 {
in.UpdatedBy = contexts.GetUserId(ctx)
- _, err = s.Model(ctx).Where(dao.AddonHgexampleTable.Columns().Id, in.Id).Data(in).Update()
+ if _, err = s.Model(ctx).WherePri(in.Id).Data(in).Update(); err != nil {
+ err = gerror.Wrap(err, "修改表格失败,请稍后重试!")
+ return
+ }
return
}
// 新增
in.CreatedBy = contexts.GetUserId(ctx)
- _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).Data(in).Insert()
+ if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).Data(in).Insert(); err != nil {
+ err = gerror.Wrap(err, "新增表格失败,请稍后重试!")
+ return
+ }
return
}
// Delete 删除
-func (s *sSysTable) Delete(ctx context.Context, in sysin.TableDeleteInp) (err error) {
- _, err = s.Model(ctx).Where(dao.AddonHgexampleTable.Columns().Id, in.Id).Delete()
+func (s *sSysTable) Delete(ctx context.Context, in *sysin.TableDeleteInp) (err error) {
+ if _, err = s.Model(ctx).WherePri(in.Id).Delete(); err != nil {
+ err = gerror.Wrap(err, "删除表格失败,请稍后重试!")
+ return
+ }
return
}
// Status 更新状态
-func (s *sSysTable) Status(ctx context.Context, in sysin.TableStatusInp) (err error) {
- if in.Id <= 0 {
- err = gerror.New("ID不能为空")
- return
- }
-
- if in.Status <= 0 {
- err = gerror.New("状态不能为空")
- return
- }
-
- if !validate.InSlice(consts.StatusSlice, in.Status) {
- err = gerror.New("状态不正确")
- return
- }
-
- // 修改
- _, err = s.Model(ctx).Where(dao.AddonHgexampleTable.Columns().Id, in.Id).Data(g.Map{
+func (s *sSysTable) Status(ctx context.Context, in *sysin.TableStatusInp) (err error) {
+ update := g.Map{
dao.AddonHgexampleTable.Columns().Status: in.Status,
dao.AddonHgexampleTable.Columns().UpdatedBy: contexts.GetUserId(ctx),
- }).Update()
+ }
+
+ if _, err = s.Model(ctx).WherePri(in.Id).Data(update).Update(); err != nil {
+ err = gerror.Wrap(err, "更新表格状态失败,请稍后重试!")
+ return
+ }
return
}
// Switch 更新开关状态
-func (s *sSysTable) Switch(ctx context.Context, in sysin.TableSwitchInp) (err error) {
+func (s *sSysTable) Switch(ctx context.Context, in *sysin.TableSwitchInp) (err error) {
var fields = []string{
dao.AddonHgexampleTable.Columns().Switch,
// ...
@@ -203,18 +202,23 @@ func (s *sSysTable) Switch(ctx context.Context, in sysin.TableSwitchInp) (err er
return
}
- // 修改
- _, err = s.Model(ctx).Where(dao.AddonHgexampleTable.Columns().Id, in.Id).Data(g.Map{
+ update := g.Map{
in.Key: in.Value,
dao.AddonHgexampleTable.Columns().UpdatedBy: contexts.GetUserId(ctx),
- }).Update()
+ }
+
+ if _, err = s.Model(ctx).Where(dao.AddonHgexampleTable.Columns().Id, in.Id).Data(update).Update(); err != nil {
+ err = gerror.Wrap(err, "更新表格开关失败,请稍后重试!")
+ return
+ }
return
}
// MaxSort 最大排序
-func (s *sSysTable) MaxSort(ctx context.Context, in sysin.TableMaxSortInp) (res *sysin.TableMaxSortModel, err error) {
- if err = dao.AddonHgexampleTable.Ctx(ctx).Fields(dao.AddonHgexampleTable.Columns().Sort).OrderDesc(dao.AddonHgexampleTable.Columns().Sort).Scan(&res); err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
+func (s *sSysTable) MaxSort(ctx context.Context, in *sysin.TableMaxSortInp) (res *sysin.TableMaxSortModel, err error) {
+ dx := dao.AddonHgexampleTable
+ if err = dx.Ctx(ctx).Fields(dx.Columns().Sort).OrderDesc(dx.Columns().Sort).Scan(&res); err != nil {
+ err = gerror.Wrap(err, "获取表格最大排序,请稍后重试!")
return
}
@@ -222,12 +226,15 @@ func (s *sSysTable) MaxSort(ctx context.Context, in sysin.TableMaxSortInp) (res
res = new(sysin.TableMaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
// View 获取指定信息
-func (s *sSysTable) View(ctx context.Context, in sysin.TableViewInp) (res *sysin.TableViewModel, err error) {
- err = s.Model(ctx).Where(dao.AddonHgexampleTable.Columns().Id, in.Id).Scan(&res)
+func (s *sSysTable) View(ctx context.Context, in *sysin.TableViewInp) (res *sysin.TableViewModel, err error) {
+ if err = s.Model(ctx).WherePri(in.Id).Scan(&res); err != nil {
+ err = gerror.Wrap(err, "获取生成演示信息,请稍后重试!")
+ return
+ }
return
}
diff --git a/server/addons/hgexample/model/input/sysin/table.go b/server/addons/hgexample/model/input/sysin/table.go
index f8c5df1..8ad6d9a 100644
--- a/server/addons/hgexample/model/input/sysin/table.go
+++ b/server/addons/hgexample/model/input/sysin/table.go
@@ -9,6 +9,7 @@ import (
"context"
"errors"
"github.com/gogf/gf/v2/encoding/gjson"
+ "github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"hotgo/internal/consts"
@@ -149,6 +150,24 @@ type TableStatusInp struct {
Status int `json:"status" dc:"状态"`
}
+func (in *TableStatusInp) Filter(ctx context.Context) (err error) {
+ if in.Id <= 0 {
+ err = gerror.New("ID不能为空")
+ return
+ }
+
+ if in.Status <= 0 {
+ err = gerror.New("状态不能为空")
+ return
+ }
+
+ if !validate.InSlice(consts.StatusSlice, in.Status) {
+ err = gerror.New("状态不正确")
+ return
+ }
+ return
+}
+
type TableStatusModel struct{}
// TableSwitchInp 更新开关状态
diff --git a/server/addons/hgexample/queues/queues.go b/server/addons/hgexample/queues/queues.go
index 892a3d2..9f2e7eb 100644
--- a/server/addons/hgexample/queues/queues.go
+++ b/server/addons/hgexample/queues/queues.go
@@ -1,3 +1,8 @@
+// Package queues
+// @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 queues
// 消息队列.
diff --git a/server/addons/hgexample/service/sys.go b/server/addons/hgexample/service/sys.go
index 5e04b2f..b26e867 100644
--- a/server/addons/hgexample/service/sys.go
+++ b/server/addons/hgexample/service/sys.go
@@ -17,29 +17,29 @@ import (
type (
ISysConfig interface {
GetBasic(ctx context.Context) (conf *model.BasicConfig, err error)
- GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
- UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error
+ GetConfigByGroup(ctx context.Context, in *sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
+ UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateConfigInp) error
}
ISysIndex interface {
- Test(ctx context.Context, in sysin.IndexTestInp) (res *sysin.IndexTestModel, err error)
+ Test(ctx context.Context, in *sysin.IndexTestInp) (res *sysin.IndexTestModel, err error)
}
ISysTable interface {
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
- List(ctx context.Context, in sysin.TableListInp) (list []*sysin.TableListModel, totalCount int, err error)
- Export(ctx context.Context, in sysin.TableListInp) (err error)
- Edit(ctx context.Context, in sysin.TableEditInp) (err error)
- Delete(ctx context.Context, in sysin.TableDeleteInp) (err error)
- Status(ctx context.Context, in sysin.TableStatusInp) (err error)
- Switch(ctx context.Context, in sysin.TableSwitchInp) (err error)
- MaxSort(ctx context.Context, in sysin.TableMaxSortInp) (res *sysin.TableMaxSortModel, err error)
- View(ctx context.Context, in sysin.TableViewInp) (res *sysin.TableViewModel, err error)
+ List(ctx context.Context, in *sysin.TableListInp) (list []*sysin.TableListModel, totalCount int, err error)
+ Export(ctx context.Context, in *sysin.TableListInp) (err error)
+ Edit(ctx context.Context, in *sysin.TableEditInp) (err error)
+ Delete(ctx context.Context, in *sysin.TableDeleteInp) (err error)
+ Status(ctx context.Context, in *sysin.TableStatusInp) (err error)
+ Switch(ctx context.Context, in *sysin.TableSwitchInp) (err error)
+ MaxSort(ctx context.Context, in *sysin.TableMaxSortInp) (res *sysin.TableMaxSortModel, err error)
+ View(ctx context.Context, in *sysin.TableViewInp) (res *sysin.TableViewModel, err error)
}
)
var (
- localSysTable ISysTable
localSysConfig ISysConfig
localSysIndex ISysIndex
+ localSysTable ISysTable
)
func SysConfig() ISysConfig {
diff --git a/server/api/admin/addons/addons.go b/server/api/admin/addons/addons.go
index bef6c6f..f454188 100644
--- a/server/api/admin/addons/addons.go
+++ b/server/api/admin/addons/addons.go
@@ -24,6 +24,7 @@ type ListRes struct {
type SelectsReq struct {
g.Meta `path:"/addons/selects" method:"get" tags:"插件管理" summary:"生成入口选项"`
+ sysin.AddonsSelectsInp
}
type SelectsRes struct {
diff --git a/server/api/admin/attachment/attachment.go b/server/api/admin/attachment/attachment.go
index bb06707..cc9277e 100644
--- a/server/api/admin/attachment/attachment.go
+++ b/server/api/admin/attachment/attachment.go
@@ -13,12 +13,8 @@ import (
// ListReq 查询附件列表
type ListReq struct {
- form.PageReq
- form.RangeDateReq
- form.StatusReq
- MemberId int64 `json:"member_id"`
- Drive string `json:"drive"`
- g.Meta `path:"/attachment/list" method:"get" tags:"附件" summary:"获取附件列表"`
+ g.Meta `path:"/attachment/list" method:"get" tags:"附件" summary:"获取附件列表"`
+ sysin.AttachmentListInp
}
type ListRes struct {
@@ -28,8 +24,8 @@ type ListRes struct {
// ViewReq 获取附件信息
type ViewReq struct {
- Id int64 `json:"id" v:"required#附件ID不能为空" dc:"附件ID"`
g.Meta `path:"/attachment/view" method:"get" tags:"附件" summary:"获取指定附件信息"`
+ sysin.AttachmentViewInp
}
type ViewRes struct {
@@ -38,8 +34,34 @@ type ViewRes struct {
// DeleteReq 删除附件
type DeleteReq struct {
- Id interface{} `json:"id" v:"required#附件ID不能为空" dc:"附件ID"`
g.Meta `path:"/attachment/delete" method:"post" tags:"附件" summary:"删除附件"`
+ sysin.AttachmentDeleteInp
}
type DeleteRes struct{}
+
+// ClearKindReq 清空上传类型
+type ClearKindReq struct {
+ g.Meta `path:"/attachment/clearKind" method:"post" tags:"附件" summary:"清空上传类型"`
+ sysin.AttachmentClearKindInp
+}
+
+type ClearKindRes struct{}
+
+// ChooserOptionReq 获取选择器选项
+type ChooserOptionReq struct {
+ g.Meta `path:"/attachment/chooserOption" method:"get" tags:"附件" summary:"获取选择器选项"`
+}
+
+type ChooserOptionRes struct {
+ Drive sysin.DataSelectModel `json:"drive" dc:"驱动"`
+ Kind []KindSelect `json:"kind" dc:"上传类型"`
+}
+
+type KindSelect struct {
+ Key string `json:"key"`
+ Value string `json:"value"`
+ Tag string `json:"listClass"`
+ Label string `json:"label"`
+ Icon string `json:"icon"`
+}
diff --git a/server/api/admin/blacklist/blacklist.go b/server/api/admin/blacklist/blacklist.go
index 85a5965..361fc4b 100644
--- a/server/api/admin/blacklist/blacklist.go
+++ b/server/api/admin/blacklist/blacklist.go
@@ -7,19 +7,14 @@ package blacklist
import (
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
)
// ListReq 查询列表
type ListReq struct {
- form.PageReq
- form.RangeDateReq
- form.StatusReq
- Title string `json:"title"`
- Content string `json:"content"`
- g.Meta `path:"/blacklist/list" method:"get" tags:"黑名单" summary:"获取黑名单列表"`
+ g.Meta `path:"/blacklist/list" method:"get" tags:"黑名单" summary:"获取黑名单列表"` // v:"RequestPreFilter"
+ sysin.BlacklistListInp
}
type ListRes struct {
@@ -29,8 +24,8 @@ type ListRes struct {
// ViewReq 获取信息
type ViewReq struct {
- Id int64 `json:"id" v:"required#黑名单ID不能为空" dc:"黑名单ID"`
g.Meta `path:"/blacklist/view" method:"get" tags:"黑名单" summary:"获取指定信息"`
+ sysin.BlacklistViewInp
}
type ViewRes struct {
@@ -39,34 +34,24 @@ type ViewRes struct {
// EditReq 修改/新增
type EditReq struct {
- entity.SysBlacklist
g.Meta `path:"/blacklist/edit" method:"post" tags:"黑名单" summary:"修改/新增黑名单"`
+ sysin.BlacklistEditInp
}
type EditRes struct{}
// DeleteReq 删除
type DeleteReq struct {
- Id interface{} `json:"id" v:"required#黑名单ID不能为空" dc:"黑名单ID"`
g.Meta `path:"/blacklist/delete" method:"post" tags:"黑名单" summary:"删除黑名单"`
+ sysin.BlacklistDeleteInp
}
type DeleteRes struct{}
-// MaxSortReq 最大排序
-type MaxSortReq struct {
- Id int64 `json:"id" dc:"黑名单ID"`
- g.Meta `path:"/blacklist/maxSort" method:"get" tags:"黑名单" summary:"黑名单最大排序"`
-}
-
-type MaxSortRes struct {
- Sort int `json:"sort" dc:"排序"`
-}
-
// StatusReq 更新状态
type StatusReq struct {
- entity.SysBlacklist
g.Meta `path:"/blacklist/status" method:"post" tags:"黑名单" summary:"更新黑名单状态"`
+ sysin.BlacklistStatusInp
}
type StatusRes struct{}
diff --git a/server/api/admin/cash/cash.go b/server/api/admin/cash/cash.go
index 434c5de..0d82d1f 100644
--- a/server/api/admin/cash/cash.go
+++ b/server/api/admin/cash/cash.go
@@ -34,18 +34,16 @@ type ViewRes struct {
// ApplyReq 申请提现
type ApplyReq struct {
- Money float64 `json:"money" description:"提现金额"`
g.Meta `path:"/cash/apply" method:"post" tags:"提现" summary:"申请提现"`
+ Money float64 `json:"money" description:"提现金额"`
}
type ApplyRes struct{}
// PaymentReq 提现打款处理
type PaymentReq struct {
- Id int64 `json:"id" description:"ID"`
- Status int64 `json:"status" description:"状态码"`
- Msg string `json:"msg" description:"处理结果"`
g.Meta `path:"/cash/payment" method:"post" tags:"提现" summary:"提现打款处理"`
+ adminin.CashPaymentInp
}
type PaymentRes struct{}
diff --git a/server/api/admin/common/ems.go b/server/api/admin/common/ems.go
index 4b3a97b..82a5a53 100644
--- a/server/api/admin/common/ems.go
+++ b/server/api/admin/common/ems.go
@@ -11,8 +11,8 @@ import (
// SendTestEmailReq 发送测试邮件
type SendTestEmailReq struct {
- To string `json:"to" v:"required#接收者邮件不能为空" dc:"接收者邮件,多个用;隔开"`
g.Meta `path:"/ems/sendTest" tags:"邮件" method:"post" summary:"发送测试邮件"`
+ To string `json:"to" v:"required#接收者邮件不能为空" dc:"接收者邮件,多个用;隔开"`
}
type SendTestEmailRes struct {
diff --git a/server/api/admin/common/sms.go b/server/api/admin/common/sms.go
index 4343ece..53ebbd1 100644
--- a/server/api/admin/common/sms.go
+++ b/server/api/admin/common/sms.go
@@ -5,14 +5,15 @@
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package common
-import "github.com/gogf/gf/v2/frame/g"
+import (
+ "github.com/gogf/gf/v2/frame/g"
+ "hotgo/internal/model/input/sysin"
+)
// SendTestSmsReq 发送测试短信
type SendTestSmsReq struct {
- Event string `json:"event" v:"required#事件模板不能为空" dc:"事件模板"`
- Mobile string `json:"mobile" v:"required#接收手机号不能为空" dc:"接收手机号"`
- Code string `json:"code" v:"required#接收验证码不能为空" dc:"接收验证码"`
g.Meta `path:"/sms/sendTest" tags:"短信" method:"post" summary:"发送测试短信"`
+ sysin.SendCodeInp
}
type SendTestSmsRes struct {
@@ -29,8 +30,7 @@ type SendBindSmsRes struct {
// SendSmsReq 发送短信
type SendSmsReq struct {
g.Meta `path:"/sms/send" tags:"短信" method:"post" summary:"发送短信"`
- Event string `json:"event" v:"required#事件模板不能为空" dc:"事件模板"`
- Mobile string `json:"mobile" v:"required#接收手机号不能为空" dc:"接收手机号"`
+ sysin.SendCodeInp
}
type SendSmsRes struct {
diff --git a/server/api/admin/common/upload.go b/server/api/admin/common/upload.go
index 005a8b5..d29d904 100644
--- a/server/api/admin/common/upload.go
+++ b/server/api/admin/common/upload.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package common
import (
@@ -11,13 +10,6 @@ import (
"hotgo/internal/model/input/sysin"
)
-// UploadImageReq 上传图片
-type UploadImageReq struct {
- g.Meta `path:"/upload/image" tags:"上传" method:"post" summary:"上传图片"`
-}
-
-type UploadImageRes *sysin.AttachmentListModel
-
// UploadFileReq 上传文件
type UploadFileReq struct {
g.Meta `path:"/upload/file" tags:"上传" method:"post" summary:"上传附件"`
diff --git a/server/api/admin/config/config.go b/server/api/admin/config/config.go
index ea8851d..cc8b9b5 100644
--- a/server/api/admin/config/config.go
+++ b/server/api/admin/config/config.go
@@ -13,8 +13,8 @@ import (
// GetReq 获取指定分组的配置
type GetReq struct {
- Group string `json:"group" dc:"分组名称" v:"required#分组名称不能为空" `
g.Meta `path:"/config/get" method:"get" tags:"配置" summary:"获取指定分组的配置"`
+ sysin.GetConfigInp
}
type GetRes struct {
@@ -23,9 +23,8 @@ type GetRes struct {
// UpdateReq 获取指定分组的配置
type UpdateReq struct {
- Group string `json:"group" dc:"分组名称" v:"required#分组名称不能为空" `
- List g.Map `json:"list" dc:"更新配置列表" `
g.Meta `path:"/config/update" method:"post" tags:"配置" summary:"获取指定分组的配置"`
+ sysin.UpdateConfigInp
}
type UpdateRes struct {
diff --git a/server/api/admin/cron/cron_group.go b/server/api/admin/cron/cron_group.go
index 38d9ea4..fa20089 100644
--- a/server/api/admin/cron/cron_group.go
+++ b/server/api/admin/cron/cron_group.go
@@ -75,6 +75,7 @@ type GroupStatusRes struct {
// GroupSelectReq 定时任务分组选项
type GroupSelectReq struct {
g.Meta `path:"/cronGroup/select" method:"get" tags:"定时任务分组" summary:"定时任务分组选项"`
+ sysin.CronGroupSelectInp
}
type GroupSelectRes struct {
diff --git a/server/api/admin/curddemo/curddemo.go b/server/api/admin/curddemo/curddemo.go
index 612eb44..40e1e21 100644
--- a/server/api/admin/curddemo/curddemo.go
+++ b/server/api/admin/curddemo/curddemo.go
@@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-// @AutoGenerate Version 2.7.3
+// @AutoGenerate Version 2.7.6
package curddemo
import (
@@ -47,6 +47,7 @@ type EditReq struct {
g.Meta `path:"/curdDemo/edit" method:"post" tags:"生成演示" summary:"修改/新增生成演示"`
sysin.CurdDemoEditInp
}
+
type EditRes struct{}
// DeleteReq 删除生成演示
@@ -60,6 +61,7 @@ type DeleteRes struct{}
// MaxSortReq 获取生成演示最大排序
type MaxSortReq struct {
g.Meta `path:"/curdDemo/maxSort" method:"get" tags:"生成演示" summary:"获取生成演示最大排序"`
+ sysin.CurdDemoMaxSortInp
}
type MaxSortRes struct {
diff --git a/server/api/admin/dept/dept.go b/server/api/admin/dept/dept.go
index 0d0ef18..f33b68e 100644
--- a/server/api/admin/dept/dept.go
+++ b/server/api/admin/dept/dept.go
@@ -7,26 +7,22 @@ package dept
import (
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model/entity"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/form"
)
// ListReq 查询列表
type ListReq struct {
- Name string `json:"name" dc:"部门名称"`
- Code string `json:"code" dc:"部门编码"`
g.Meta `path:"/dept/list" method:"get" tags:"部门" summary:"获取部门列表"`
+ adminin.DeptListInp
}
-type ListRes struct {
- adminin.DeptListModel
-}
+type ListRes *adminin.DeptListModel
// ViewReq 获取指定信息
type ViewReq struct {
- Id int64 `json:"id" v:"required#部门ID不能为空" dc:"部门ID"`
g.Meta `path:"/dept/view" method:"get" tags:"部门" summary:"获取指定信息"`
+ adminin.DeptViewInp
}
type ViewRes struct {
@@ -35,24 +31,24 @@ type ViewRes struct {
// EditReq 修改/新增字典数据
type EditReq struct {
- entity.AdminDept
g.Meta `path:"/dept/edit" method:"post" tags:"部门" summary:"修改/新增部门"`
+ adminin.DeptEditInp
}
type EditRes struct{}
// DeleteReq 删除字典类型
type DeleteReq struct {
- Id interface{} `json:"id" v:"required#部门ID不能为空" dc:"部门ID"`
g.Meta `path:"/dept/delete" method:"post" tags:"部门" summary:"删除部门"`
+ adminin.DeptDeleteInp
}
type DeleteRes struct{}
// MaxSortReq 最大排序
type MaxSortReq struct {
- Id int64 `json:"id" dc:"部门ID"`
g.Meta `path:"/dept/maxSort" method:"get" tags:"部门" summary:"部门最大排序"`
+ adminin.DeptMaxSortInp
}
type MaxSortRes struct {
@@ -61,8 +57,8 @@ type MaxSortRes struct {
// StatusReq 更新部门状态
type StatusReq struct {
- entity.AdminDept
g.Meta `path:"/dept/status" method:"post" tags:"部门" summary:"更新部门状态"`
+ adminin.DeptStatusInp
}
type StatusRes struct{}
diff --git a/server/api/admin/dict/dict_data.go b/server/api/admin/dict/dict_data.go
index ddfb011..3c7e4d9 100644
--- a/server/api/admin/dict/dict_data.go
+++ b/server/api/admin/dict/dict_data.go
@@ -7,37 +7,30 @@ package dict
import (
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
)
// DataEditReq 修改/新增字典数据
type DataEditReq struct {
- entity.SysDictData
- TypeID int64 `json:"typeID" dc:"字典类型ID"`
g.Meta `path:"/dictData/edit" method:"post" tags:"字典数据" summary:"修改/新增字典数据"`
+ sysin.DictDataEditInp
}
type DataEditRes struct{}
// DataDeleteReq 删除字典数据
type DataDeleteReq struct {
- Id interface{} `json:"id" v:"required#字典数据ID不能为空" dc:"字典数据ID"`
g.Meta `path:"/dictData/delete" method:"post" tags:"字典数据" summary:"删除字典数据"`
+ sysin.DictDataDeleteInp
}
type DataDeleteRes struct{}
// DataListReq 查询列表
type DataListReq struct {
- form.PageReq
- form.RangeDateReq
- form.StatusReq
- TypeID int64 `json:"typeId" v:"required#字典类型ID不能为空" dc:"字典类型ID"` //
- Type string `json:"type"`
- Label string `json:"label"`
g.Meta `path:"/dictData/list" method:"get" tags:"字典数据" summary:"获取字典数据列表"`
+ sysin.DictDataListInp
}
type DataListRes struct {
@@ -47,7 +40,7 @@ type DataListRes struct {
type DataSelectReq struct {
g.Meta `path:"/dictData/option/{Type}" method:"get" summary:"字典数据" tags:"获取指定字典选项"`
- Type string `in:"path" v:"required#字典类型不能为空" dc:"字典类型"`
+ sysin.DataSelectInp
}
type DataSelectRes sysin.DataSelectModel
diff --git a/server/api/admin/dict/dict_type.go b/server/api/admin/dict/dict_type.go
index 3c184b3..16f09cb 100644
--- a/server/api/admin/dict/dict_type.go
+++ b/server/api/admin/dict/dict_type.go
@@ -7,7 +7,6 @@ package dict
import (
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model/entity"
"hotgo/internal/model/input/sysin"
)
@@ -22,16 +21,16 @@ type TypeTreeRes struct {
// TypeEditReq 修改/新增字典数据
type TypeEditReq struct {
- entity.AdminDept
g.Meta `path:"/dictType/edit" method:"post" tags:"字典类型" summary:"修改/新增字典类型"`
+ sysin.DictTypeEditInp
}
type TypeEditRes struct{}
// TypeDeleteReq 删除字典类型
type TypeDeleteReq struct {
- Id interface{} `json:"id" v:"required#字典类型ID不能为空" dc:"字典类型ID"`
g.Meta `path:"/dictType/delete" method:"post" tags:"字典类型" summary:"删除字典类型"`
+ sysin.DictTypeDeleteInp
}
type TypeDeleteRes struct{}
diff --git a/server/api/admin/gencodes/gencodes.go b/server/api/admin/gencodes/gencodes.go
index a4fe628..7b196c8 100644
--- a/server/api/admin/gencodes/gencodes.go
+++ b/server/api/admin/gencodes/gencodes.go
@@ -7,7 +7,6 @@ package gencodes
import (
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
)
@@ -25,8 +24,8 @@ type ListRes struct {
// ViewReq 获取指定信息
type ViewReq struct {
- Id int64 `json:"id" v:"required#生成代码ID不能为空" dc:"生成代码ID"`
g.Meta `path:"/genCodes/view" method:"get" tags:"生成代码" summary:"获取指定信息"`
+ sysin.GenCodesViewInp
}
type ViewRes struct {
@@ -35,8 +34,8 @@ type ViewRes struct {
// EditReq 修改/新增数据
type EditReq struct {
- entity.SysGenCodes
g.Meta `path:"/genCodes/edit" method:"post" tags:"生成代码" summary:"修改/新增生成代码"`
+ sysin.GenCodesEditInp
}
type EditRes struct {
@@ -45,32 +44,33 @@ type EditRes struct {
// DeleteReq 删除
type DeleteReq struct {
- Id interface{} `json:"id" v:"required#生成代码ID不能为空" dc:"生成代码ID"`
g.Meta `path:"/genCodes/delete" method:"post" tags:"生成代码" summary:"删除生成代码"`
+ sysin.GenCodesDeleteInp
}
type DeleteRes struct{}
// MaxSortReq 最大排序
type MaxSortReq struct {
- Id int64 `json:"id" dc:"生成代码ID"`
g.Meta `path:"/genCodes/maxSort" method:"get" tags:"生成代码" summary:"生成代码最大排序"`
+ sysin.GenCodesMaxSortInp
}
type MaxSortRes struct {
- Sort int `json:"sort" dc:"排序"`
+ *sysin.GenCodesMaxSortModel
}
// StatusReq 更新状态
type StatusReq struct {
- entity.SysGenCodes
g.Meta `path:"/genCodes/status" method:"post" tags:"生成代码" summary:"更新生成代码状态"`
+ sysin.GenCodesStatusInp
}
type StatusRes struct{}
type SelectsReq struct {
g.Meta `path:"/genCodes/selects" method:"get" tags:"生成代码" summary:"生成入口选项"`
+ sysin.GenCodesSelectsInp
}
type SelectsRes struct {
@@ -111,7 +111,7 @@ type PreviewRes struct {
// BuildReq 提交生成
type BuildReq struct {
g.Meta `path:"/genCodes/build" method:"post" tags:"生成代码" summary:"提交生成"`
- sysin.GenCodesPreviewInp
+ sysin.GenCodesBuildInp
}
type BuildRes struct {
diff --git a/server/api/admin/log/log.go b/server/api/admin/log/log.go
index 08122ed..d2c8ad3 100644
--- a/server/api/admin/log/log.go
+++ b/server/api/admin/log/log.go
@@ -21,15 +21,7 @@ type ClearRes struct{}
// ExportReq 导出
type ExportReq struct {
g.Meta `path:"/log/export" method:"get" tags:"日志" summary:"导出日志"`
- form.PageReq
- form.RangeDateReq
- Module string `json:"module" dc:"应用端口"`
- MemberId int `json:"member_id" dc:"用户ID"`
- TakeUpTime int `json:"take_up_time" dc:"请求耗时"`
- Method string `json:"method" dc:"请求方式"`
- Url string `json:"url" dc:"请求路径"`
- Ip string `json:"ip" dc:"访问IP"`
- ErrorCode string `json:"error_code" dc:"状态码"`
+ sysin.LogListInp
}
type ExportRes struct{}
@@ -37,16 +29,7 @@ type ExportRes struct{}
// ListReq 获取菜单列表
type ListReq struct {
g.Meta `path:"/log/list" method:"get" tags:"日志" summary:"获取日志列表"`
- form.PageReq
- form.RangeDateReq
- Module string `json:"module" dc:"应用端口"`
- MemberId int `json:"member_id" dc:"用户ID"`
- TakeUpTime int `json:"take_up_time" dc:"请求耗时"`
- Method string `json:"method" dc:"请求方式"`
- Url string `json:"url" dc:"请求路径"`
- Ip string `json:"ip" dc:"访问IP"`
- ErrorCode string `json:"error_code" dc:"状态码"`
- CreatedAt []int64 `json:"created_at " dc:"访问时间区间"`
+ sysin.LogListInp
}
type ListRes struct {
@@ -57,7 +40,7 @@ type ListRes struct {
// DeleteReq 删除
type DeleteReq struct {
g.Meta `path:"/log/delete" method:"post" tags:"日志" summary:"删除日志"`
- Id interface{} `json:"id" v:"required#日志ID不能为空" description:"日志ID"`
+ sysin.LogDeleteInp
}
type DeleteRes struct{}
@@ -65,7 +48,7 @@ type DeleteRes struct{}
// ViewReq 获取指定信息
type ViewReq struct {
g.Meta `path:"/log/view" method:"get" tags:"日志" summary:"获取指定信息"`
- Id string `json:"id" v:"required#日志ID不能为空" description:"日志ID"`
+ sysin.LogViewInp
}
type ViewRes struct {
diff --git a/server/api/admin/loginlog/loginlog.go b/server/api/admin/loginlog/loginlog.go
index c14a3a1..903ad8f 100644
--- a/server/api/admin/loginlog/loginlog.go
+++ b/server/api/admin/loginlog/loginlog.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package loginlog
import (
diff --git a/server/api/admin/member/member.go b/server/api/admin/member/member.go
index 42e8014..49cd1f0 100644
--- a/server/api/admin/member/member.go
+++ b/server/api/admin/member/member.go
@@ -107,6 +107,7 @@ type StatusRes struct{}
// SelectReq 获取可选的后台用户选项
type SelectReq struct {
g.Meta `path:"/member/option" method:"get" tags:"用户" summary:"获取可选的后台用户选项"`
+ adminin.MemberSelectInp
}
type SelectRes []*adminin.MemberSelectModel
diff --git a/server/api/admin/menu/menu.go b/server/api/admin/menu/menu.go
index 199cb36..45351da 100644
--- a/server/api/admin/menu/menu.go
+++ b/server/api/admin/menu/menu.go
@@ -34,7 +34,6 @@ type ListReq struct {
}
type ListRes struct {
- //List adminin.MenuList `json:"list" dc:"数据列表"`
*adminin.MenuListModel
form.PageRes
}
diff --git a/server/api/admin/monitor/monitor.go b/server/api/admin/monitor/monitor.go
index 3b6061a..b0ff750 100644
--- a/server/api/admin/monitor/monitor.go
+++ b/server/api/admin/monitor/monitor.go
@@ -7,43 +7,35 @@ package monitor
import (
"github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gtime"
+ "hotgo/internal/library/network/tcp"
"hotgo/internal/model/input/form"
)
-// OfflineReq 下线用户
-type OfflineReq struct {
- g.Meta `path:"/monitor/offline" method:"post" tags:"在线用户" summary:"下线用户"`
+// UserOfflineReq 下线用户
+type UserOfflineReq struct {
+ g.Meta `path:"/monitor/userOffline" method:"post" tags:"在线用户" summary:"下线用户"`
Id string `json:"id" v:"required#SID不能为空" description:"SID"`
}
-type OfflineRes struct{}
+type UserOfflineRes struct{}
-// OnlineListReq 获取在线用户列表
-type OnlineListReq struct {
- g.Meta `path:"/monitor/onlineList" method:"get" tags:"在线用户" summary:"获取监控列表"`
+// UserOnlineListReq 获取在线用户列表
+type UserOnlineListReq struct {
+ g.Meta `path:"/monitor/userOnlineList" method:"get" tags:"在线用户" summary:"获取在线用户列表"`
form.PageReq
- form.RangeDateReq
- form.StatusReq
- UserId int64 `json:"userId" description:"用户ID"`
- Addr string `json:"addr" description:"登录地址"`
+ UserId int64 `json:"userId" description:"用户ID"`
+ Username string `json:"username" description:"用户名"`
+ Addr string `json:"addr" description:"登录地址"`
+ FirstTime []*gtime.Time `json:"firstTime" description:"登录时间"`
}
-type OnlineListRes struct {
- List []*OnlineModel `json:"list" description:"数据列表"`
+type UserOnlineListRes struct {
+ List []*UserOnlineModel `json:"list" description:"数据列表"`
form.PageRes
}
-// OnlineViewReq 获取指定信息
-type OnlineViewReq struct {
- g.Meta `path:"/monitor/onlineView" method:"get" tags:"在线用户" summary:"获取指定用户信息"`
- Id string `json:"id" v:"required#SID不能为空" description:"SID"`
-}
-
-type OnlineViewRes struct {
- *OnlineModel
-}
-
-type OnlineModel struct {
+type UserOnlineModel struct {
ID string `json:"id"` // 连接唯一标识
Addr string `json:"addr"` // 客户端地址
Os string `json:"os"` // 客户端系统名称
@@ -56,14 +48,60 @@ type OnlineModel struct {
Avatar string `json:"avatar"` // 头像
}
-type OnlineModels []*OnlineModel
+// NetOnlineListReq 获取在线服务列表
+type NetOnlineListReq struct {
+ g.Meta `path:"/monitor/netOnlineList" method:"get" tags:"在线服务" summary:"获取在线服务列表"`
+ form.PageReq
+ Name string `json:"name" description:"应用名称"`
+ Group string `json:"group" description:"分组"`
+ AppId string `json:"appId" description:"APPID"`
+ Addr string `json:"addr" description:"登录地址"`
+ FirstTime []*gtime.Time `json:"firstTime" description:"登录时间"`
+}
-func (p OnlineModels) Len() int {
- return len(p)
+type NetOnlineListRes struct {
+ List []*NetOnlineModel `json:"list" description:"数据列表"`
+ form.PageRes
}
-func (p OnlineModels) Swap(i, j int) {
- p[i], p[j] = p[j], p[i]
+
+type NetOnlineModel struct {
+ *tcp.AuthMeta
+ Id int64 `json:"id" description:"连接ID"`
+ IsAuth bool `json:"isAuth" description:"是否认证"`
+ Addr string `json:"addr" description:"登录地址"`
+ Port string `json:"port" description:"连接端口"`
+ FirstTime int64 `json:"firstTime" description:"首次连接时间"`
+ HeartbeatTime int64 `json:"heartbeatTime" description:"上次心跳时间"`
+ LicenseId int64 `json:"licenseId" description:"许可ID"`
+ LicenseName string `json:"licenseName" description:"许可名称"`
+ LoginTimes int64 `json:"loginTimes" description:"许可累计登录次数"`
+ Online int `json:"online" description:"许可在线数量"`
+ OnlineLimit int `json:"onlineLimit" description:"许可在线数量限制"`
+ Desc string `json:"desc" description:"许可说明"`
+ Proto string `json:"proto" description:"网络协议"`
}
-func (p OnlineModels) Less(i, j int) bool {
- return p[j].FirstTime < p[i].FirstTime
+
+// NetOptionReq 获取服务选项
+type NetOptionReq struct {
+ g.Meta `path:"/monitor/netOption" method:"get" tags:"在线服务" summary:"获取服务选项"`
}
+
+type NetOptionRes struct {
+ LicenseGroup form.Selects `json:"licenseGroup" dc:"授权分组"`
+ Routes []*RouteSelect `json:"routes" dc:"路由选项"`
+}
+
+type RouteSelect struct {
+ Value interface{} `json:"value"`
+ Label string `json:"label"`
+ Disabled bool `json:"disabled"`
+ IsRPC bool `json:"isRPC"`
+}
+
+// NetOfflineReq 下线服务
+type NetOfflineReq struct {
+ g.Meta `path:"/monitor/netOffline" method:"post" tags:"在线服务" summary:"下线服务"`
+ Id int64 `json:"id" v:"required#连接ID不能为空" description:"连接ID"`
+}
+
+type NetOfflineRes struct{}
diff --git a/server/api/admin/notice/notice.go b/server/api/admin/notice/notice.go
index b74e994..75232df 100644
--- a/server/api/admin/notice/notice.go
+++ b/server/api/admin/notice/notice.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package notice
import (
@@ -56,7 +55,7 @@ type MaxSortReq struct {
}
type MaxSortRes struct {
- Sort int `json:"sort" dc:"排序"`
+ *adminin.NoticeMaxSortModel
}
// StatusReq 更新公告状态
diff --git a/server/api/admin/post/post.go b/server/api/admin/post/post.go
index c153e3d..e0659a6 100644
--- a/server/api/admin/post/post.go
+++ b/server/api/admin/post/post.go
@@ -7,7 +7,6 @@ package post
import (
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model/entity"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/form"
)
@@ -15,7 +14,7 @@ import (
// EditReq 修改/新增岗位
type EditReq struct {
g.Meta `path:"/post/edit" method:"post" tags:"岗位" summary:"修改/新增岗位"`
- entity.AdminPost
+ adminin.PostEditInp
}
type EditRes struct{}
@@ -23,7 +22,7 @@ type EditRes struct{}
// DeleteReq 删除岗位
type DeleteReq struct {
g.Meta `path:"/post/delete" method:"post" tags:"岗位" summary:"删除岗位"`
- Id interface{} `json:"id" v:"required#岗位ID不能为空" description:"岗位ID"`
+ adminin.PostDeleteInp
}
type DeleteRes struct{}
@@ -31,21 +30,17 @@ type DeleteRes struct{}
// MaxSortReq 最大排序
type MaxSortReq struct {
g.Meta `path:"/post/maxSort" method:"get" tags:"岗位" summary:"岗位最大排序"`
- Id int64 `json:"id" description:"岗位ID"`
+ adminin.PostMaxSortInp
}
type MaxSortRes struct {
- Sort int `json:"sort" description:"排序"`
+ *adminin.PostMaxSortModel
}
// ListReq 获取列表
type ListReq struct {
g.Meta `path:"/post/list" method:"get" tags:"岗位" summary:"获取岗位列表"`
- form.PageReq
- form.RangeDateReq
- form.StatusReq
- Name string `json:"name" description:"岗位名称"`
- Code string `json:"code" description:"岗位编码"`
+ adminin.PostListInp
}
type ListRes struct {
@@ -56,39 +51,17 @@ type ListRes struct {
// ViewReq 获取指定信息
type ViewReq struct {
g.Meta `path:"/post/view" method:"get" tags:"岗位" summary:"获取指定信息"`
- Id string `json:"id" v:"required#岗位ID不能为空" description:"岗位ID"`
+ adminin.PostViewInp
}
type ViewRes struct {
*adminin.PostViewModel
}
-// CodeUniqueReq 编码是否唯一
-type CodeUniqueReq struct {
- g.Meta `path:"/post/code_unique" method:"get" tags:"岗位" summary:"岗位编码是否唯一"`
- Code string `json:"code" v:"required#岗位编码不能为空" description:"岗位编码"`
- Id int64 `json:"id" description:"岗位ID"`
-}
-
-type CodeUniqueRes struct {
- IsUnique bool `json:"is_unique" description:"是否唯一"`
-}
-
-// NameUniqueReq 名称是否唯一
-type NameUniqueReq struct {
- g.Meta `path:"/post/name_unique" method:"get" tags:"岗位" summary:"岗位名称是否唯一"`
- Name string `json:"name" v:"required#岗位名称不能为空" description:"岗位名称"`
- Id int64 `json:"id" description:"岗位ID"`
-}
-
-type NameUniqueRes struct {
- IsUnique bool `json:"is_unique" description:"是否唯一"`
-}
-
// StatusReq 更新状态
type StatusReq struct {
- entity.AdminPost
g.Meta `path:"/post/status" method:"post" tags:"岗位" summary:"更新岗位状态"`
+ adminin.PostStatusInp
}
type StatusRes struct{}
diff --git a/server/api/admin/provinces/provinces.go b/server/api/admin/provinces/provinces.go
index 14c9323..1c23fb1 100644
--- a/server/api/admin/provinces/provinces.go
+++ b/server/api/admin/provinces/provinces.go
@@ -7,19 +7,14 @@ package provinces
import (
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
)
// ListReq 查询列表
type ListReq struct {
- form.PageReq
- form.RangeDateReq
- form.StatusReq
- Title string `json:"title"`
- Content string `json:"content"`
- g.Meta `path:"/provinces/list" method:"get" tags:"省市区" summary:"获取省市区列表"`
+ g.Meta `path:"/provinces/list" method:"get" tags:"省市区" summary:"获取省市区列表"`
+ sysin.ProvincesListInp
}
type ListRes struct {
@@ -29,8 +24,8 @@ type ListRes struct {
// ViewReq 获取信息
type ViewReq struct {
- Id int64 `json:"id" v:"required#省市区ID不能为空" dc:"省市区ID"`
g.Meta `path:"/provinces/view" method:"get" tags:"省市区" summary:"获取指定信息"`
+ sysin.ProvincesViewInp
}
type ViewRes struct {
@@ -56,6 +51,7 @@ type DeleteRes struct{}
// MaxSortReq 最大排序
type MaxSortReq struct {
g.Meta `path:"/provinces/maxSort" method:"get" tags:"省市区" summary:"省市区最大排序"`
+ sysin.ProvincesMaxSortInp
}
type MaxSortRes struct {
@@ -64,8 +60,8 @@ type MaxSortRes struct {
// StatusReq 更新状态
type StatusReq struct {
- entity.SysProvinces
g.Meta `path:"/provinces/status" method:"post" tags:"省市区" summary:"更新省市区状态"`
+ sysin.ProvincesStatusInp
}
type StatusRes struct{}
diff --git a/server/api/admin/role/role.go b/server/api/admin/role/role.go
index 692bd8c..f9e4ca5 100644
--- a/server/api/admin/role/role.go
+++ b/server/api/admin/role/role.go
@@ -27,34 +27,8 @@ type DynamicReq struct {
g.Meta `path:"/role/dynamic" method:"get" tags:"路由" summary:"获取动态路由" description:"获取登录用户动态路由"`
}
-type DynamicMeta struct {
- Title string `json:"title" description:"菜单标题"`
- Icon string `json:"icon" description:"菜单图标"`
- NoCache bool `json:"noCache" description:"是否缓存"`
- Remark string `json:"remark" description:"备注"`
-}
-
-type DynamicBase struct {
- Id int64 `json:"id" description:"菜单ID"`
- Pid int64 `json:"pid" description:"父ID"`
- Name string `json:"name" description:"菜单名称"`
- Code string `json:"code" description:"菜单编码"`
- Path string `json:"path" description:"路由地址"`
- Hidden bool `json:"hidden" description:"是否隐藏"`
- Redirect string `json:"redirect" description:"重定向"`
- Component string `json:"component" description:"组件路径"`
- AlwaysShow bool `json:"alwaysShow" description:"暂时不知道干啥"`
- IsFrame string `json:"isFrame" description:"是否为外链(0是 1否)"`
- Meta *DynamicMeta `json:"meta" description:"配置数据集"`
-}
-
-type DynamicMenu struct {
- DynamicBase
- Children []*DynamicBase `json:"children" description:"子菜单"`
-}
-
type DynamicRes struct {
- List []adminin.MenuRoute `json:"list" description:"数据列表"`
+ List []*adminin.MenuRoute `json:"list" description:"数据列表"`
}
type UpdatePermissionsReq struct {
diff --git a/server/api/admin/servelicense/servelicense.go b/server/api/admin/servelicense/servelicense.go
new file mode 100644
index 0000000..78c7f20
--- /dev/null
+++ b/server/api/admin/servelicense/servelicense.go
@@ -0,0 +1,74 @@
+// Package servelicense
+// @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
+// @AutoGenerate Version 2.7.6
+package servelicense
+
+import (
+ "github.com/gogf/gf/v2/frame/g"
+ "hotgo/internal/model/input/form"
+ "hotgo/internal/model/input/sysin"
+)
+
+// ListReq 查询服务许可证列表
+type ListReq struct {
+ g.Meta `path:"/serveLicense/list" method:"get" tags:"服务许可证" summary:"获取服务许可证列表"`
+ sysin.ServeLicenseListInp
+}
+
+type ListRes struct {
+ form.PageRes
+ List []*sysin.ServeLicenseListModel `json:"list" dc:"数据列表"`
+}
+
+// ExportReq 导出服务许可证列表
+type ExportReq struct {
+ g.Meta `path:"/serveLicense/export" method:"get" tags:"服务许可证" summary:"导出服务许可证列表"`
+ sysin.ServeLicenseListInp
+}
+
+type ExportRes struct{}
+
+// ViewReq 获取服务许可证指定信息
+type ViewReq struct {
+ g.Meta `path:"/serveLicense/view" method:"get" tags:"服务许可证" summary:"获取服务许可证指定信息"`
+ sysin.ServeLicenseViewInp
+}
+
+type ViewRes struct {
+ *sysin.ServeLicenseViewModel
+}
+
+// EditReq 修改/新增服务许可证
+type EditReq struct {
+ g.Meta `path:"/serveLicense/edit" method:"post" tags:"服务许可证" summary:"修改/新增服务许可证"`
+ sysin.ServeLicenseEditInp
+}
+
+type EditRes struct{}
+
+// DeleteReq 删除服务许可证
+type DeleteReq struct {
+ g.Meta `path:"/serveLicense/delete" method:"post" tags:"服务许可证" summary:"删除服务许可证"`
+ sysin.ServeLicenseDeleteInp
+}
+
+type DeleteRes struct{}
+
+// StatusReq 更新服务许可证状态
+type StatusReq struct {
+ g.Meta `path:"/serveLicense/status" method:"post" tags:"服务许可证" summary:"更新服务许可证状态"`
+ sysin.ServeLicenseStatusInp
+}
+
+type StatusRes struct{}
+
+// AssignRouterReq 分配服务许可证路由
+type AssignRouterReq struct {
+ g.Meta `path:"/serveLicense/assignRouter" method:"post" tags:"服务许可证" summary:"分配服务许可证路由"`
+ sysin.ServeLicenseAssignRouterInp
+}
+
+type AssignRouterRes struct{}
diff --git a/server/api/admin/servelog/servelog.go b/server/api/admin/servelog/servelog.go
index e48f05f..d250cd1 100644
--- a/server/api/admin/servelog/servelog.go
+++ b/server/api/admin/servelog/servelog.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package servelog
import (
diff --git a/server/api/admin/smslog/smslog.go b/server/api/admin/smslog/smslog.go
index 170d549..a5d0362 100644
--- a/server/api/admin/smslog/smslog.go
+++ b/server/api/admin/smslog/smslog.go
@@ -2,7 +2,6 @@ package smslog
import (
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
)
@@ -20,8 +19,8 @@ type ListRes struct {
// ViewReq 获取指定信息
type ViewReq struct {
- Id int64 `json:"id" v:"required#短信记录ID不能为空" dc:"短信记录ID"`
g.Meta `path:"/smsLog/view" method:"get" tags:"短信记录" summary:"获取指定信息"`
+ sysin.SmsLogViewInp
}
type ViewRes struct {
@@ -30,42 +29,24 @@ type ViewRes struct {
// EditReq 修改/新增数据
type EditReq struct {
- entity.SysSmsLog
g.Meta `path:"/smsLog/edit" method:"post" tags:"短信记录" summary:"修改/新增短信记录"`
+ sysin.SmsLogEditInp
}
type EditRes struct{}
// DeleteReq 删除
type DeleteReq struct {
- Id interface{} `json:"id" v:"required#短信记录ID不能为空" dc:"短信记录ID"`
g.Meta `path:"/smsLog/delete" method:"post" tags:"短信记录" summary:"删除短信记录"`
+ sysin.SmsLogDeleteInp
}
type DeleteRes struct{}
-// MaxSortReq 最大排序
-type MaxSortReq struct {
- Id int64 `json:"id" dc:"短信记录ID"`
- g.Meta `path:"/smsLog/maxSort" method:"get" tags:"短信记录" summary:"短信记录最大排序"`
-}
-
-type MaxSortRes struct {
- Sort int `json:"sort" dc:"排序"`
-}
-
// StatusReq 更新状态
type StatusReq struct {
- entity.SysSmsLog
g.Meta `path:"/smsLog/status" method:"post" tags:"短信记录" summary:"更新短信记录状态"`
+ sysin.SmsLogStatusInp
}
type StatusRes struct{}
-
-// SendTestReq 更新状态
-type SendTestReq struct {
- entity.SysSmsLog
- g.Meta `path:"/smsLog/sendTest" method:"post" tags:"短信记录" summary:"发送测试短信"`
-}
-
-type SendTestRes struct{}
diff --git a/server/api/admin/user/hello.go b/server/api/admin/user/hello.go
deleted file mode 100644
index 5645fd1..0000000
--- a/server/api/admin/user/hello.go
+++ /dev/null
@@ -1,18 +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"`
-}
-
-type HelloRes struct {
- g.Meta `mime:"text/html" example:"string"`
-}
diff --git a/server/api/api/pay/notify.go b/server/api/api/pay/notify.go
index 005a0c3..4c3f9e5 100644
--- a/server/api/api/pay/notify.go
+++ b/server/api/api/pay/notify.go
@@ -12,7 +12,7 @@ type NotifyAliPayReq struct {
type NotifyAliPayRes struct {
g.Meta `mime:"text/html" type:"string" example:""`
- payin.PayNotifyModel
+ *payin.PayNotifyModel
}
// NotifyWxPayReq 微信支付回调
@@ -20,7 +20,9 @@ type NotifyWxPayReq struct {
g.Meta `path:"/pay/notify/wxpay" method:"post" tags:"支付异步通知" summary:"微信支付回调"`
}
-type NotifyWxPayRes payin.PayNotifyModel
+type NotifyWxPayRes struct {
+ *payin.PayNotifyModel
+}
// NotifyQQPayReq QQ支付回调
type NotifyQQPayReq struct {
@@ -29,5 +31,5 @@ type NotifyQQPayReq struct {
type NotifyQQPayRes struct {
g.Meta `mime:"text/xml" type:"string"`
- payin.PayNotifyModel
+ *payin.PayNotifyModel
}
diff --git a/server/api/servmsg/auth.go b/server/api/servmsg/auth.go
new file mode 100644
index 0000000..ab3fe96
--- /dev/null
+++ b/server/api/servmsg/auth.go
@@ -0,0 +1,16 @@
+package servmsg
+
+import (
+ "hotgo/internal/library/network/tcp"
+ "hotgo/internal/model/input/servmsgin"
+)
+
+// AuthSummaryReq 授权信息
+type AuthSummaryReq struct {
+}
+
+// AuthSummaryRes 响应授权信息
+type AuthSummaryRes struct {
+ tcp.ServerRes
+ Data *servmsgin.AuthSummaryModel `json:"data,omitempty" description:"数据集"`
+}
diff --git a/server/api/servmsg/cron.go b/server/api/servmsg/cron.go
new file mode 100644
index 0000000..88a6380
--- /dev/null
+++ b/server/api/servmsg/cron.go
@@ -0,0 +1,46 @@
+package servmsg
+
+import (
+ "hotgo/internal/library/network/tcp"
+ "hotgo/internal/model/input/sysin"
+)
+
+// CronDeleteReq 删除任务
+type CronDeleteReq struct {
+ *sysin.CronDeleteInp
+}
+
+type CronDeleteRes struct {
+ tcp.ServerRes
+ sysin.CronDeleteModel
+}
+
+// CronEditReq 编辑任务
+type CronEditReq struct {
+ *sysin.CronEditInp
+}
+
+type CronEditRes struct {
+ tcp.ServerRes
+ *sysin.CronEditModel
+}
+
+// CronStatusReq 修改任务状态
+type CronStatusReq struct {
+ *sysin.CronStatusInp
+}
+
+type CronStatusRes struct {
+ tcp.ServerRes
+ *sysin.CronStatusModel
+}
+
+// CronOnlineExecReq 在线执行
+type CronOnlineExecReq struct {
+ *sysin.OnlineExecInp
+}
+
+type CronOnlineExecRes struct {
+ tcp.ServerRes
+ *sysin.OnlineExecModel
+}
diff --git a/server/api/servmsg/example.go b/server/api/servmsg/example.go
new file mode 100644
index 0000000..e09fb27
--- /dev/null
+++ b/server/api/servmsg/example.go
@@ -0,0 +1,28 @@
+package servmsg
+
+import (
+ "hotgo/internal/library/network/tcp"
+ "hotgo/internal/model/input/servmsgin"
+)
+
+// 一些例子.
+
+// ExampleHelloReq 一个tcp请求例子
+type ExampleHelloReq struct {
+ Name string `json:"name" description:"名字"`
+}
+
+type ExampleHelloRes struct {
+ tcp.ServerRes
+ Data *servmsgin.ExampleHelloModel `json:"data,omitempty" description:"数据集"`
+}
+
+// ExampleRPCHelloReq 一个rpc请求例子
+type ExampleRPCHelloReq struct {
+ Name string `json:"name" description:"名字"`
+}
+
+type ExampleRPCHelloRes struct {
+ tcp.ServerRes
+ Data *servmsgin.ExampleHelloModel `json:"data,omitempty" description:"数据集"`
+}
diff --git a/server/api/websocket/base/send.go b/server/api/websocket/base/send.go
index 5a9c72c..13a8d40 100644
--- a/server/api/websocket/base/send.go
+++ b/server/api/websocket/base/send.go
@@ -8,7 +8,7 @@ import (
// SendToTagReq 发送标签消息
type SendToTagReq struct {
g.Meta `path:"/send/toTag" method:"post" tags:"WebSocket" summary:"发送标签消息"`
- websocketin.SendToTagInput
+ websocketin.SendToTagInp
}
type SendToTagRes struct {
diff --git a/server/go.mod b/server/go.mod
index 7ac9b8e..576dac2 100644
--- a/server/go.mod
+++ b/server/go.mod
@@ -13,13 +13,14 @@ require (
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.4.3
- github.com/gogf/gf/contrib/nosql/redis/v2 v2.4.3
- github.com/gogf/gf/contrib/trace/jaeger/v2 v2.4.3
- github.com/gogf/gf/v2 v2.4.3
+ github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.0
+ github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.0
+ github.com/gogf/gf/contrib/trace/jaeger/v2 v2.4.4
+ github.com/gogf/gf/v2 v2.5.0
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/gorilla/websocket v1.5.0
github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794
+ github.com/minio/selfupdate v0.6.0
github.com/mojocn/base64Captcha v1.3.5
github.com/olekukonko/tablewriter v0.0.5
github.com/qiniu/go-sdk/v7 v7.14.0
@@ -31,11 +32,13 @@ require (
github.com/ufilesdk-dev/ufile-gosdk v1.0.3
github.com/xuri/excelize/v2 v2.6.0
go.opentelemetry.io/otel v1.16.0
+ golang.org/x/mod v0.9.0
golang.org/x/tools v0.7.0
gopkg.in/yaml.v3 v3.0.1
)
require (
+ aead.dev/minisign v0.2.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
@@ -114,13 +117,12 @@ require (
go.opentelemetry.io/otel/sdk v1.16.0 // indirect
go.opentelemetry.io/otel/trace v1.16.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
- golang.org/x/crypto v0.10.0 // indirect
- golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect
- golang.org/x/mod v0.9.0 // indirect
- golang.org/x/net v0.11.0 // indirect
+ golang.org/x/crypto v0.11.0 // indirect
+ golang.org/x/image v0.1.0 // indirect
+ golang.org/x/net v0.12.0 // indirect
golang.org/x/sync v0.1.0 // indirect
- golang.org/x/sys v0.9.0 // indirect
- golang.org/x/text v0.10.0 // indirect
+ golang.org/x/sys v0.10.0 // indirect
+ golang.org/x/text v0.11.0 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
gopkg.in/ini.v1 v1.56.0 // indirect
stathat.com/c/consistent v1.0.0 // indirect
diff --git a/server/go.sum b/server/go.sum
index c295c85..30472f5 100644
--- a/server/go.sum
+++ b/server/go.sum
@@ -1,3 +1,5 @@
+aead.dev/minisign v0.2.0 h1:kAWrq/hBRu4AARY6AlciO83xhNnW9UaC8YipS2uhLPk=
+aead.dev/minisign v0.2.0/go.mod h1:zdq6LdSd9TbuSxchxwhpA9zEb9YXcVGoE8JakuiGaIQ=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@@ -168,14 +170,15 @@ github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrt
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
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.4.3 h1:KQ+NbjzRnc6vI59txxb7xh1z7XUNSECuVrKagunpdNU=
-github.com/gogf/gf/contrib/drivers/mysql/v2 v2.4.3/go.mod h1:6X8mwgoByuHnal8X+iLYWvtQQf5ONfOUgsXd9309rJ8=
-github.com/gogf/gf/contrib/nosql/redis/v2 v2.4.3 h1:mDOAJJ3H6LSPdAR+0urO5S5WpglVFGuZTQx31L3o01Y=
-github.com/gogf/gf/contrib/nosql/redis/v2 v2.4.3/go.mod h1:t/9bT/mPQfoO4IhXTeGpPXooQ0STSoe/4ZspJLJoGug=
-github.com/gogf/gf/contrib/trace/jaeger/v2 v2.4.3 h1:yUNE2/LiACU36uFNeSEISwtWVyEQtFhRV0tVec8hOTU=
-github.com/gogf/gf/contrib/trace/jaeger/v2 v2.4.3/go.mod h1:Q/BRwWQUKKRbrr3blYV2M5ukNXJHlITJJLCw0RNfjss=
-github.com/gogf/gf/v2 v2.4.3 h1:OP91EICmypAEaEpwSyjFnAZtTfcmeKXJQnPP4FZR/BM=
-github.com/gogf/gf/v2 v2.4.3/go.mod h1:tsbmtwcAl2chcYoq/fP9W2FZf06aw4i89X34nbSHo9Y=
+github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.0 h1:HfZOhkqsOAH/zmVLn6Ay3WDAxEItEhVtGVVlIYghaLI=
+github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.0/go.mod h1:x5EfQfDMycTBfFHIGNUHU0ZIznHnPQP4adpxz3TByAM=
+github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.0 h1:1o/ynDWETKdWuS8tj8iKWods9c1pV/UC2dxFIG6W8z4=
+github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.0/go.mod h1:vOV5lfJOkQhf95J9dUqQ/cUzbMyDbljDitHetmEZOcg=
+github.com/gogf/gf/contrib/trace/jaeger/v2 v2.4.4 h1:c3Ra9uhi5YU73vGHE2d1GCTGci8BAhbmJxbF+dRPedo=
+github.com/gogf/gf/contrib/trace/jaeger/v2 v2.4.4/go.mod h1:gw64aC/Sa+N+qr5qsUZ0gCs6Ep9FEVEePa/6Xv59wf4=
+github.com/gogf/gf/v2 v2.4.4/go.mod h1:tsbmtwcAl2chcYoq/fP9W2FZf06aw4i89X34nbSHo9Y=
+github.com/gogf/gf/v2 v2.5.0 h1:dFZbIOq/3TmHNWTodSxHbAluuyh274hTvqoNe67pAbE=
+github.com/gogf/gf/v2 v2.5.0/go.mod h1:tsbmtwcAl2chcYoq/fP9W2FZf06aw4i89X34nbSHo9Y=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
@@ -330,6 +333,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU=
+github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -494,6 +499,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -527,13 +533,15 @@ golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
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.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
-golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
+golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
+golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
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=
@@ -549,6 +557,8 @@ golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMx
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
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/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=
@@ -568,6 +578,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
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.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=
@@ -609,8 +620,9 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
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.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
-golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
+golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
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=
@@ -628,6 +640,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -674,6 +687,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -686,13 +700,16 @@ golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -703,8 +720,9 @@ 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.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
+golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
@@ -755,6 +773,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.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
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=
diff --git a/server/internal/cmd/http.go b/server/internal/cmd/http.go
index c5f3e22..810d938 100644
--- a/server/internal/cmd/http.go
+++ b/server/internal/cmd/http.go
@@ -52,6 +52,7 @@ var (
service.Middleware().CORS, // 跨域中间件,自动处理跨域问题
service.Middleware().Blacklist, // IP黑名单中间件,如果请求IP被后台拉黑,所有请求将被拒绝
service.Middleware().DemoLimit, // 演示系統操作限制,当开启演示模式时,所有POST请求将被拒绝
+ service.Middleware().PreFilter, // 请求输入预处理,api使用gf规范路由并且XxxReq结构体实现了validate.Filter接口即可隐式预处理
service.Middleware().ResponseHandler, // HTTP响应预处理,在业务处理完成后,对响应结果进行格式化和错误过滤,将处理后的数据发送给请求方
)
diff --git a/server/internal/cmd/tools.go b/server/internal/cmd/tools.go
index 9131f4a..7f6dbbe 100644
--- a/server/internal/cmd/tools.go
+++ b/server/internal/cmd/tools.go
@@ -7,6 +7,7 @@ package cmd
import (
"context"
+ "github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcmd"
"hotgo/internal/library/casbin"
@@ -18,44 +19,50 @@ var (
Brief: "常用工具",
Description: ``,
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
- flags := parser.GetOptAll()
- g.Log().Debugf(ctx, "flags:%+v", flags)
- if len(flags) == 0 {
- g.Log().Fatal(ctx, "工具参数不能为空")
+ args := parser.GetOptAll()
+ g.Log().Debugf(ctx, "tools args:%v", args)
+ if len(args) == 0 {
+ err = gerror.New("tools args cannot be empty.")
return
}
- method, ok := flags["m"]
+ method, ok := args["m"]
if !ok {
- g.Log().Fatal(ctx, "工具方法不能为空")
+ err = gerror.New("tools method cannot be empty.")
return
}
switch method {
case "casbin":
- a1, ok := flags["a1"]
- if !ok {
- g.Log().Fatal(ctx, "casbin参数不能为空")
- return
- }
- casbin.InitEnforcer(ctx)
- if a1 == "clear" {
- if err := casbin.Clear(ctx); err != nil {
- return err
- }
- } else if a1 == "refresh" {
- if err := casbin.Refresh(ctx); err != nil {
- return err
- }
- } else {
- g.Log().Fatalf(ctx, "casbin参数无效,a1:%+v", a1)
- return
- }
+ err = handleCasbin(ctx, args)
default:
- g.Log().Fatal(ctx, "工具方法不存在")
+ err = gerror.Newf("tools method[%v] does not exist", method)
+ }
+
+ if err == nil {
+ g.Log().Info(ctx, "tools exec successful!")
}
- g.Log().Info(ctx, "执行完成!")
return
},
}
)
+
+// handleCasbin casbin.
+func handleCasbin(ctx context.Context, args map[string]string) (err error) {
+ a1, ok := args["a1"]
+ if !ok {
+ err = gerror.New("casbin args cannot be empty.")
+ return
+ }
+
+ casbin.InitEnforcer(ctx)
+ switch a1 {
+ case "clear":
+ err = casbin.Clear(ctx)
+ case "refresh":
+ err = casbin.Refresh(ctx)
+ default:
+ err = gerror.Newf("casbin a1 is invalid, a1:%v", a1)
+ }
+ return
+}
diff --git a/server/internal/consts/context.go b/server/internal/consts/context.go
index cbe59c4..149e283 100644
--- a/server/internal/consts/context.go
+++ b/server/internal/consts/context.go
@@ -11,5 +11,4 @@ type CtxKey string
const (
ContextHTTPKey CtxKey = "httpContext" // http上下文变量名称
ContextKeyCronArgs CtxKey = "cronArgs" // 定时任务参数上下文变量名称
- ContextTCPKey CtxKey = "tcpContext" // tcp上下文变量名称
)
diff --git a/server/internal/consts/debris.go b/server/internal/consts/debris.go
index f190a71..4f8eaf6 100644
--- a/server/internal/consts/debris.go
+++ b/server/internal/consts/debris.go
@@ -8,8 +8,16 @@ package consts
// 碎片
const (
- DemoTips = "演示系统已隐藏"
- NilJsonToString = "{}" // 空json初始化值
- RegionSpilt = " / " // 地区分隔符
- Unknown = "Unknown"
+ DemoTips = "演示系统已隐藏" // 演示系统敏感数据打码
+ NilJsonToString = "{}" // 空json初始化值
+ RegionSpilt = " / " // 地区分隔符
+ Unknown = "Unknown" // Unknown
+ SuperRoleKey = "super" // 超管角色唯一标识符,通过角色验证超管
+)
+
+// curd.
+const (
+ DefaultPage = 10 // 默认列表分页加载数量
+ DefaultPageSize = 1 // 默认列表分页加载页码
+ MaxSortIncr = 10 // 最大排序值增量
)
diff --git a/server/internal/consts/servelicense.go b/server/internal/consts/servelicense.go
new file mode 100644
index 0000000..5d938c0
--- /dev/null
+++ b/server/internal/consts/servelicense.go
@@ -0,0 +1,14 @@
+package consts
+
+// 授权分组
+const (
+ LicenseGroupDefault = "default" // 默认组
+ LicenseGroupCron = "cron" // 定时任务
+ LicenseGroupAuth = "auth" // 服务授权
+)
+
+var LicenseGroupNameMap = map[string]string{
+ LicenseGroupDefault: "默认组",
+ LicenseGroupCron: "定时任务",
+ LicenseGroupAuth: "服务授权",
+}
diff --git a/server/internal/consts/tcp.go b/server/internal/consts/tcp.go
deleted file mode 100644
index e6a1347..0000000
--- a/server/internal/consts/tcp.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package consts
-
-const (
- TCPMsgCodeSuccess = 2000 // 成功的状态码
-)
-
-// 定时任务
-const (
- TCPCronHeartbeatVerify = "tcpHeartbeatVerify"
- TCPCronHeartbeat = "tcpHeartbeat"
- TCPCronAuthVerify = "tcpAuthVerify"
-)
-
-// 认证分组
-const (
- TCPClientGroupCron = "cron" // 定时任务
- TCPClientGroupQueue = "queue" // 消息队列
- TCPClientGroupAuth = "auth" // 服务授权
-)
-
-const (
- TCPHeartbeatTimeout = 300 // tcp心跳超时,默认300s
- TCPRpcTimeout = 10 // rpc通讯超时时间, 默认10s
-)
diff --git a/server/internal/consts/upload.go b/server/internal/consts/upload.go
index cbf2926..1b28c96 100644
--- a/server/internal/consts/upload.go
+++ b/server/internal/consts/upload.go
@@ -5,15 +5,6 @@
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package consts
-// 上传类型
-const (
- UploadTypeFile = 1 // 文件
- UploadTypeImage = 2 // 图片
- UploadTypeDoc = 3 // 文档
- UploadTypeAudio = 4 // 音频
- UploadTypeVideo = 5 // 视频
-)
-
// 上传存储驱动
const (
UploadDriveLocal = "local" // 本地驱动
diff --git a/server/internal/consts/version.go b/server/internal/consts/version.go
index a7fdab5..b67e421 100644
--- a/server/internal/consts/version.go
+++ b/server/internal/consts/version.go
@@ -7,5 +7,5 @@ package consts
// VersionApp HotGo版本
const (
- VersionApp = "2.7.6"
+ VersionApp = "2.8.4"
)
diff --git a/server/internal/controller/admin/admin/cash.go b/server/internal/controller/admin/admin/cash.go
index 126f4c7..124b034 100644
--- a/server/internal/controller/admin/admin/cash.go
+++ b/server/internal/controller/admin/admin/cash.go
@@ -7,11 +7,9 @@ package admin
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/cash"
"hotgo/internal/library/contexts"
"hotgo/internal/model/input/adminin"
- "hotgo/internal/model/input/form"
"hotgo/internal/service"
)
@@ -23,7 +21,7 @@ type cCash struct{}
// View 获取指定信息
func (c *cCash) View(ctx context.Context, req *cash.ViewReq) (res *cash.ViewRes, err error) {
- data, err := service.AdminCash().View(ctx, adminin.CashViewInp{Id: req.Id})
+ data, err := service.AdminCash().View(ctx, &req.CashViewInp)
if err != nil {
return
}
@@ -35,27 +33,20 @@ func (c *cCash) View(ctx context.Context, req *cash.ViewReq) (res *cash.ViewRes,
// List 查看列表
func (c *cCash) List(ctx context.Context, req *cash.ListReq) (res *cash.ListRes, err error) {
- var in adminin.CashListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.AdminCash().List(ctx, in)
+ list, totalCount, err := service.AdminCash().List(ctx, &req.CashListInp)
if err != nil {
return
}
res = new(cash.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Apply 申请提现
func (c *cCash) Apply(ctx context.Context, req *cash.ApplyReq) (res *cash.ApplyRes, err error) {
- err = service.AdminCash().Apply(ctx, adminin.CashApplyInp{
+ err = service.AdminCash().Apply(ctx, &adminin.CashApplyInp{
Money: req.Money,
MemberId: contexts.GetUserId(ctx),
})
@@ -64,10 +55,6 @@ func (c *cCash) Apply(ctx context.Context, req *cash.ApplyReq) (res *cash.ApplyR
// Payment 提现打款处理
func (c *cCash) Payment(ctx context.Context, req *cash.PaymentReq) (res *cash.PaymentRes, err error) {
- err = service.AdminCash().Payment(ctx, adminin.CashPaymentInp{
- Id: req.Id,
- Status: req.Status,
- Msg: req.Msg,
- })
+ err = service.AdminCash().Payment(ctx, &req.CashPaymentInp)
return
}
diff --git a/server/internal/controller/admin/admin/credits_log.go b/server/internal/controller/admin/admin/credits_log.go
index ad07a99..6997078 100644
--- a/server/internal/controller/admin/admin/credits_log.go
+++ b/server/internal/controller/admin/admin/credits_log.go
@@ -11,12 +11,7 @@ import (
"context"
"hotgo/api/admin/creditslog"
"hotgo/internal/consts"
- "hotgo/internal/model/input/adminin"
- "hotgo/internal/model/input/form"
"hotgo/internal/service"
- "hotgo/utility/validate"
-
- "github.com/gogf/gf/v2/util/gconv"
)
var (
@@ -27,40 +22,20 @@ type cCreditsLog struct{}
// List 查看资产变动列表
func (c *cCreditsLog) List(ctx context.Context, req *creditslog.ListReq) (res *creditslog.ListRes, err error) {
- var in adminin.CreditsLogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.AdminCreditsLog().List(ctx, in)
+ list, totalCount, err := service.AdminCreditsLog().List(ctx, &req.CreditsLogListInp)
if err != nil {
return
}
res = new(creditslog.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Export 导出资产变动列表
func (c *cCreditsLog) Export(ctx context.Context, req *creditslog.ExportReq) (res *creditslog.ExportRes, err error) {
- var in adminin.CreditsLogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminCreditsLog().Export(ctx, in)
+ err = service.AdminCreditsLog().Export(ctx, &req.CreditsLogListInp)
return
}
diff --git a/server/internal/controller/admin/admin/dept.go b/server/internal/controller/admin/admin/dept.go
index ed7f1e5..ea30cc8 100644
--- a/server/internal/controller/admin/admin/dept.go
+++ b/server/internal/controller/admin/admin/dept.go
@@ -7,12 +7,8 @@ package admin
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/dept"
- "hotgo/internal/model/input/adminin"
- "hotgo/internal/model/input/form"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -23,33 +19,19 @@ type cDept struct{}
// Delete 删除
func (c *cDept) Delete(ctx context.Context, req *dept.DeleteReq) (res *dept.DeleteRes, err error) {
- var in adminin.DeptDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminDept().Delete(ctx, in)
+ err = service.AdminDept().Delete(ctx, &req.DeptDeleteInp)
return
}
// Edit 更新
func (c *cDept) Edit(ctx context.Context, req *dept.EditReq) (res *dept.EditRes, err error) {
- var in adminin.DeptEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminDept().Edit(ctx, in)
+ err = service.AdminDept().Edit(ctx, &req.DeptEditInp)
return
}
// MaxSort 最大排序
func (c *cDept) MaxSort(ctx context.Context, req *dept.MaxSortReq) (res *dept.MaxSortRes, err error) {
- data, err := service.AdminDept().MaxSort(ctx, adminin.DeptMaxSortInp{Id: req.Id})
+ data, err := service.AdminDept().MaxSort(ctx, &req.DeptMaxSortInp)
if err != nil {
return
}
@@ -61,64 +43,37 @@ func (c *cDept) MaxSort(ctx context.Context, req *dept.MaxSortReq) (res *dept.Ma
// View 获取指定信息
func (c *cDept) View(ctx context.Context, req *dept.ViewReq) (res *dept.ViewRes, err error) {
- data, err := service.AdminDept().View(ctx, adminin.DeptViewInp{Id: req.Id})
- if err != nil {
- return
- }
-
res = new(dept.ViewRes)
- res.DeptViewModel = data
+ res.DeptViewModel, err = service.AdminDept().View(ctx, &req.DeptViewInp)
return
}
// List 查看列表
func (c *cDept) List(ctx context.Context, req *dept.ListReq) (res *dept.ListRes, err error) {
- var in adminin.DeptListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- data, err := service.AdminDept().List(ctx, in)
+ data, err := service.AdminDept().List(ctx, &req.DeptListInp)
if err != nil || data == nil {
return
}
- res = new(dept.ListRes)
- res.List = data.List
+ res = (*dept.ListRes)(&data)
return
}
// Status 更新部门状态
func (c *cDept) Status(ctx context.Context, req *dept.StatusReq) (res *dept.StatusRes, err error) {
- var in adminin.DeptStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminDept().Status(ctx, in)
+ err = service.AdminDept().Status(ctx, &req.DeptStatusInp)
return
}
// Option 获取部门选项树
func (c *cDept) Option(ctx context.Context, req *dept.OptionReq) (res *dept.OptionRes, err error) {
- var in adminin.DeptOptionInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.AdminDept().Option(ctx, in)
+ list, totalCount, err := service.AdminDept().Option(ctx, &req.DeptOptionInp)
if err != nil {
return
}
res = new(dept.OptionRes)
res.DeptOptionModel = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
diff --git a/server/internal/controller/admin/admin/member.go b/server/internal/controller/admin/admin/member.go
index 8d7a1e9..6724e58 100644
--- a/server/internal/controller/admin/admin/member.go
+++ b/server/internal/controller/admin/admin/member.go
@@ -8,13 +8,10 @@ package admin
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/member"
"hotgo/internal/library/contexts"
"hotgo/internal/model/input/adminin"
- "hotgo/internal/model/input/form"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -25,45 +22,25 @@ type cMember struct{}
// UpdateCash 修改代理商提现信息
func (c *cMember) UpdateCash(ctx context.Context, req *member.UpdateCashReq) (res *member.UpdateCashRes, err error) {
- var in adminin.MemberUpdateCashInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminMember().UpdateCash(ctx, in)
+ err = service.AdminMember().UpdateCash(ctx, &req.MemberUpdateCashInp)
return
}
// UpdateEmail 换绑邮箱
func (c *cMember) UpdateEmail(ctx context.Context, req *member.UpdateEmailReq) (res *member.UpdateEmailRes, err error) {
- var in adminin.MemberUpdateEmailInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminMember().UpdateEmail(ctx, in)
+ err = service.AdminMember().UpdateEmail(ctx, &req.MemberUpdateEmailInp)
return
}
// UpdateMobile 换绑手机号
func (c *cMember) UpdateMobile(ctx context.Context, req *member.UpdateMobileReq) (res *member.UpdateMobileRes, err error) {
- var in adminin.MemberUpdateMobileInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminMember().UpdateMobile(ctx, in)
+ err = service.AdminMember().UpdateMobile(ctx, &req.MemberUpdateMobileInp)
return
}
// UpdateProfile 更新用户资料
func (c *cMember) UpdateProfile(ctx context.Context, req *member.UpdateProfileReq) (res *member.UpdateProfileRes, err error) {
- var in adminin.MemberUpdateProfileInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminMember().UpdateProfile(ctx, in)
+ err = service.AdminMember().UpdateProfile(ctx, &req.MemberUpdateProfileInp)
return
}
@@ -72,27 +49,20 @@ func (c *cMember) UpdatePwd(ctx context.Context, req *member.UpdatePwdReq) (res
var memberId = contexts.Get(ctx).User.Id
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
- return nil, err
+ return
}
- var in = adminin.MemberUpdatePwdInp{
+ err = service.AdminMember().UpdatePwd(ctx, &adminin.MemberUpdatePwdInp{
Id: memberId,
OldPassword: req.OldPassword,
NewPassword: req.NewPassword,
- }
-
- err = service.AdminMember().UpdatePwd(ctx, in)
+ })
return
}
// ResetPwd 重置密码
func (c *cMember) ResetPwd(ctx context.Context, req *member.ResetPwdReq) (res *member.ResetPwdRes, err error) {
- var in = adminin.MemberResetPwdInp{
- Id: req.Id,
- Password: req.Password,
- }
-
- err = service.AdminMember().ResetPwd(ctx, in)
+ err = service.AdminMember().ResetPwd(ctx, &req.MemberResetPwdInp)
return
}
@@ -108,40 +78,21 @@ func (c *cMember) MemberInfo(ctx context.Context, _ *member.InfoReq) (res *membe
return
}
-// Delete 删除
+// Delete 删除用户
func (c *cMember) Delete(ctx context.Context, req *member.DeleteReq) (res *member.DeleteRes, err error) {
- var in adminin.MemberDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminMember().Delete(ctx, in)
+ err = service.AdminMember().Delete(ctx, &req.MemberDeleteInp)
return
}
-// Edit 修改/新增
+// Edit 修改/新增用户
func (c *cMember) Edit(ctx context.Context, req *member.EditReq) (res *member.EditRes, err error) {
- var in adminin.MemberEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- in.PostIds = req.PostIds
- err = service.AdminMember().Edit(ctx, in)
+ err = service.AdminMember().Edit(ctx, &req.MemberEditInp)
return
}
-// View 获取指定信息
+// View 获取指定用户信息
func (c *cMember) View(ctx context.Context, req *member.ViewReq) (res *member.ViewRes, err error) {
- data, err := service.AdminMember().View(ctx, adminin.MemberViewInp{Id: req.Id})
+ data, err := service.AdminMember().View(ctx, &req.MemberViewInp)
if err != nil {
return
}
@@ -151,44 +102,28 @@ func (c *cMember) View(ctx context.Context, req *member.ViewReq) (res *member.Vi
return
}
-// List 查看列表
+// List 查看用户列表
func (c *cMember) List(ctx context.Context, req *member.ListReq) (res *member.ListRes, err error) {
- var in adminin.MemberListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.AdminMember().List(ctx, in)
+ list, totalCount, err := service.AdminMember().List(ctx, &req.MemberListInp)
if err != nil {
return
}
res = new(member.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
-// Status 更新状态
+// Status 更新用户状态
func (c *cMember) Status(ctx context.Context, req *member.StatusReq) (res *member.StatusRes, err error) {
- var in adminin.MemberStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminMember().Status(ctx, in)
+ err = service.AdminMember().Status(ctx, &req.MemberStatusInp)
return
}
// Select 获取可选的后台用户选项
-func (c *cMember) Select(ctx context.Context, _ *member.SelectReq) (res *member.SelectRes, err error) {
- data, err := service.AdminMember().Select(ctx, adminin.MemberSelectInp{})
+func (c *cMember) Select(ctx context.Context, req *member.SelectReq) (res *member.SelectRes, err error) {
+ data, err := service.AdminMember().Select(ctx, &req.MemberSelectInp)
if err != nil {
return
}
@@ -197,32 +132,14 @@ func (c *cMember) Select(ctx context.Context, _ *member.SelectReq) (res *member.
return
}
-// AddBalance 增加余额
+// AddBalance 增加用户余额
func (c *cMember) AddBalance(ctx context.Context, req *member.AddBalanceReq) (res *member.AddBalanceRes, err error) {
- var in adminin.MemberAddBalanceInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminMember().AddBalance(ctx, in)
+ err = service.AdminMember().AddBalance(ctx, &req.MemberAddBalanceInp)
return
}
-// AddIntegral 增加积分
+// AddIntegral 增加用户积分
func (c *cMember) AddIntegral(ctx context.Context, req *member.AddIntegralReq) (res *member.AddIntegralRes, err error) {
- var in adminin.MemberAddIntegralInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminMember().AddIntegral(ctx, in)
+ err = service.AdminMember().AddIntegral(ctx, &req.MemberAddIntegralInp)
return
}
diff --git a/server/internal/controller/admin/admin/menu.go b/server/internal/controller/admin/admin/menu.go
index 6907e59..3bd2de5 100644
--- a/server/internal/controller/admin/admin/menu.go
+++ b/server/internal/controller/admin/admin/menu.go
@@ -7,11 +7,8 @@ package admin
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/menu"
- "hotgo/internal/model/input/adminin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
// Menu 菜单
@@ -23,45 +20,18 @@ type cMenu struct{}
// Delete 删除
func (c *cMenu) Delete(ctx context.Context, req *menu.DeleteReq) (res *menu.DeleteRes, err error) {
- var in adminin.MenuDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminMenu().Delete(ctx, in)
+ err = service.AdminMenu().Delete(ctx, &req.MenuDeleteInp)
return
}
// Edit 更新
func (c *cMenu) Edit(ctx context.Context, req *menu.EditReq) (res *menu.EditRes, err error) {
- var in adminin.MenuEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminMenu().Edit(ctx, in)
+ err = service.AdminMenu().Edit(ctx, &req.MenuEditInp)
return
}
// List 获取列表
func (c *cMenu) List(ctx context.Context, req *menu.ListReq) (res menu.ListRes, err error) {
- var in adminin.MenuListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- res.MenuListModel, err = service.AdminMenu().List(ctx, in)
+ res.MenuListModel, err = service.AdminMenu().List(ctx, &req.MenuListInp)
return
}
diff --git a/server/internal/controller/admin/admin/monitor.go b/server/internal/controller/admin/admin/monitor.go
index ac68e6a..1d5cc81 100644
--- a/server/internal/controller/admin/admin/monitor.go
+++ b/server/internal/controller/admin/admin/monitor.go
@@ -13,7 +13,10 @@ import (
"github.com/gogf/gf/v2/text/gstr"
"hotgo/api/admin/monitor"
"hotgo/internal/consts"
+ "hotgo/internal/dao"
+ "hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
+ "hotgo/internal/service"
"hotgo/internal/websocket"
"hotgo/utility/simple"
"hotgo/utility/useragent"
@@ -29,8 +32,8 @@ type cMonitor struct {
wsManager *websocket.ClientManager
}
-// Offline 下线用户
-func (c *cMonitor) Offline(ctx context.Context, req *monitor.OfflineReq) (res *monitor.OfflineRes, err error) {
+// UserOffline 下线用户
+func (c *cMonitor) UserOffline(ctx context.Context, req *monitor.UserOfflineReq) (res *monitor.UserOfflineRes, err error) {
client := c.wsManager.GetClient(req.Id)
if client == nil {
err = gerror.New("客户端已离线")
@@ -44,15 +47,10 @@ func (c *cMonitor) Offline(ctx context.Context, req *monitor.OfflineReq) (res *m
return
}
-// View 获取指定信息
-func (c *cMonitor) View(ctx context.Context, req *monitor.OnlineViewReq) (res *monitor.OnlineViewRes, err error) {
- return
-}
-
-// OnlineList 获取在线列表
-func (c *cMonitor) OnlineList(ctx context.Context, req *monitor.OnlineListReq) (res *monitor.OnlineListRes, err error) {
+// UserOnlineList 获取用户在线列表
+func (c *cMonitor) UserOnlineList(ctx context.Context, req *monitor.UserOnlineListReq) (res *monitor.UserOnlineListRes, err error) {
var (
- clients []*monitor.OnlineModel
+ clients []*monitor.UserOnlineModel
i int
)
@@ -69,16 +67,24 @@ func (c *cMonitor) OnlineList(ctx context.Context, req *monitor.OnlineListReq) (
continue
}
+ if req.Username != "" && req.Username != conn.User.Username {
+ continue
+ }
+
if req.Addr != "" && !gstr.Contains(conn.Addr, req.Addr) {
continue
}
- clients = append(clients, &monitor.OnlineModel{
+ if len(req.FirstTime) == 2 && (conn.User.LoginAt.Before(req.FirstTime[0]) || conn.User.LoginAt.After(req.FirstTime[1])) {
+ continue
+ }
+
+ clients = append(clients, &monitor.UserOnlineModel{
ID: conn.ID,
Addr: conn.Addr,
Os: useragent.GetOs(conn.UserAgent),
Browser: useragent.GetBrowser(conn.UserAgent),
- FirstTime: gtime.New(conn.User.LoginAt).Unix(),
+ FirstTime: conn.User.LoginAt.Unix(),
HeartbeatTime: conn.HeartbeatTime,
App: conn.User.App,
UserId: conn.User.Id,
@@ -87,14 +93,18 @@ func (c *cMonitor) OnlineList(ctx context.Context, req *monitor.OnlineListReq) (
})
}
- res = new(monitor.OnlineListRes)
- res.PageCount = form.CalPageCount(len(clients), req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res = new(monitor.UserOnlineListRes)
+ res.PageRes.Pack(req, len(clients))
+
+ sort.Slice(clients, func(i, j int) bool {
+ if clients[i].FirstTime == clients[j].FirstTime {
+ return clients[i].ID < clients[j].ID
+ }
+ return clients[i].FirstTime < clients[j].FirstTime
+ })
- sort.Sort(monitor.OnlineModels(clients))
isDemo := g.Cfg().MustGet(ctx, "hotgo.isDemo", false).Bool()
- _, perPage, offset := form.CalPage(ctx, req.Page, req.PerPage)
+ _, perPage, offset := form.CalPage(req.Page, req.PerPage)
for k, v := range clients {
if k >= offset && i <= perPage {
@@ -107,3 +117,138 @@ func (c *cMonitor) OnlineList(ctx context.Context, req *monitor.OnlineListReq) (
}
return
}
+
+// NetOnlineList 获取服务在线列表
+func (c *cMonitor) NetOnlineList(ctx context.Context, req *monitor.NetOnlineListReq) (res *monitor.NetOnlineListRes, err error) {
+ var (
+ clients []*monitor.NetOnlineModel
+ i int
+ cols = dao.SysServeLicense.Columns()
+ serv = service.TCPServer().Instance()
+ models *entity.SysServeLicense
+ )
+
+ conns := serv.GetClients()
+ if len(conns) == 0 {
+ return
+ }
+
+ for _, conn := range conns {
+ v := &monitor.NetOnlineModel{
+ AuthMeta: conn.Auth,
+ Id: conn.CID,
+ IsAuth: conn.Auth != nil,
+ Addr: conn.RemoteAddr().String(),
+ Port: gstr.SubStrFromEx(conn.LocalAddr().String(), `:`),
+ FirstTime: conn.FirstTime,
+ HeartbeatTime: conn.Heartbeat,
+ Proto: "TCP",
+ }
+
+ if v.IsAuth {
+ if err = dao.SysServeLicense.Ctx(ctx).Where(cols.Appid, conn.Auth.AppId).Where(cols.Group, conn.Auth.Group).Scan(&models); err != nil {
+ return
+ }
+
+ if models == nil {
+ continue
+ }
+
+ v.LicenseId = models.Id
+ v.LicenseName = models.Name
+ v.LoginTimes = models.LoginTimes
+ v.Online = serv.GetAppIdOnline(models.Appid)
+ v.OnlineLimit = models.OnlineLimit
+ }
+
+ if req.Addr != "" && !gstr.Contains(v.Addr, req.Addr) {
+ continue
+ }
+
+ if req.Name != "" && !gstr.Contains(v.Name, req.Name) {
+ continue
+ }
+
+ if req.Group != "" && (!v.IsAuth || v.Group != req.Group) {
+ continue
+ }
+
+ if req.AppId != "" && (!v.IsAuth || v.AppId != req.AppId) {
+ continue
+ }
+
+ ft := gtime.New(conn.FirstTime)
+ if len(req.FirstTime) == 2 && (ft.Before(req.FirstTime[0]) || ft.After(req.FirstTime[1])) {
+ continue
+ }
+ clients = append(clients, v)
+ }
+
+ res = new(monitor.NetOnlineListRes)
+ res.PageRes.Pack(req, len(clients))
+
+ sort.Slice(clients, func(i, j int) bool {
+ return clients[i].Id > clients[j].Id
+ })
+
+ _, perPage, offset := form.CalPage(req.Page, req.PerPage)
+ for k, v := range clients {
+ if k >= offset && i <= perPage {
+ res.List = append(res.List, v)
+ i++
+ }
+ }
+ return
+}
+
+// NetOption 获取服务选项
+func (c *cMonitor) NetOption(ctx context.Context, req *monitor.NetOptionReq) (res *monitor.NetOptionRes, err error) {
+ res = new(monitor.NetOptionRes)
+
+ // 授权分组
+ for k, v := range consts.LicenseGroupNameMap {
+ res.LicenseGroup = append(res.LicenseGroup, &form.Select{
+ Value: k,
+ Name: v,
+ Label: v,
+ })
+ }
+ sort.Sort(res.LicenseGroup)
+
+ for _, v := range service.TCPServer().Instance().GetRoutes() {
+ // 无需勾选的路由
+ disabled := false
+ if v.Id == "ServerLoginReq" || v.Id == "ServerHeartbeatReq" {
+ disabled = true
+ }
+
+ res.Routes = append(res.Routes, &monitor.RouteSelect{
+ Value: v.Id,
+ Label: v.Id,
+ Disabled: disabled,
+ IsRPC: v.IsRPC,
+ })
+ }
+
+ sort.Slice(res.Routes, func(i, j int) bool {
+ if res.Routes[i].IsRPC && !res.Routes[j].IsRPC {
+ return true
+ } else if !res.Routes[i].IsRPC && res.Routes[j].IsRPC {
+ return false
+ }
+ return res.Routes[i].Label < res.Routes[j].Label
+ })
+ return
+}
+
+// NetOffline 下线服务
+func (c *cMonitor) NetOffline(ctx context.Context, req *monitor.NetOfflineReq) (res *monitor.NetOfflineRes, err error) {
+ conn := service.TCPServer().Instance().GetClientById(req.Id)
+ if conn == nil {
+ err = gerror.New("客户端不在线")
+ return
+ }
+ // 关闭连接
+ conn.Close()
+ return
+}
diff --git a/server/internal/controller/admin/admin/notice.go b/server/internal/controller/admin/admin/notice.go
index ce1914f..f3d7f03 100644
--- a/server/internal/controller/admin/admin/notice.go
+++ b/server/internal/controller/admin/admin/notice.go
@@ -3,16 +3,12 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package admin
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/notice"
"hotgo/internal/consts"
- "hotgo/internal/model/input/adminin"
- "hotgo/internal/model/input/form"
"hotgo/internal/service"
)
@@ -24,30 +20,19 @@ type cNotice struct{}
// Delete 删除
func (c *cNotice) Delete(ctx context.Context, req *notice.DeleteReq) (res *notice.DeleteRes, err error) {
- var in adminin.NoticeDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminNotice().Delete(ctx, in)
+ err = service.AdminNotice().Delete(ctx, &req.NoticeDeleteInp)
return
}
// Edit 更新
func (c *cNotice) Edit(ctx context.Context, req *notice.EditReq) (res *notice.EditRes, err error) {
- var in adminin.NoticeEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- in.Receiver = req.Receiver
- err = service.AdminNotice().Edit(ctx, in)
+ err = service.AdminNotice().Edit(ctx, &req.NoticeEditInp)
return
}
// MaxSort 最大排序
func (c *cNotice) MaxSort(ctx context.Context, req *notice.MaxSortReq) (res *notice.MaxSortRes, err error) {
- data, err := service.AdminNotice().MaxSort(ctx, adminin.NoticeMaxSortInp{Id: req.Id})
+ data, err := service.AdminNotice().MaxSort(ctx, &req.NoticeMaxSortInp)
if err != nil {
return
}
@@ -59,7 +44,7 @@ func (c *cNotice) MaxSort(ctx context.Context, req *notice.MaxSortReq) (res *not
// View 获取指定信息
func (c *cNotice) View(ctx context.Context, req *notice.ViewReq) (res *notice.ViewRes, err error) {
- data, err := service.AdminNotice().View(ctx, adminin.NoticeViewInp{Id: req.Id})
+ data, err := service.AdminNotice().View(ctx, &req.NoticeViewInp)
if err != nil {
return
}
@@ -71,97 +56,53 @@ func (c *cNotice) View(ctx context.Context, req *notice.ViewReq) (res *notice.Vi
// List 查看列表
func (c *cNotice) List(ctx context.Context, req *notice.ListReq) (res *notice.ListRes, err error) {
- var in adminin.NoticeListInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- list, totalCount, err := service.AdminNotice().List(ctx, in)
+ list, totalCount, err := service.AdminNotice().List(ctx, &req.NoticeListInp)
if err != nil {
return nil, err
}
res = new(notice.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
-// Status 更新部门状态
+// Status 更新状态
func (c *cNotice) Status(ctx context.Context, req *notice.StatusReq) (res *notice.StatusRes, err error) {
- var in adminin.NoticeStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- err = service.AdminNotice().Status(ctx, in)
+ err = service.AdminNotice().Status(ctx, &req.NoticeStatusInp)
return
}
// Notify 更新通知
func (c *cNotice) Notify(ctx context.Context, req *notice.EditNotifyReq) (res *notice.EditNotifyRes, err error) {
- var in adminin.NoticeEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- in.Type = consts.NoticeTypeNotify
- in.Receiver = req.Receiver
- err = service.AdminNotice().Edit(ctx, in)
+ req.Type = consts.NoticeTypeNotify
+ err = service.AdminNotice().Edit(ctx, &req.NoticeEditInp)
return
}
// Notice 更新公告
func (c *cNotice) Notice(ctx context.Context, req *notice.EditNoticeReq) (res *notice.EditNoticeRes, err error) {
- var in adminin.NoticeEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- in.Type = consts.NoticeTypeNotice
- in.Receiver = req.Receiver
- err = service.AdminNotice().Edit(ctx, in)
+ req.Type = consts.NoticeTypeNotice
+ err = service.AdminNotice().Edit(ctx, &req.NoticeEditInp)
return
}
// Letter 更新私信
func (c *cNotice) Letter(ctx context.Context, req *notice.EditLetterReq) (res *notice.EditLetterRes, err error) {
- var in adminin.NoticeEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- in.Type = consts.NoticeTypeLetter
- in.Receiver = req.Receiver
- err = service.AdminNotice().Edit(ctx, in)
+ req.Type = consts.NoticeTypeLetter
+ err = service.AdminNotice().Edit(ctx, &req.NoticeEditInp)
return
}
// UpRead 更新已读
func (c *cNotice) UpRead(ctx context.Context, req *notice.UpReadReq) (res *notice.UpReadRes, err error) {
- var in adminin.NoticeUpReadInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminNotice().UpRead(ctx, in)
+ err = service.AdminNotice().UpRead(ctx, &req.NoticeUpReadInp)
return
}
// PullMessages 拉取未读消息列表
func (c *cNotice) PullMessages(ctx context.Context, req *notice.PullMessagesReq) (res *notice.PullMessagesRes, err error) {
- var in adminin.PullMessagesInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if in.Limit == 0 {
- in.Limit = 100
- }
-
- data, err := service.AdminNotice().PullMessages(ctx, in)
+ data, err := service.AdminNotice().PullMessages(ctx, &req.PullMessagesInp)
if err != nil {
return
}
@@ -173,31 +114,19 @@ func (c *cNotice) PullMessages(ctx context.Context, req *notice.PullMessagesReq)
// ReadAll 全部已读
func (c *cNotice) ReadAll(ctx context.Context, req *notice.ReadAllReq) (res *notice.ReadAllRes, err error) {
- var in adminin.NoticeReadAllInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminNotice().ReadAll(ctx, in)
+ err = service.AdminNotice().ReadAll(ctx, &req.NoticeReadAllInp)
return
}
// MessageList 我的消息列表
func (c *cNotice) MessageList(ctx context.Context, req *notice.MessageListReq) (res *notice.MessageListRes, err error) {
- var in adminin.NoticeMessageListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.AdminNotice().MessageList(ctx, in)
+ list, totalCount, err := service.AdminNotice().MessageList(ctx, &req.NoticeMessageListInp)
if err != nil {
return
}
res = new(notice.MessageListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
diff --git a/server/internal/controller/admin/admin/order.go b/server/internal/controller/admin/admin/order.go
index 4d75bb7..3e7b444 100644
--- a/server/internal/controller/admin/admin/order.go
+++ b/server/internal/controller/admin/admin/order.go
@@ -9,12 +9,7 @@ import (
"context"
"hotgo/api/admin/order"
"hotgo/internal/consts"
- "hotgo/internal/model/input/adminin"
- "hotgo/internal/model/input/form"
"hotgo/internal/service"
- "hotgo/utility/validate"
-
- "github.com/gogf/gf/v2/util/gconv"
)
var (
@@ -25,31 +20,13 @@ type cOrder struct{}
// AcceptRefund 受理申请退款
func (c *cOrder) AcceptRefund(ctx context.Context, req *order.AcceptRefundReq) (res *order.AcceptRefundRes, err error) {
- var in adminin.OrderAcceptRefundInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminOrder().AcceptRefund(ctx, in)
+ err = service.AdminOrder().AcceptRefund(ctx, &req.OrderAcceptRefundInp)
return
}
// ApplyRefund 申请退款
func (c *cOrder) ApplyRefund(ctx context.Context, req *order.ApplyRefundReq) (res *order.ApplyRefundRes, err error) {
- var in adminin.OrderApplyRefundInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminOrder().ApplyRefund(ctx, in)
+ err = service.AdminOrder().ApplyRefund(ctx, &req.OrderApplyRefundInp)
return
}
@@ -65,16 +42,7 @@ func (c *cOrder) Option(ctx context.Context, req *order.OptionReq) (res *order.O
// Create 创建充值订单
func (c *cOrder) Create(ctx context.Context, req *order.CreateReq) (res *order.CreateRes, err error) {
- var in adminin.OrderCreateInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- data, err := service.AdminOrder().Create(ctx, in)
+ data, err := service.AdminOrder().Create(ctx, &req.OrderCreateInp)
if err != nil {
return
}
@@ -86,70 +54,32 @@ func (c *cOrder) Create(ctx context.Context, req *order.CreateReq) (res *order.C
// List 查看充值订单列表
func (c *cOrder) List(ctx context.Context, req *order.ListReq) (res *order.ListRes, err error) {
- var in adminin.OrderListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.AdminOrder().List(ctx, in)
+ list, totalCount, err := service.AdminOrder().List(ctx, &req.OrderListInp)
if err != nil {
return
}
res = new(order.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Export 导出充值订单列表
func (c *cOrder) Export(ctx context.Context, req *order.ExportReq) (res *order.ExportRes, err error) {
- var in adminin.OrderListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminOrder().Export(ctx, in)
+ err = service.AdminOrder().Export(ctx, &req.OrderListInp)
return
}
// Edit 更新充值订单
func (c *cOrder) Edit(ctx context.Context, req *order.EditReq) (res *order.EditRes, err error) {
- var in adminin.OrderEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminOrder().Edit(ctx, in)
+ err = service.AdminOrder().Edit(ctx, &req.OrderEditInp)
return
}
// View 获取指定充值订单信息
func (c *cOrder) View(ctx context.Context, req *order.ViewReq) (res *order.ViewRes, err error) {
- var in adminin.OrderViewInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- data, err := service.AdminOrder().View(ctx, in)
+ data, err := service.AdminOrder().View(ctx, &req.OrderViewInp)
if err != nil {
return
}
@@ -161,30 +91,12 @@ func (c *cOrder) View(ctx context.Context, req *order.ViewReq) (res *order.ViewR
// Delete 删除充值订单
func (c *cOrder) Delete(ctx context.Context, req *order.DeleteReq) (res *order.DeleteRes, err error) {
- var in adminin.OrderDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminOrder().Delete(ctx, in)
+ err = service.AdminOrder().Delete(ctx, &req.OrderDeleteInp)
return
}
// Status 更新充值订单状态
func (c *cOrder) Status(ctx context.Context, req *order.StatusReq) (res *order.StatusRes, err error) {
- var in adminin.OrderStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminOrder().Status(ctx, in)
+ err = service.AdminOrder().Status(ctx, &req.OrderStatusInp)
return
}
diff --git a/server/internal/controller/admin/admin/post.go b/server/internal/controller/admin/admin/post.go
index 74c230b..d199b11 100644
--- a/server/internal/controller/admin/admin/post.go
+++ b/server/internal/controller/admin/admin/post.go
@@ -7,10 +7,7 @@ package admin
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/post"
- "hotgo/internal/model/input/adminin"
- "hotgo/internal/model/input/form"
"hotgo/internal/service"
)
@@ -21,29 +18,19 @@ type cPost struct{}
// Delete 删除
func (c *cPost) Delete(ctx context.Context, req *post.DeleteReq) (res *post.DeleteRes, err error) {
- var in adminin.PostDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminPost().Delete(ctx, in)
+ err = service.AdminPost().Delete(ctx, &req.PostDeleteInp)
return
}
// Edit 修改/新增
func (c *cPost) Edit(ctx context.Context, req *post.EditReq) (res *post.EditRes, err error) {
- var in adminin.PostEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminPost().Edit(ctx, in)
+ err = service.AdminPost().Edit(ctx, &req.PostEditInp)
return
}
// MaxSort 最大排序
func (c *cPost) MaxSort(ctx context.Context, req *post.MaxSortReq) (res *post.MaxSortRes, err error) {
- data, err := service.AdminPost().MaxSort(ctx, adminin.PostMaxSortInp{Id: req.Id})
+ data, err := service.AdminPost().MaxSort(ctx, &req.PostMaxSortInp)
if err != nil {
return
}
@@ -53,33 +40,9 @@ func (c *cPost) MaxSort(ctx context.Context, req *post.MaxSortReq) (res *post.Ma
return
}
-// NameUnique 名称是否唯一
-func (c *cPost) NameUnique(ctx context.Context, req *post.NameUniqueReq) (res *post.NameUniqueRes, err error) {
- data, err := service.AdminPost().NameUnique(ctx, adminin.PostNameUniqueInp{Id: req.Id, Name: req.Name})
- if err != nil {
- return
- }
-
- res = new(post.NameUniqueRes)
- res.IsUnique = data.IsUnique
- return
-}
-
-// CodeUnique 编码是否唯一
-func (c *cPost) CodeUnique(ctx context.Context, req *post.CodeUniqueReq) (res *post.CodeUniqueRes, err error) {
- data, err := service.AdminPost().CodeUnique(ctx, adminin.PostCodeUniqueInp{Id: req.Id, Code: req.Code})
- if err != nil {
- return nil, err
- }
-
- res = new(post.CodeUniqueRes)
- res.IsUnique = data.IsUnique
- return
-}
-
// View 获取指定信息
func (c *cPost) View(ctx context.Context, req *post.ViewReq) (res *post.ViewRes, err error) {
- data, err := service.AdminPost().View(ctx, adminin.PostViewInp{Id: req.Id})
+ data, err := service.AdminPost().View(ctx, &req.PostViewInp)
if err != nil {
return
}
@@ -91,31 +54,19 @@ func (c *cPost) View(ctx context.Context, req *post.ViewReq) (res *post.ViewRes,
// List 获取列表
func (c *cPost) List(ctx context.Context, req *post.ListReq) (res *post.ListRes, err error) {
- var in adminin.PostListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.AdminPost().List(ctx, in)
+ list, totalCount, err := service.AdminPost().List(ctx, &req.PostListInp)
if err != nil {
return
}
res = new(post.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Status 更新状态
func (c *cPost) Status(ctx context.Context, req *post.StatusReq) (res *post.StatusRes, err error) {
- var in adminin.PostStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.AdminPost().Status(ctx, in)
+ err = service.AdminPost().Status(ctx, &req.PostStatusInp)
return
}
diff --git a/server/internal/controller/admin/admin/role.go b/server/internal/controller/admin/admin/role.go
index 436a228..28b9508 100644
--- a/server/internal/controller/admin/admin/role.go
+++ b/server/internal/controller/admin/admin/role.go
@@ -7,13 +7,9 @@ package admin
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/role"
"hotgo/internal/library/contexts"
- "hotgo/internal/model/input/adminin"
- "hotgo/internal/model/input/form"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -24,51 +20,26 @@ type cRole struct{}
// List 获取列表
func (c *cRole) List(ctx context.Context, req *role.ListReq) (res *role.ListRes, err error) {
- var in adminin.RoleListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.AdminRole().List(ctx, in)
+ list, totalCount, err := service.AdminRole().List(ctx, &req.RoleListInp)
if err != nil {
return
}
res = new(role.ListRes)
res.RoleListModel = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Edit 修改角色
func (c *cRole) Edit(ctx context.Context, req *role.EditReq) (res *role.EditRes, err error) {
- var in adminin.RoleEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminRole().Edit(ctx, in)
+ err = service.AdminRole().Edit(ctx, &req.RoleEditInp)
return
}
// Delete 删除
func (c *cRole) Delete(ctx context.Context, req *role.DeleteReq) (res *role.DeleteRes, err error) {
- var in adminin.RoleDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminRole().Delete(ctx, in)
+ err = service.AdminRole().Delete(ctx, &req.RoleDeleteInp)
return
}
@@ -79,16 +50,7 @@ func (c *cRole) Dynamic(ctx context.Context, _ *role.DynamicReq) (res *role.Dyna
// GetPermissions 获取指定角色权限
func (c *cRole) GetPermissions(ctx context.Context, req *role.GetPermissionsReq) (res *role.GetPermissionsRes, err error) {
- var in adminin.GetPermissionsInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- data, err := service.AdminRole().GetPermissions(ctx, in)
+ data, err := service.AdminRole().GetPermissions(ctx, &req.GetPermissionsInp)
if err != nil {
return
}
@@ -100,16 +62,7 @@ func (c *cRole) GetPermissions(ctx context.Context, req *role.GetPermissionsReq)
// UpdatePermissions 修改角色菜单权限
func (c *cRole) UpdatePermissions(ctx context.Context, req *role.UpdatePermissionsReq) (res *role.UpdatePermissionsRes, err error) {
- var in adminin.UpdatePermissionsInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminRole().UpdatePermissions(ctx, in)
+ err = service.AdminRole().UpdatePermissions(ctx, &req.UpdatePermissionsInp)
return
}
@@ -122,16 +75,6 @@ func (c *cRole) DataScopeSelect(_ context.Context, _ *role.DataScopeSelectReq) (
// DataScopeEdit 获取数据权限选项
func (c *cRole) DataScopeEdit(ctx context.Context, req *role.DataScopeEditReq) (res *role.DataScopeEditRes, err error) {
- var in adminin.DataScopeEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- in.CustomDept = req.CustomDept
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminRole().DataScopeEdit(ctx, &in)
+ err = service.AdminRole().DataScopeEdit(ctx, &req.DataScopeEditInp)
return
}
diff --git a/server/internal/controller/admin/common/ems.go b/server/internal/controller/admin/common/ems.go
index 0cd32d8..d3f29f6 100644
--- a/server/internal/controller/admin/common/ems.go
+++ b/server/internal/controller/admin/common/ems.go
@@ -23,7 +23,7 @@ type cEms struct{}
// SendTest 发送测试邮件
func (c *cEms) SendTest(ctx context.Context, req *common.SendTestEmailReq) (res *common.SendTestEmailRes, err error) {
- err = service.SysEmsLog().Send(ctx, sysin.SendEmsInp{
+ err = service.SysEmsLog().Send(ctx, &sysin.SendEmsInp{
Event: consts.EmsTemplateText,
Email: req.To,
Content: `
@@ -47,16 +47,13 @@ func (c *cSms) SendBindEms(ctx context.Context, _ *common.SendBindEmsReq) (res *
memberId = contexts.GetUserId(ctx)
models *entity.AdminMember
)
+
if memberId <= 0 {
err = gerror.New("用户身份异常,请重新登录!")
return
}
- err = g.Model("admin_member").
- Fields("email").
- Where("id", memberId).
- Scan(&models)
- if err != nil {
+ if err = g.Model("admin_member").Fields("email").Where("id", memberId).Scan(&models); err != nil {
return
}
@@ -70,7 +67,7 @@ func (c *cSms) SendBindEms(ctx context.Context, _ *common.SendBindEmsReq) (res *
return
}
- err = service.SysEmsLog().Send(ctx, sysin.SendEmsInp{
+ err = service.SysEmsLog().Send(ctx, &sysin.SendEmsInp{
Event: consts.EmsTemplateBind,
Email: models.Email,
})
diff --git a/server/internal/controller/admin/common/site.go b/server/internal/controller/admin/common/site.go
index 8a27625..adffbec 100644
--- a/server/internal/controller/admin/common/site.go
+++ b/server/internal/controller/admin/common/site.go
@@ -15,7 +15,6 @@ import (
"hotgo/internal/consts"
"hotgo/internal/library/captcha"
"hotgo/internal/library/token"
- "hotgo/internal/model/input/adminin"
"hotgo/internal/service"
"hotgo/utility/validate"
)
@@ -51,7 +50,6 @@ func (c *cSite) getWsAddr(ctx context.Context, request *ghttp.Request) string {
if err != nil || basic == nil {
return ""
}
-
return basic.WsAddr
}
@@ -66,7 +64,6 @@ func (c *cSite) getDomain(ctx context.Context, request *ghttp.Request) string {
if err != nil || basic == nil {
return ""
}
-
return basic.Domain
}
@@ -91,26 +88,12 @@ func (c *cSite) Captcha(ctx context.Context, _ *common.LoginCaptchaReq) (res *co
// Register 账号注册
func (c *cSite) Register(ctx context.Context, req *common.RegisterReq) (res *common.RegisterRes, err error) {
- var in adminin.RegisterInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.AdminSite().Register(ctx, in)
+ err = service.AdminSite().Register(ctx, &req.RegisterInp)
return
}
// AccountLogin 账号登录
func (c *cSite) AccountLogin(ctx context.Context, req *common.AccountLoginReq) (res *common.AccountLoginRes, err error) {
- var in adminin.AccountLoginInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
login, err := service.SysConfig().GetLogin(ctx)
if err != nil {
return
@@ -124,7 +107,7 @@ func (c *cSite) AccountLogin(ctx context.Context, req *common.AccountLoginReq) (
}
}
- model, err := service.AdminSite().AccountLogin(ctx, in)
+ model, err := service.AdminSite().AccountLogin(ctx, &req.AccountLoginInp)
if err != nil {
return
}
@@ -135,12 +118,7 @@ func (c *cSite) AccountLogin(ctx context.Context, req *common.AccountLoginReq) (
// MobileLogin 手机号登录
func (c *cSite) MobileLogin(ctx context.Context, req *common.MobileLoginReq) (res *common.MobileLoginRes, err error) {
- var in adminin.MobileLoginInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- model, err := service.AdminSite().MobileLogin(ctx, in)
+ model, err := service.AdminSite().MobileLogin(ctx, &req.MobileLoginInp)
if err != nil {
return
}
diff --git a/server/internal/controller/admin/common/sms.go b/server/internal/controller/admin/common/sms.go
index 573d93e..beae377 100644
--- a/server/internal/controller/admin/common/sms.go
+++ b/server/internal/controller/admin/common/sms.go
@@ -9,14 +9,12 @@ import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/common"
"hotgo/internal/consts"
"hotgo/internal/library/contexts"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var Sms = new(cSms)
@@ -25,16 +23,7 @@ type cSms struct{}
// SendTest 发送测试短信
func (c *cSms) SendTest(ctx context.Context, req *common.SendTestSmsReq) (res *common.SendTestSmsRes, err error) {
- var in sysin.SendCodeInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysSmsLog().SendCode(ctx, in)
+ err = service.SysSmsLog().SendCode(ctx, &req.SendCodeInp)
return
}
@@ -50,11 +39,7 @@ func (c *cSms) SendBindSms(ctx context.Context, _ *common.SendBindSmsReq) (res *
return
}
- err = g.Model("admin_member").
- Fields("mobile").
- Where("id", memberId).
- Scan(&models)
- if err != nil {
+ if err = g.Model("admin_member").Fields("mobile").Where("id", memberId).Scan(&models); err != nil {
return
}
@@ -68,7 +53,7 @@ func (c *cSms) SendBindSms(ctx context.Context, _ *common.SendBindSmsReq) (res *
return
}
- err = service.SysSmsLog().SendCode(ctx, sysin.SendCodeInp{
+ err = service.SysSmsLog().SendCode(ctx, &sysin.SendCodeInp{
Event: consts.SmsTemplateBind,
Mobile: models.Mobile,
})
@@ -77,15 +62,6 @@ func (c *cSms) SendBindSms(ctx context.Context, _ *common.SendBindSmsReq) (res *
// SendSms 发送短信
func (c *cSms) SendSms(ctx context.Context, req *common.SendSmsReq) (res *common.SendSmsRes, err error) {
- var in sysin.SendCodeInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysSmsLog().SendCode(ctx, in)
+ err = service.SysSmsLog().SendCode(ctx, &req.SendCodeInp)
return
}
diff --git a/server/internal/controller/admin/common/upload.go b/server/internal/controller/admin/common/upload.go
index d02363e..5609988 100644
--- a/server/internal/controller/admin/common/upload.go
+++ b/server/internal/controller/admin/common/upload.go
@@ -10,29 +10,28 @@ import (
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"hotgo/api/admin/common"
+ "hotgo/internal/library/storager"
"hotgo/internal/service"
+ "hotgo/utility/validate"
)
var Upload = new(cUpload)
type cUpload struct{}
-// UploadImage 上传图片
-func (c *cUpload) UploadImage(ctx context.Context, _ *common.UploadImageReq) (res common.UploadImageRes, err error) {
- file := g.RequestFromCtx(ctx).GetUploadFile("file")
- if file == nil {
- err = gerror.New("没有找到上传的文件")
- return
- }
- return service.CommonUpload().UploadImage(ctx, file)
-}
-
-// UploadFile 上传附件
+// UploadFile 上传文件
func (c *cUpload) UploadFile(ctx context.Context, _ *common.UploadFileReq) (res common.UploadFileRes, err error) {
- file := g.RequestFromCtx(ctx).GetUploadFile("file")
+ r := g.RequestFromCtx(ctx)
+ uploadType := r.Header.Get("uploadType")
+ if uploadType != "default" && !validate.InSlice(storager.KindSlice, uploadType) {
+ err = gerror.New("上传类型是无效的")
+ return
+ }
+
+ file := r.GetUploadFile("file")
if file == nil {
err = gerror.New("没有找到上传的文件")
return
}
- return service.CommonUpload().UploadFile(ctx, file)
+ return service.CommonUpload().UploadFile(ctx, uploadType, file)
}
diff --git a/server/internal/controller/admin/common/wechat.go b/server/internal/controller/admin/common/wechat.go
index 0a4666c..4e658d3 100644
--- a/server/internal/controller/admin/common/wechat.go
+++ b/server/internal/controller/admin/common/wechat.go
@@ -7,11 +7,8 @@ package common
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/common"
- "hotgo/internal/model/input/commonin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -21,29 +18,11 @@ var (
type cWechat struct{}
func (c *cWechat) Authorize(ctx context.Context, req *common.WechatAuthorizeReq) (res *common.WechatAuthorizeRes, err error) {
- var in commonin.WechatAuthorizeInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- _, err = service.CommonWechat().Authorize(ctx, in)
+ _, err = service.CommonWechat().Authorize(ctx, &req.WechatAuthorizeInp)
return
}
func (c *cWechat) AuthorizeCall(ctx context.Context, req *common.WechatAuthorizeCallReq) (res *common.WechatAuthorizeCallRes, err error) {
- var in commonin.WechatAuthorizeCallInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- _, err = service.CommonWechat().AuthorizeCall(ctx, in)
+ _, err = service.CommonWechat().AuthorizeCall(ctx, &req.WechatAuthorizeCallInp)
return
}
diff --git a/server/internal/controller/admin/pay/refund.go b/server/internal/controller/admin/pay/refund.go
index a395c91..1facbfe 100644
--- a/server/internal/controller/admin/pay/refund.go
+++ b/server/internal/controller/admin/pay/refund.go
@@ -10,12 +10,7 @@ package pay
import (
"context"
"hotgo/api/admin/pay"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/payin"
"hotgo/internal/service"
- "hotgo/utility/validate"
-
- "github.com/gogf/gf/v2/util/gconv"
)
var (
@@ -26,39 +21,19 @@ type cRefund struct{}
// List 查看交易退款列表
func (c *cRefund) List(ctx context.Context, req *pay.RefundListReq) (res *pay.RefundListRes, err error) {
- var in payin.PayRefundListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.PayRefund().List(ctx, in)
+ list, totalCount, err := service.PayRefund().List(ctx, &req.PayRefundListInp)
if err != nil {
return
}
res = new(pay.RefundListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Export 导出交易退款列表
func (c *cRefund) Export(ctx context.Context, req *pay.RefundExportReq) (res *pay.RefundExportRes, err error) {
- var in payin.PayRefundListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.PayRefund().Export(ctx, in)
+ err = service.PayRefund().Export(ctx, &req.PayRefundListInp)
return
}
diff --git a/server/internal/controller/admin/sys/addons.go b/server/internal/controller/admin/sys/addons.go
index bc04aad..e2098c6 100644
--- a/server/internal/controller/admin/sys/addons.go
+++ b/server/internal/controller/admin/sys/addons.go
@@ -7,12 +7,8 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/addons"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -23,27 +19,20 @@ type cAddons struct{}
// List 查看列表
func (c *cAddons) List(ctx context.Context, req *addons.ListReq) (res *addons.ListRes, err error) {
- var in sysin.AddonsListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysAddons().List(ctx, in)
+ list, totalCount, err := service.SysAddons().List(ctx, &req.AddonsListInp)
if err != nil {
return
}
res = new(addons.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Selects 获取指定信息
func (c *cAddons) Selects(ctx context.Context, req *addons.SelectsReq) (res *addons.SelectsRes, err error) {
- data, err := service.SysAddons().Selects(ctx, sysin.AddonsSelectsInp{})
+ data, err := service.SysAddons().Selects(ctx, &req.AddonsSelectsInp)
if err != nil {
return
}
@@ -55,27 +44,13 @@ func (c *cAddons) Selects(ctx context.Context, req *addons.SelectsReq) (res *add
// Build 生成预览
func (c *cAddons) Build(ctx context.Context, req *addons.BuildReq) (res *addons.BuildRes, err error) {
- var in sysin.AddonsBuildInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysAddons().Build(ctx, in)
+ err = service.SysAddons().Build(ctx, &req.AddonsBuildInp)
return
}
// Install 安装模块
func (c *cAddons) Install(ctx context.Context, req *addons.InstallReq) (res *addons.InstallRes, err error) {
- var in sysin.AddonsInstallInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = service.SysAddons().Install(ctx, in); err != nil {
+ if err = service.SysAddons().Install(ctx, &req.AddonsInstallInp); err != nil {
return
}
return
@@ -83,12 +58,7 @@ func (c *cAddons) Install(ctx context.Context, req *addons.InstallReq) (res *add
// Upgrade 更新模块
func (c *cAddons) Upgrade(ctx context.Context, req *addons.UpgradeReq) (res *addons.UpgradeRes, err error) {
- var in sysin.AddonsUpgradeInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = service.SysAddons().Upgrade(ctx, in); err != nil {
+ if err = service.SysAddons().Upgrade(ctx, &req.AddonsUpgradeInp); err != nil {
return
}
return
@@ -96,12 +66,7 @@ func (c *cAddons) Upgrade(ctx context.Context, req *addons.UpgradeReq) (res *add
// UnInstall 卸载模块
func (c *cAddons) UnInstall(ctx context.Context, req *addons.UnInstallReq) (res *addons.UnInstallRes, err error) {
- var in sysin.AddonsUnInstallInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = service.SysAddons().UnInstall(ctx, in); err != nil {
+ if err = service.SysAddons().UnInstall(ctx, &req.AddonsUnInstallInp); err != nil {
return
}
return
diff --git a/server/internal/controller/admin/sys/attachment.go b/server/internal/controller/admin/sys/attachment.go
index bc15b9a..0236466 100644
--- a/server/internal/controller/admin/sys/attachment.go
+++ b/server/internal/controller/admin/sys/attachment.go
@@ -7,9 +7,8 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/attachment"
- "hotgo/internal/model/input/form"
+ "hotgo/internal/library/storager"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
)
@@ -22,18 +21,13 @@ type cAttachment struct{}
// Delete 删除附件
func (c *cAttachment) Delete(ctx context.Context, req *attachment.DeleteReq) (res *attachment.DeleteRes, err error) {
- var in sysin.AttachmentDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysAttachment().Delete(ctx, in)
+ err = service.SysAttachment().Delete(ctx, &req.AttachmentDeleteInp)
return
}
// View 获取指定附件信息
func (c *cAttachment) View(ctx context.Context, req *attachment.ViewReq) (res *attachment.ViewRes, err error) {
- data, err := service.SysAttachment().View(ctx, sysin.AttachmentViewInp{Id: req.Id})
+ data, err := service.SysAttachment().View(ctx, &req.AttachmentViewInp)
if err != nil {
return
}
@@ -45,20 +39,55 @@ func (c *cAttachment) View(ctx context.Context, req *attachment.ViewReq) (res *a
// List 查看附件列表
func (c *cAttachment) List(ctx context.Context, req *attachment.ListReq) (res *attachment.ListRes, err error) {
- var in sysin.AttachmentListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysAttachment().List(ctx, in)
+ list, totalCount, err := service.SysAttachment().List(ctx, &req.AttachmentListInp)
if err != nil {
return
}
res = new(attachment.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
+ return
+}
+
+// ChooserOption 获取选择器选项
+func (c *cAttachment) ChooserOption(ctx context.Context, req *attachment.ChooserOptionReq) (res *attachment.ChooserOptionRes, err error) {
+ res = new(attachment.ChooserOptionRes)
+
+ res.Drive, err = service.SysDictData().Select(ctx, &sysin.DataSelectInp{Type: "config_upload_drive"})
+ if err != nil {
+ return
+ }
+
+ var kinds = []attachment.KindSelect{
+ {
+ Label: "全部", Key: "", Value: "",
+ },
+ {
+ Label: "图片", Key: storager.KindImg, Value: storager.KindImg, Icon: "PictureOutlined", Tag: "success",
+ },
+ {
+ Label: "文档", Key: storager.KindDoc, Value: storager.KindDoc, Icon: "FileWordOutlined", Tag: "primary",
+ },
+ {
+ Label: "音频", Key: storager.KindAudio, Value: storager.KindAudio, Icon: "CustomerServiceOutlined", Tag: "info",
+ },
+ {
+ Label: "视频", Key: storager.KindVideo, Value: storager.KindVideo, Icon: "PlaySquareOutlined", Tag: "warning",
+ },
+ {
+ Label: "压缩包", Key: storager.KindZip, Value: storager.KindZip, Icon: "FileZipOutlined", Tag: "error",
+ },
+ {
+ Label: "其他", Key: storager.KindOther, Value: storager.KindOther, Icon: "PlusOutlined", Tag: "default",
+ },
+ }
+ res.Kind = append(res.Kind, kinds...)
+ return
+}
+
+// ClearKind 清空上传类型
+func (c *cAttachment) ClearKind(ctx context.Context, req *attachment.ClearKindReq) (res *attachment.ClearKindRes, err error) {
+ err = service.SysAttachment().ClearKind(ctx, &req.AttachmentClearKindInp)
return
}
diff --git a/server/internal/controller/admin/sys/blacklist.go b/server/internal/controller/admin/sys/blacklist.go
index 49719fd..cac7c3d 100644
--- a/server/internal/controller/admin/sys/blacklist.go
+++ b/server/internal/controller/admin/sys/blacklist.go
@@ -3,15 +3,11 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/blacklist"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
)
@@ -23,41 +19,19 @@ type cBlacklist struct{}
// Delete 删除
func (c *cBlacklist) Delete(ctx context.Context, req *blacklist.DeleteReq) (res *blacklist.DeleteRes, err error) {
- var in sysin.BlacklistDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysBlacklist().Delete(ctx, in)
+ err = service.SysBlacklist().Delete(ctx, &req.BlacklistDeleteInp)
return
}
// Edit 更新
func (c *cBlacklist) Edit(ctx context.Context, req *blacklist.EditReq) (res *blacklist.EditRes, err error) {
- var in sysin.BlacklistEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysBlacklist().Edit(ctx, in)
- return
-}
-
-// MaxSort 最大排序
-func (c *cBlacklist) MaxSort(ctx context.Context, req *blacklist.MaxSortReq) (res *blacklist.MaxSortRes, err error) {
- data, err := service.SysBlacklist().MaxSort(ctx, sysin.BlacklistMaxSortInp{Id: req.Id})
- if err != nil {
- return
- }
-
- res = new(blacklist.MaxSortRes)
- res.Sort = data.Sort
+ err = service.SysBlacklist().Edit(ctx, &req.BlacklistEditInp)
return
}
// View 获取指定信息
func (c *cBlacklist) View(ctx context.Context, req *blacklist.ViewReq) (res *blacklist.ViewRes, err error) {
- data, err := service.SysBlacklist().View(ctx, sysin.BlacklistViewInp{Id: req.Id})
+ data, err := service.SysBlacklist().View(ctx, &req.BlacklistViewInp)
if err != nil {
return
}
@@ -69,31 +43,19 @@ func (c *cBlacklist) View(ctx context.Context, req *blacklist.ViewReq) (res *bla
// List 查看列表
func (c *cBlacklist) List(ctx context.Context, req *blacklist.ListReq) (res *blacklist.ListRes, err error) {
- var in sysin.BlacklistListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysBlacklist().List(ctx, in)
+ list, totalCount, err := service.SysBlacklist().List(ctx, &req.BlacklistListInp)
if err != nil {
return
}
res = new(blacklist.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
-// Status 更新部门状态
+// Status 更新黑名单状态
func (c *cBlacklist) Status(ctx context.Context, req *blacklist.StatusReq) (res *blacklist.StatusRes, err error) {
- var in sysin.BlacklistStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysBlacklist().Status(ctx, in)
+ err = service.SysBlacklist().Status(ctx, &req.BlacklistStatusInp)
return
}
diff --git a/server/internal/controller/admin/sys/config.go b/server/internal/controller/admin/sys/config.go
index 2be9551..a831c80 100644
--- a/server/internal/controller/admin/sys/config.go
+++ b/server/internal/controller/admin/sys/config.go
@@ -7,7 +7,6 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/config"
"hotgo/internal/consts"
"hotgo/internal/model/input/form"
@@ -23,24 +22,14 @@ type cConfig struct{}
// GetConfig 获取指定分组的配置
func (c *cConfig) GetConfig(ctx context.Context, req *config.GetReq) (res *config.GetRes, err error) {
- var in sysin.GetConfigInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
res = new(config.GetRes)
- res.GetConfigModel, err = service.SysConfig().GetConfigByGroup(ctx, in)
+ res.GetConfigModel, err = service.SysConfig().GetConfigByGroup(ctx, &req.GetConfigInp)
return
}
// UpdateConfig 更新指定分组的配置
func (c *cConfig) UpdateConfig(ctx context.Context, req *config.UpdateReq) (res *config.UpdateRes, err error) {
- var in sysin.UpdateConfigInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysConfig().UpdateConfigByGroup(ctx, in)
+ err = service.SysConfig().UpdateConfigByGroup(ctx, &req.UpdateConfigInp)
return
}
@@ -56,9 +45,9 @@ func (c *cConfig) TypeSelect(_ context.Context, _ *config.TypeSelectReq) (res co
return
}
-// GetCash 获取指定分组的配置
+// GetCash 获取提现的配置
func (c *cConfig) GetCash(ctx context.Context, _ *config.GetCashReq) (res *config.GetCashRes, err error) {
res = new(config.GetCashRes)
- res.GetConfigModel, err = service.SysConfig().GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "cash"})
+ res.GetConfigModel, err = service.SysConfig().GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "cash"})
return
}
diff --git a/server/internal/controller/admin/sys/cron.go b/server/internal/controller/admin/sys/cron.go
index 7c59fcc..36e938f 100644
--- a/server/internal/controller/admin/sys/cron.go
+++ b/server/internal/controller/admin/sys/cron.go
@@ -8,11 +8,8 @@ package sys
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/cron"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/msgin"
- "hotgo/internal/model/input/sysin"
+ "hotgo/api/servmsg"
"hotgo/internal/service"
)
@@ -24,29 +21,19 @@ type cCron struct{}
// Delete 删除
func (c *cCron) Delete(ctx context.Context, req *cron.DeleteReq) (res *cron.DeleteRes, err error) {
- var in = new(msgin.CronDelete)
- if err = gconv.Scan(req, &in.CronDeleteInp); err != nil {
- return
- }
-
- err = service.TCPServer().CronDelete(ctx, in)
+ err = service.TCPServer().CronDelete(ctx, &servmsg.CronDeleteReq{CronDeleteInp: &req.CronDeleteInp})
return
}
// Edit 更新
func (c *cCron) Edit(ctx context.Context, req *cron.EditReq) (res *cron.EditRes, err error) {
- var in = new(msgin.CronEdit)
- if err = gconv.Scan(req, &in.CronEditInp); err != nil {
- return
- }
-
- err = service.TCPServer().CronEdit(ctx, in)
+ err = service.TCPServer().CronEdit(ctx, &servmsg.CronEditReq{CronEditInp: &req.CronEditInp})
return
}
// MaxSort 最大排序
func (c *cCron) MaxSort(ctx context.Context, req *cron.MaxSortReq) (res *cron.MaxSortRes, err error) {
- data, err := service.SysCron().MaxSort(ctx, sysin.CronMaxSortInp{Id: req.Id})
+ data, err := service.SysCron().MaxSort(ctx, &req.CronMaxSortInp)
if err != nil {
return
}
@@ -58,7 +45,7 @@ func (c *cCron) MaxSort(ctx context.Context, req *cron.MaxSortReq) (res *cron.Ma
// View 获取指定信息
func (c *cCron) View(ctx context.Context, req *cron.ViewReq) (res *cron.ViewRes, err error) {
- data, err := service.SysCron().View(ctx, sysin.CronViewInp{Id: req.Id})
+ data, err := service.SysCron().View(ctx, &req.CronViewInp)
if err != nil {
return
}
@@ -70,32 +57,20 @@ func (c *cCron) View(ctx context.Context, req *cron.ViewReq) (res *cron.ViewRes,
// List 查看列表
func (c *cCron) List(ctx context.Context, req *cron.ListReq) (res *cron.ListRes, err error) {
- var in sysin.CronListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysCron().List(ctx, in)
+ list, totalCount, err := service.SysCron().List(ctx, &req.CronListInp)
if err != nil {
return
}
res = new(cron.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Status 更新部门状态
func (c *cCron) Status(ctx context.Context, req *cron.StatusReq) (res *cron.StatusRes, err error) {
- var in sysin.CronStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysCron().Status(ctx, in)
+ err = service.SysCron().Status(ctx, &req.CronStatusInp)
return
}
@@ -105,11 +80,6 @@ func (c *cCron) OnlineExec(ctx context.Context, req *cron.OnlineExecReq) (res *c
return nil, gerror.New("定时任务ID不能为空")
}
- var in = new(msgin.CronOnlineExec)
- if err = gconv.Scan(req, &in.OnlineExecInp); err != nil {
- return
- }
-
- err = service.TCPServer().CronOnlineExec(ctx, in)
+ err = service.TCPServer().CronOnlineExec(ctx, &servmsg.CronOnlineExecReq{OnlineExecInp: &req.OnlineExecInp})
return
}
diff --git a/server/internal/controller/admin/sys/cron_group.go b/server/internal/controller/admin/sys/cron_group.go
index eb70c30..5941491 100644
--- a/server/internal/controller/admin/sys/cron_group.go
+++ b/server/internal/controller/admin/sys/cron_group.go
@@ -7,12 +7,8 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/cron"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -23,33 +19,19 @@ type cCronGroup struct{}
// Delete 删除
func (c *cCronGroup) Delete(ctx context.Context, req *cron.GroupDeleteReq) (res *cron.GroupDeleteRes, err error) {
- var in sysin.CronGroupDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysCronGroup().Delete(ctx, in)
+ err = service.SysCronGroup().Delete(ctx, &req.CronGroupDeleteInp)
return
}
// Edit 更新
func (c *cCronGroup) Edit(ctx context.Context, req *cron.GroupEditReq) (res *cron.GroupEditRes, err error) {
- var in sysin.CronGroupEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysCronGroup().Edit(ctx, in)
+ err = service.SysCronGroup().Edit(ctx, &req.CronGroupEditInp)
return
}
// MaxSort 最大排序
func (c *cCronGroup) MaxSort(ctx context.Context, req *cron.GroupMaxSortReq) (res *cron.GroupMaxSortRes, err error) {
- data, err := service.SysCronGroup().MaxSort(ctx, sysin.CronGroupMaxSortInp{Id: req.Id})
+ data, err := service.SysCronGroup().MaxSort(ctx, &req.CronGroupMaxSortInp)
if err != nil {
return
}
@@ -61,7 +43,7 @@ func (c *cCronGroup) MaxSort(ctx context.Context, req *cron.GroupMaxSortReq) (re
// View 获取指定信息
func (c *cCronGroup) View(ctx context.Context, req *cron.GroupViewReq) (res *cron.GroupViewRes, err error) {
- data, err := service.SysCronGroup().View(ctx, sysin.CronGroupViewInp{Id: req.Id})
+ data, err := service.SysCronGroup().View(ctx, &req.CronGroupViewInp)
if err != nil {
return
}
@@ -73,42 +55,26 @@ func (c *cCronGroup) View(ctx context.Context, req *cron.GroupViewReq) (res *cro
// List 查看列表
func (c *cCronGroup) List(ctx context.Context, req *cron.GroupListReq) (res *cron.GroupListRes, err error) {
- var in sysin.CronGroupListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysCronGroup().List(ctx, in)
+ list, totalCount, err := service.SysCronGroup().List(ctx, &req.CronGroupListInp)
if err != nil {
return
}
res = new(cron.GroupListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Status 更新状态
func (c *cCronGroup) Status(ctx context.Context, req *cron.GroupStatusReq) (res *cron.GroupStatusRes, err error) {
- var in sysin.CronGroupStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysCronGroup().Status(ctx, in)
+ err = service.SysCronGroup().Status(ctx, &req.CronGroupStatusInp)
return
}
// Select 选项
-func (c *cCronGroup) Select(ctx context.Context, _ *cron.GroupSelectReq) (res *cron.GroupSelectRes, err error) {
- data, err := service.SysCronGroup().Select(ctx, sysin.CronGroupSelectInp{})
+func (c *cCronGroup) Select(ctx context.Context, req *cron.GroupSelectReq) (res *cron.GroupSelectRes, err error) {
+ data, err := service.SysCronGroup().Select(ctx, &req.CronGroupSelectInp)
if err != nil {
return
}
diff --git a/server/internal/controller/admin/sys/curd_demo.go b/server/internal/controller/admin/sys/curd_demo.go
index 89a6800..15330ee 100644
--- a/server/internal/controller/admin/sys/curd_demo.go
+++ b/server/internal/controller/admin/sys/curd_demo.go
@@ -3,18 +3,13 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-// @AutoGenerate Version 2.7.3
+// @AutoGenerate Version 2.7.6
package sys
import (
"context"
"hotgo/api/admin/curddemo"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
-
- "github.com/gogf/gf/v2/util/gconv"
)
var (
@@ -25,61 +20,32 @@ type cCurdDemo struct{}
// List 查看生成演示列表
func (c *cCurdDemo) List(ctx context.Context, req *curddemo.ListReq) (res *curddemo.ListRes, err error) {
- var in sysin.CurdDemoListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysCurdDemo().List(ctx, in)
+ list, totalCount, err := service.SysCurdDemo().List(ctx, &req.CurdDemoListInp)
if err != nil {
return
}
res = new(curddemo.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Export 导出生成演示列表
func (c *cCurdDemo) Export(ctx context.Context, req *curddemo.ExportReq) (res *curddemo.ExportRes, err error) {
- var in sysin.CurdDemoListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysCurdDemo().Export(ctx, in)
+ err = service.SysCurdDemo().Export(ctx, &req.CurdDemoListInp)
return
}
// Edit 更新生成演示
func (c *cCurdDemo) Edit(ctx context.Context, req *curddemo.EditReq) (res *curddemo.EditRes, err error) {
- var in sysin.CurdDemoEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysCurdDemo().Edit(ctx, in)
+ err = service.SysCurdDemo().Edit(ctx, &req.CurdDemoEditInp)
return
}
// MaxSort 获取生成演示最大排序
func (c *cCurdDemo) MaxSort(ctx context.Context, req *curddemo.MaxSortReq) (res *curddemo.MaxSortRes, err error) {
- data, err := service.SysCurdDemo().MaxSort(ctx, sysin.CurdDemoMaxSortInp{})
+ data, err := service.SysCurdDemo().MaxSort(ctx, &req.CurdDemoMaxSortInp)
if err != nil {
return
}
@@ -91,16 +57,7 @@ func (c *cCurdDemo) MaxSort(ctx context.Context, req *curddemo.MaxSortReq) (res
// View 获取指定生成演示信息
func (c *cCurdDemo) View(ctx context.Context, req *curddemo.ViewReq) (res *curddemo.ViewRes, err error) {
- var in sysin.CurdDemoViewInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- data, err := service.SysCurdDemo().View(ctx, in)
+ data, err := service.SysCurdDemo().View(ctx, &req.CurdDemoViewInp)
if err != nil {
return
}
@@ -112,45 +69,18 @@ func (c *cCurdDemo) View(ctx context.Context, req *curddemo.ViewReq) (res *curdd
// Delete 删除生成演示
func (c *cCurdDemo) Delete(ctx context.Context, req *curddemo.DeleteReq) (res *curddemo.DeleteRes, err error) {
- var in sysin.CurdDemoDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysCurdDemo().Delete(ctx, in)
+ err = service.SysCurdDemo().Delete(ctx, &req.CurdDemoDeleteInp)
return
}
// Status 更新生成演示状态
func (c *cCurdDemo) Status(ctx context.Context, req *curddemo.StatusReq) (res *curddemo.StatusRes, err error) {
- var in sysin.CurdDemoStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysCurdDemo().Status(ctx, in)
+ err = service.SysCurdDemo().Status(ctx, &req.CurdDemoStatusInp)
return
}
// Switch 更新生成演示开关状态
func (c *cCurdDemo) Switch(ctx context.Context, req *curddemo.SwitchReq) (res *curddemo.SwitchRes, err error) {
- var in sysin.CurdDemoSwitchInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysCurdDemo().Switch(ctx, in)
+ err = service.SysCurdDemo().Switch(ctx, &req.CurdDemoSwitchInp)
return
}
diff --git a/server/internal/controller/admin/sys/dict_data.go b/server/internal/controller/admin/sys/dict_data.go
index d7b142b..1e067da 100644
--- a/server/internal/controller/admin/sys/dict_data.go
+++ b/server/internal/controller/admin/sys/dict_data.go
@@ -7,12 +7,9 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/dict"
- "hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -23,58 +20,32 @@ type cDictData struct{}
// Delete 删除
func (c *cDictData) Delete(ctx context.Context, req *dict.DataDeleteReq) (res *dict.DataDeleteRes, err error) {
- var in sysin.DictDataDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysDictData().Delete(ctx, in)
+ err = service.SysDictData().Delete(ctx, &req.DictDataDeleteInp)
return
}
// Edit 更新
func (c *cDictData) Edit(ctx context.Context, req *dict.DataEditReq) (res *dict.DataEditRes, err error) {
- var in sysin.DictDataEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysDictData().Edit(ctx, in)
+ err = service.SysDictData().Edit(ctx, &req.DictDataEditInp)
return
}
// List 查看列表
func (c *cDictData) List(ctx context.Context, req *dict.DataListReq) (res *dict.DataListRes, err error) {
- var in sysin.DictDataListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysDictData().List(ctx, in)
+ list, totalCount, err := service.SysDictData().List(ctx, &req.DictDataListInp)
if err != nil {
return
}
res = new(dict.DataListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Select 指定选项
func (c *cDictData) Select(ctx context.Context, req *dict.DataSelectReq) (res dict.DataSelectRes, err error) {
- var in sysin.DataSelectInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, err := service.SysDictData().Select(ctx, in)
+ list, err := service.SysDictData().Select(ctx, &req.DataSelectInp)
if err != nil {
return
}
@@ -87,7 +58,7 @@ func (c *cDictData) Select(ctx context.Context, req *dict.DataSelectReq) (res di
func (c *cDictData) Selects(ctx context.Context, req *dict.DataSelectsReq) (res dict.DataSelectsRes, err error) {
res = make(dict.DataSelectsRes)
for _, v := range req.Types {
- option, err := service.SysDictData().Select(ctx, sysin.DataSelectInp{Type: v})
+ option, err := service.SysDictData().Select(ctx, &sysin.DataSelectInp{Type: v})
if err != nil {
return nil, err
}
diff --git a/server/internal/controller/admin/sys/dict_type.go b/server/internal/controller/admin/sys/dict_type.go
index 86afb6a..ededd0a 100644
--- a/server/internal/controller/admin/sys/dict_type.go
+++ b/server/internal/controller/admin/sys/dict_type.go
@@ -7,11 +7,8 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/dict"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -29,26 +26,12 @@ func (c *cDictType) Tree(ctx context.Context, _ *dict.TypeTreeReq) (res *dict.Ty
// Delete 删除
func (c *cDictType) Delete(ctx context.Context, req *dict.TypeDeleteReq) (res *dict.TypeDeleteRes, err error) {
- var in sysin.DictTypeDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysDictType().Delete(ctx, in)
+ err = service.SysDictType().Delete(ctx, &req.DictTypeDeleteInp)
return
}
// Edit 更新
func (c *cDictType) Edit(ctx context.Context, req *dict.TypeEditReq) (res *dict.TypeEditRes, err error) {
- var in sysin.DictTypeEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysDictType().Edit(ctx, in)
+ err = service.SysDictType().Edit(ctx, &req.DictTypeEditInp)
return
}
diff --git a/server/internal/controller/admin/sys/ems_log.go b/server/internal/controller/admin/sys/ems_log.go
index 10459aa..0bea28e 100644
--- a/server/internal/controller/admin/sys/ems_log.go
+++ b/server/internal/controller/admin/sys/ems_log.go
@@ -3,15 +3,11 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/emslog"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
)
@@ -23,29 +19,19 @@ type cEmsLog struct{}
// Delete 删除
func (c *cEmsLog) Delete(ctx context.Context, req *emslog.DeleteReq) (res *emslog.DeleteRes, err error) {
- var in sysin.EmsLogDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysEmsLog().Delete(ctx, in)
+ err = service.SysEmsLog().Delete(ctx, &req.EmsLogDeleteInp)
return
}
// Edit 更新
func (c *cEmsLog) Edit(ctx context.Context, req *emslog.EditReq) (res *emslog.EditRes, err error) {
- var in sysin.EmsLogEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysEmsLog().Edit(ctx, in)
+ err = service.SysEmsLog().Edit(ctx, &req.EmsLogEditInp)
return
}
// View 获取指定信息
func (c *cEmsLog) View(ctx context.Context, req *emslog.ViewReq) (res *emslog.ViewRes, err error) {
- data, err := service.SysEmsLog().View(ctx, sysin.EmsLogViewInp{Id: req.Id})
+ data, err := service.SysEmsLog().View(ctx, &req.EmsLogViewInp)
if err != nil {
return
}
@@ -57,31 +43,19 @@ func (c *cEmsLog) View(ctx context.Context, req *emslog.ViewReq) (res *emslog.Vi
// List 查看列表
func (c *cEmsLog) List(ctx context.Context, req *emslog.ListReq) (res *emslog.ListRes, err error) {
- var in sysin.EmsLogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysEmsLog().List(ctx, in)
+ list, totalCount, err := service.SysEmsLog().List(ctx, &req.EmsLogListInp)
if err != nil {
return
}
res = new(emslog.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
-// Status 更新部门状态
+// Status 更新状态
func (c *cEmsLog) Status(ctx context.Context, req *emslog.StatusReq) (res *emslog.StatusRes, err error) {
- var in sysin.EmsLogStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysEmsLog().Status(ctx, in)
+ err = service.SysEmsLog().Status(ctx, &req.EmsLogStatusInp)
return
}
diff --git a/server/internal/controller/admin/sys/gen_codes.go b/server/internal/controller/admin/sys/gen_codes.go
index ca1d23d..d7a4b2b 100644
--- a/server/internal/controller/admin/sys/gen_codes.go
+++ b/server/internal/controller/admin/sys/gen_codes.go
@@ -3,17 +3,12 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/gencodes"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -24,27 +19,13 @@ type cGenCodes struct{}
// Delete 删除
func (c *cGenCodes) Delete(ctx context.Context, req *gencodes.DeleteReq) (res *gencodes.DeleteRes, err error) {
- var in sysin.GenCodesDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysGenCodes().Delete(ctx, in)
+ err = service.SysGenCodes().Delete(ctx, &req.GenCodesDeleteInp)
return
}
// Edit 更新
func (c *cGenCodes) Edit(ctx context.Context, req *gencodes.EditReq) (res *gencodes.EditRes, err error) {
- var in sysin.GenCodesEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- data, err := service.SysGenCodes().Edit(ctx, in)
+ data, err := service.SysGenCodes().Edit(ctx, &req.GenCodesEditInp)
if err != nil {
return
}
@@ -56,7 +37,7 @@ func (c *cGenCodes) Edit(ctx context.Context, req *gencodes.EditReq) (res *genco
// MaxSort 最大排序
func (c *cGenCodes) MaxSort(ctx context.Context, req *gencodes.MaxSortReq) (res *gencodes.MaxSortRes, err error) {
- data, err := service.SysGenCodes().MaxSort(ctx, sysin.GenCodesMaxSortInp{Id: req.Id})
+ data, err := service.SysGenCodes().MaxSort(ctx, &req.GenCodesMaxSortInp)
if err != nil {
return
}
@@ -68,7 +49,7 @@ func (c *cGenCodes) MaxSort(ctx context.Context, req *gencodes.MaxSortReq) (res
// View 获取指定信息
func (c *cGenCodes) View(ctx context.Context, req *gencodes.ViewReq) (res *gencodes.ViewRes, err error) {
- data, err := service.SysGenCodes().View(ctx, sysin.GenCodesViewInp{Id: req.Id})
+ data, err := service.SysGenCodes().View(ctx, &req.GenCodesViewInp)
if err != nil {
return
}
@@ -80,38 +61,26 @@ func (c *cGenCodes) View(ctx context.Context, req *gencodes.ViewReq) (res *genco
// List 查看列表
func (c *cGenCodes) List(ctx context.Context, req *gencodes.ListReq) (res *gencodes.ListRes, err error) {
- var in sysin.GenCodesListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysGenCodes().List(ctx, in)
+ list, totalCount, err := service.SysGenCodes().List(ctx, &req.GenCodesListInp)
if err != nil {
return
}
res = new(gencodes.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
-// Status 更新部门状态
+// Status 更新状态
func (c *cGenCodes) Status(ctx context.Context, req *gencodes.StatusReq) (res *gencodes.StatusRes, err error) {
- var in sysin.GenCodesStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysGenCodes().Status(ctx, in)
+ err = service.SysGenCodes().Status(ctx, &req.GenCodesStatusInp)
return
}
// Selects 获取指定信息
func (c *cGenCodes) Selects(ctx context.Context, req *gencodes.SelectsReq) (res *gencodes.SelectsRes, err error) {
- data, err := service.SysGenCodes().Selects(ctx, sysin.GenCodesSelectsInp{})
+ data, err := service.SysGenCodes().Selects(ctx, &req.GenCodesSelectsInp)
if err != nil {
return
}
@@ -123,7 +92,7 @@ func (c *cGenCodes) Selects(ctx context.Context, req *gencodes.SelectsReq) (res
// TableSelect 数据库表选项
func (c *cGenCodes) TableSelect(ctx context.Context, req *gencodes.TableSelectReq) (res *gencodes.TableSelectRes, err error) {
- data, err := service.SysGenCodes().TableSelect(ctx, sysin.GenCodesTableSelectInp{Name: req.Name})
+ data, err := service.SysGenCodes().TableSelect(ctx, &req.GenCodesTableSelectInp)
if err != nil {
return
}
@@ -134,7 +103,7 @@ func (c *cGenCodes) TableSelect(ctx context.Context, req *gencodes.TableSelectRe
// ColumnSelect 表字段选项
func (c *cGenCodes) ColumnSelect(ctx context.Context, req *gencodes.ColumnSelectReq) (res *gencodes.ColumnSelectRes, err error) {
- data, err := service.SysGenCodes().ColumnSelect(ctx, sysin.GenCodesColumnSelectInp{Name: req.Name, Table: req.Table})
+ data, err := service.SysGenCodes().ColumnSelect(ctx, &req.GenCodesColumnSelectInp)
if err != nil {
return
}
@@ -145,12 +114,7 @@ func (c *cGenCodes) ColumnSelect(ctx context.Context, req *gencodes.ColumnSelect
// ColumnList 表字段列表
func (c *cGenCodes) ColumnList(ctx context.Context, req *gencodes.ColumnListReq) (res *gencodes.ColumnListRes, err error) {
- var in sysin.GenCodesColumnListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- data, err := service.SysGenCodes().ColumnList(ctx, in)
+ data, err := service.SysGenCodes().ColumnList(ctx, &req.GenCodesColumnListInp)
if err != nil {
return
}
@@ -161,16 +125,7 @@ func (c *cGenCodes) ColumnList(ctx context.Context, req *gencodes.ColumnListReq)
// Preview 生成预览
func (c *cGenCodes) Preview(ctx context.Context, req *gencodes.PreviewReq) (res *gencodes.PreviewRes, err error) {
- var in sysin.GenCodesPreviewInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- data, err := service.SysGenCodes().Preview(ctx, in)
+ data, err := service.SysGenCodes().Preview(ctx, &req.GenCodesPreviewInp)
if err != nil {
return
}
@@ -182,15 +137,6 @@ func (c *cGenCodes) Preview(ctx context.Context, req *gencodes.PreviewReq) (res
// Build 生成预览
func (c *cGenCodes) Build(ctx context.Context, req *gencodes.BuildReq) (res *gencodes.BuildRes, err error) {
- var in sysin.GenCodesBuildInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysGenCodes().Build(ctx, in)
+ err = service.SysGenCodes().Build(ctx, &req.GenCodesBuildInp)
return
}
diff --git a/server/internal/controller/admin/sys/log.go b/server/internal/controller/admin/sys/log.go
index e6fce95..192a5a5 100644
--- a/server/internal/controller/admin/sys/log.go
+++ b/server/internal/controller/admin/sys/log.go
@@ -8,10 +8,7 @@ package sys
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/log"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
)
@@ -28,54 +25,32 @@ func (c *sLog) Clear(ctx context.Context, _ *log.ClearReq) (res *log.ClearRes, e
// Export 导出
func (c *sLog) Export(ctx context.Context, req *log.ExportReq) (res *log.ExportRes, err error) {
- var in sysin.LogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysLog().Export(ctx, in)
+ err = service.SysLog().Export(ctx, &req.LogListInp)
return
}
// List 获取访问日志列表
func (c *sLog) List(ctx context.Context, req *log.ListReq) (res *log.ListRes, err error) {
- var in sysin.LogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysLog().List(ctx, in)
+ list, totalCount, err := service.SysLog().List(ctx, &req.LogListInp)
if err != nil {
return
}
res = new(log.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// View 获取指定信息
func (c *sLog) View(ctx context.Context, req *log.ViewReq) (res *log.ViewRes, err error) {
- data, err := service.SysLog().View(ctx, sysin.LogViewInp{Id: req.Id})
- if err != nil {
- return
- }
-
res = new(log.ViewRes)
- res.LogViewModel = data
+ res.LogViewModel, err = service.SysLog().View(ctx, &req.LogViewInp)
return
}
// Delete 删除
func (c *sLog) Delete(ctx context.Context, req *log.DeleteReq) (res *log.DeleteRes, err error) {
- var in sysin.LogDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysLog().Delete(ctx, in)
+ err = service.SysLog().Delete(ctx, &req.LogDeleteInp)
return
}
diff --git a/server/internal/controller/admin/sys/login_log.go b/server/internal/controller/admin/sys/login_log.go
index 7a06569..50fa374 100644
--- a/server/internal/controller/admin/sys/login_log.go
+++ b/server/internal/controller/admin/sys/login_log.go
@@ -5,17 +5,12 @@
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.1.1
// @AutoGenerate Date 2023-01-19 16:57:33
-//
package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/loginlog"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -26,55 +21,26 @@ type cLoginLog struct{}
// List 查看登录日志列表
func (c *cLoginLog) List(ctx context.Context, req *loginlog.ListReq) (res *loginlog.ListRes, err error) {
- var in sysin.LoginLogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysLoginLog().List(ctx, in)
+ list, totalCount, err := service.SysLoginLog().List(ctx, &req.LoginLogListInp)
if err != nil {
return
}
res = new(loginlog.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Export 导出登录日志列表
func (c *cLoginLog) Export(ctx context.Context, req *loginlog.ExportReq) (res *loginlog.ExportRes, err error) {
- var in sysin.LoginLogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysLoginLog().Export(ctx, in)
+ err = service.SysLoginLog().Export(ctx, &req.LoginLogListInp)
return
}
// View 获取指定登录日志信息
func (c *cLoginLog) View(ctx context.Context, req *loginlog.ViewReq) (res *loginlog.ViewRes, err error) {
- var in sysin.LoginLogViewInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- data, err := service.SysLoginLog().View(ctx, in)
+ data, err := service.SysLoginLog().View(ctx, &req.LoginLogViewInp)
if err != nil {
return
}
@@ -86,15 +52,6 @@ func (c *cLoginLog) View(ctx context.Context, req *loginlog.ViewReq) (res *login
// Delete 删除登录日志
func (c *cLoginLog) Delete(ctx context.Context, req *loginlog.DeleteReq) (res *loginlog.DeleteRes, err error) {
- var in sysin.LoginLogDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysLoginLog().Delete(ctx, in)
+ err = service.SysLoginLog().Delete(ctx, &req.LoginLogDeleteInp)
return
}
diff --git a/server/internal/controller/admin/sys/provinces.go b/server/internal/controller/admin/sys/provinces.go
index 9418699..318a423 100644
--- a/server/internal/controller/admin/sys/provinces.go
+++ b/server/internal/controller/admin/sys/provinces.go
@@ -7,13 +7,9 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/provinces"
"hotgo/internal/library/location"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -31,33 +27,19 @@ func (c *cProvinces) Tree(ctx context.Context, _ *provinces.TreeReq) (res *provi
// Delete 删除
func (c *cProvinces) Delete(ctx context.Context, req *provinces.DeleteReq) (res *provinces.DeleteRes, err error) {
- var in sysin.ProvincesDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysProvinces().Delete(ctx, in)
+ err = service.SysProvinces().Delete(ctx, &req.ProvincesDeleteInp)
return
}
// Edit 更新
func (c *cProvinces) Edit(ctx context.Context, req *provinces.EditReq) (res *provinces.EditRes, err error) {
- var in sysin.ProvincesEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysProvinces().Edit(ctx, in)
+ err = service.SysProvinces().Edit(ctx, &req.ProvincesEditInp)
return
}
// MaxSort 最大排序
func (c *cProvinces) MaxSort(ctx context.Context, req *provinces.MaxSortReq) (res *provinces.MaxSortRes, err error) {
- data, err := service.SysProvinces().MaxSort(ctx, sysin.ProvincesMaxSortInp{})
+ data, err := service.SysProvinces().MaxSort(ctx, &req.ProvincesMaxSortInp)
if err != nil {
return
}
@@ -69,7 +51,7 @@ func (c *cProvinces) MaxSort(ctx context.Context, req *provinces.MaxSortReq) (re
// View 获取指定信息
func (c *cProvinces) View(ctx context.Context, req *provinces.ViewReq) (res *provinces.ViewRes, err error) {
- data, err := service.SysProvinces().View(ctx, sysin.ProvincesViewInp{Id: req.Id})
+ data, err := service.SysProvinces().View(ctx, &req.ProvincesViewInp)
if err != nil {
return
}
@@ -81,67 +63,39 @@ func (c *cProvinces) View(ctx context.Context, req *provinces.ViewReq) (res *pro
// List 查看列表
func (c *cProvinces) List(ctx context.Context, req *provinces.ListReq) (res *provinces.ListRes, err error) {
- var in sysin.ProvincesListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysProvinces().List(ctx, in)
+ list, totalCount, err := service.SysProvinces().List(ctx, &req.ProvincesListInp)
if err != nil {
return
}
res = new(provinces.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
-// Status 更新部门状态
+// Status 更新省市区状态
func (c *cProvinces) Status(ctx context.Context, req *provinces.StatusReq) (res *provinces.StatusRes, err error) {
- var in sysin.ProvincesStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysProvinces().Status(ctx, in)
+ err = service.SysProvinces().Status(ctx, &req.ProvincesStatusInp)
return
}
// ChildrenList 获取省市区下级列表
func (c *cProvinces) ChildrenList(ctx context.Context, req *provinces.ChildrenListReq) (res *provinces.ChildrenListRes, err error) {
- var in sysin.ProvincesChildrenListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysProvinces().ChildrenList(ctx, in)
+ list, totalCount, err := service.SysProvinces().ChildrenList(ctx, &req.ProvincesChildrenListInp)
if err != nil {
return
}
res = new(provinces.ChildrenListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// UniqueId 地区ID是否唯一
func (c *cProvinces) UniqueId(ctx context.Context, req *provinces.UniqueIdReq) (res *provinces.UniqueIdRes, err error) {
- var in sysin.ProvincesUniqueIdInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- data, err := service.SysProvinces().UniqueId(ctx, in)
+ data, err := service.SysProvinces().UniqueId(ctx, &req.ProvincesUniqueIdInp)
if err != nil {
return
}
@@ -153,12 +107,7 @@ func (c *cProvinces) UniqueId(ctx context.Context, req *provinces.UniqueIdReq) (
// Select 省市区选项
func (c *cProvinces) Select(ctx context.Context, req *provinces.SelectReq) (res *provinces.SelectRes, err error) {
- var in sysin.ProvincesSelectInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- data, err := service.SysProvinces().Select(ctx, in)
+ data, err := service.SysProvinces().Select(ctx, &req.ProvincesSelectInp)
if err != nil {
return
}
diff --git a/server/internal/controller/admin/sys/serve_license.go b/server/internal/controller/admin/sys/serve_license.go
new file mode 100644
index 0000000..5dd94d3
--- /dev/null
+++ b/server/internal/controller/admin/sys/serve_license.go
@@ -0,0 +1,74 @@
+// Package sys
+// @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
+// @AutoGenerate Version 2.7.6
+package sys
+
+import (
+ "context"
+ "hotgo/api/admin/servelicense"
+ "hotgo/internal/service"
+)
+
+var (
+ ServeLicense = cServeLicense{}
+)
+
+type cServeLicense struct{}
+
+// List 查看服务授权许可列表
+func (c *cServeLicense) List(ctx context.Context, req *servelicense.ListReq) (res *servelicense.ListRes, err error) {
+ list, totalCount, err := service.SysServeLicense().List(ctx, &req.ServeLicenseListInp)
+ if err != nil {
+ return
+ }
+
+ res = new(servelicense.ListRes)
+ res.List = list
+ res.PageRes.Pack(req, totalCount)
+ return
+}
+
+// Export 导出服务授权许可列表
+func (c *cServeLicense) Export(ctx context.Context, req *servelicense.ExportReq) (res *servelicense.ExportRes, err error) {
+ err = service.SysServeLicense().Export(ctx, &req.ServeLicenseListInp)
+ return
+}
+
+// Edit 更新服务授权许可
+func (c *cServeLicense) Edit(ctx context.Context, req *servelicense.EditReq) (res *servelicense.EditRes, err error) {
+ err = service.SysServeLicense().Edit(ctx, &req.ServeLicenseEditInp)
+ return
+}
+
+// View 获取指定服务授权许可信息
+func (c *cServeLicense) View(ctx context.Context, req *servelicense.ViewReq) (res *servelicense.ViewRes, err error) {
+ data, err := service.SysServeLicense().View(ctx, &req.ServeLicenseViewInp)
+ if err != nil {
+ return
+ }
+
+ res = new(servelicense.ViewRes)
+ res.ServeLicenseViewModel = data
+ return
+}
+
+// Delete 删除服务授权许可
+func (c *cServeLicense) Delete(ctx context.Context, req *servelicense.DeleteReq) (res *servelicense.DeleteRes, err error) {
+ err = service.SysServeLicense().Delete(ctx, &req.ServeLicenseDeleteInp)
+ return
+}
+
+// Status 更新服务授权许可状态
+func (c *cServeLicense) Status(ctx context.Context, req *servelicense.StatusReq) (res *servelicense.StatusRes, err error) {
+ err = service.SysServeLicense().Status(ctx, &req.ServeLicenseStatusInp)
+ return
+}
+
+// AssignRouter 分配服务授权许可路由
+func (c *cServeLicense) AssignRouter(ctx context.Context, req *servelicense.AssignRouterReq) (res *servelicense.AssignRouterRes, err error) {
+ err = service.SysServeLicense().AssignRouter(ctx, &req.ServeLicenseAssignRouterInp)
+ return
+}
diff --git a/server/internal/controller/admin/sys/serve_log.go b/server/internal/controller/admin/sys/serve_log.go
index 7286b14..b3ca4cf 100644
--- a/server/internal/controller/admin/sys/serve_log.go
+++ b/server/internal/controller/admin/sys/serve_log.go
@@ -3,17 +3,12 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/servelog"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -24,55 +19,26 @@ type cServeLog struct{}
// List 查看服务日志列表
func (c *cServeLog) List(ctx context.Context, req *servelog.ListReq) (res *servelog.ListRes, err error) {
- var in sysin.ServeLogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysServeLog().List(ctx, in)
+ list, totalCount, err := service.SysServeLog().List(ctx, &req.ServeLogListInp)
if err != nil {
return
}
res = new(servelog.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
// Export 导出服务日志列表
func (c *cServeLog) Export(ctx context.Context, req *servelog.ExportReq) (res *servelog.ExportRes, err error) {
- var in sysin.ServeLogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysServeLog().Export(ctx, in)
+ err = service.SysServeLog().Export(ctx, &req.ServeLogListInp)
return
}
// View 获取指定服务日志信息
func (c *cServeLog) View(ctx context.Context, req *servelog.ViewReq) (res *servelog.ViewRes, err error) {
- var in sysin.ServeLogViewInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- data, err := service.SysServeLog().View(ctx, in)
+ data, err := service.SysServeLog().View(ctx, &req.ServeLogViewInp)
if err != nil {
return
}
@@ -84,15 +50,6 @@ func (c *cServeLog) View(ctx context.Context, req *servelog.ViewReq) (res *serve
// Delete 删除服务日志
func (c *cServeLog) Delete(ctx context.Context, req *servelog.DeleteReq) (res *servelog.DeleteRes, err error) {
- var in sysin.ServeLogDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.SysServeLog().Delete(ctx, in)
+ err = service.SysServeLog().Delete(ctx, &req.ServeLogDeleteInp)
return
}
diff --git a/server/internal/controller/admin/sys/sms_log.go b/server/internal/controller/admin/sys/sms_log.go
index 7efea74..f7f3872 100644
--- a/server/internal/controller/admin/sys/sms_log.go
+++ b/server/internal/controller/admin/sys/sms_log.go
@@ -7,12 +7,8 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/smslog"
- "hotgo/internal/model/input/form"
- "hotgo/internal/model/input/sysin"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
var (
@@ -23,41 +19,19 @@ type cSmsLog struct{}
// Delete 删除
func (c *cSmsLog) Delete(ctx context.Context, req *smslog.DeleteReq) (res *smslog.DeleteRes, err error) {
- var in sysin.SmsLogDeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysSmsLog().Delete(ctx, in)
+ err = service.SysSmsLog().Delete(ctx, &req.SmsLogDeleteInp)
return
}
// Edit 更新
func (c *cSmsLog) Edit(ctx context.Context, req *smslog.EditReq) (res *smslog.EditRes, err error) {
- var in sysin.SmsLogEditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysSmsLog().Edit(ctx, in)
- return
-}
-
-// MaxSort 最大排序
-func (c *cSmsLog) MaxSort(ctx context.Context, req *smslog.MaxSortReq) (res *smslog.MaxSortRes, err error) {
- data, err := service.SysSmsLog().MaxSort(ctx, sysin.SmsLogMaxSortInp{Id: req.Id})
- if err != nil {
- return
- }
-
- res = new(smslog.MaxSortRes)
- res.Sort = data.Sort
+ err = service.SysSmsLog().Edit(ctx, &req.SmsLogEditInp)
return
}
// View 获取指定信息
func (c *cSmsLog) View(ctx context.Context, req *smslog.ViewReq) (res *smslog.ViewRes, err error) {
- data, err := service.SysSmsLog().View(ctx, sysin.SmsLogViewInp{Id: req.Id})
+ data, err := service.SysSmsLog().View(ctx, &req.SmsLogViewInp)
if err != nil {
return
}
@@ -69,35 +43,19 @@ func (c *cSmsLog) View(ctx context.Context, req *smslog.ViewReq) (res *smslog.Vi
// List 查看列表
func (c *cSmsLog) List(ctx context.Context, req *smslog.ListReq) (res *smslog.ListRes, err error) {
- var in sysin.SmsLogListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.SysSmsLog().List(ctx, in)
+ list, totalCount, err := service.SysSmsLog().List(ctx, &req.SmsLogListInp)
if err != nil {
return
}
res = new(smslog.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
-// Status 更新部门状态
+// Status 更新状态
func (c *cSmsLog) Status(ctx context.Context, req *smslog.StatusReq) (res *smslog.StatusRes, err error) {
- var in sysin.SmsLogStatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysSmsLog().Status(ctx, in)
+ err = service.SysSmsLog().Status(ctx, &req.SmsLogStatusInp)
return
}
diff --git a/server/internal/controller/api/pay/notify.go b/server/internal/controller/api/pay/notify.go
index c9ccf1e..cd05f28 100644
--- a/server/internal/controller/api/pay/notify.go
+++ b/server/internal/controller/api/pay/notify.go
@@ -23,7 +23,7 @@ type cNotify struct{}
// AliPay 支付宝回调
func (c *cNotify) AliPay(ctx context.Context, _ *pay.NotifyAliPayReq) (res *pay.NotifyAliPayRes, err error) {
- if _, err = service.Pay().Notify(ctx, payin.PayNotifyInp{PayType: consts.PayTypeAliPay}); err != nil {
+ if _, err = service.Pay().Notify(ctx, &payin.PayNotifyInp{PayType: consts.PayTypeAliPay}); err != nil {
return nil, err
}
@@ -33,7 +33,7 @@ func (c *cNotify) AliPay(ctx context.Context, _ *pay.NotifyAliPayReq) (res *pay.
// WxPay 微信支付回调
func (c *cNotify) WxPay(ctx context.Context, _ *pay.NotifyWxPayReq) (res *pay.NotifyWxPayRes, err error) {
- if _, err = service.Pay().Notify(ctx, payin.PayNotifyInp{PayType: consts.PayTypeWxPay}); err != nil {
+ if _, err = service.Pay().Notify(ctx, &payin.PayNotifyInp{PayType: consts.PayTypeWxPay}); err != nil {
return
}
@@ -43,7 +43,7 @@ func (c *cNotify) WxPay(ctx context.Context, _ *pay.NotifyWxPayReq) (res *pay.No
// QQPay QQ支付回调
func (c *cNotify) QQPay(ctx context.Context, _ *pay.NotifyQQPayReq) (res *pay.NotifyQQPayRes, err error) {
- if _, err = service.Pay().Notify(ctx, payin.PayNotifyInp{PayType: consts.PayTypeQQPay}); err != nil {
+ if _, err = service.Pay().Notify(ctx, &payin.PayNotifyInp{PayType: consts.PayTypeQQPay}); err != nil {
return
}
diff --git a/server/internal/controller/websocket/handler/admin/monitor.go b/server/internal/controller/websocket/handler/admin/monitor.go
index 48c6368..33dfc77 100644
--- a/server/internal/controller/websocket/handler/admin/monitor.go
+++ b/server/internal/controller/websocket/handler/admin/monitor.go
@@ -64,9 +64,9 @@ func (c *cMonitor) RunInfo(client *websocket.Client, req *websocket.WRequest) {
"intranet_ip": meta.IntranetIP,
"public_ip": meta.PublicIP,
- // GO运行信息
- "goName": "Golang",
- "version": runtime.Version(),
+ // 运行信息
+ "version": runtime.Version(), // GO 版本
+ "hgVersion": consts.VersionApp, // HG 版本
"startTime": gtime.New(meta.STartTime),
"runTime": gtime.Now().Timestamp() - meta.STartTime,
"rootPath": runtime.GOROOT(),
@@ -111,22 +111,22 @@ func (c *cMonitor) Trends(client *websocket.Client, req *websocket.WRequest) {
)
if cpuErr != nil {
- g.Log().Warningf(client.Context(), "read CPU info fail:%+v", cpuErr)
+ g.Log().Infof(client.Context(), "read CPU info fail:%+v", cpuErr)
mCpu = []cpu.InfoStat{{VendorID: "", ModelName: ""}}
}
if memErr != nil {
- g.Log().Warningf(client.Context(), "read mem info fail:%+v", memErr)
+ g.Log().Infof(client.Context(), "read mem info fail:%+v", memErr)
mMem = new(mem.VirtualMemoryStat)
}
if diskErr != nil {
- g.Log().Warningf(client.Context(), "read disk info fail:%+v", diskErr)
+ g.Log().Infof(client.Context(), "read disk info fail:%+v", diskErr)
mDisk = new(disk.UsageStat)
}
if processErr != nil {
- g.Log().Warningf(client.Context(), "read process.Pids fail:%+v", processErr)
+ g.Log().Infof(client.Context(), "read process.Pids fail:%+v", processErr)
}
// cpu使用率
diff --git a/server/internal/dao/internal/addon_hgexample_table.go b/server/internal/dao/internal/addon_hgexample_table.go
index e34c75f..8b7e93e 100644
--- a/server/internal/dao/internal/addon_hgexample_table.go
+++ b/server/internal/dao/internal/addon_hgexample_table.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_cash.go b/server/internal/dao/internal/admin_cash.go
index 0467615..b92d0fa 100644
--- a/server/internal/dao/internal/admin_cash.go
+++ b/server/internal/dao/internal/admin_cash.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_credits_log.go b/server/internal/dao/internal/admin_credits_log.go
index fc092f4..86514e4 100644
--- a/server/internal/dao/internal/admin_credits_log.go
+++ b/server/internal/dao/internal/admin_credits_log.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_dept.go b/server/internal/dao/internal/admin_dept.go
index 13fd209..addcf69 100644
--- a/server/internal/dao/internal/admin_dept.go
+++ b/server/internal/dao/internal/admin_dept.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_member.go b/server/internal/dao/internal/admin_member.go
index 48a77fa..98d5796 100644
--- a/server/internal/dao/internal/admin_member.go
+++ b/server/internal/dao/internal/admin_member.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_member_post.go b/server/internal/dao/internal/admin_member_post.go
index e5c2f95..be5a754 100644
--- a/server/internal/dao/internal/admin_member_post.go
+++ b/server/internal/dao/internal/admin_member_post.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_member_role.go b/server/internal/dao/internal/admin_member_role.go
index 093b895..e62f5c8 100644
--- a/server/internal/dao/internal/admin_member_role.go
+++ b/server/internal/dao/internal/admin_member_role.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_menu.go b/server/internal/dao/internal/admin_menu.go
index 9628803..81495a5 100644
--- a/server/internal/dao/internal/admin_menu.go
+++ b/server/internal/dao/internal/admin_menu.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_notice.go b/server/internal/dao/internal/admin_notice.go
index db1768f..cc0bd06 100644
--- a/server/internal/dao/internal/admin_notice.go
+++ b/server/internal/dao/internal/admin_notice.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_notice_read.go b/server/internal/dao/internal/admin_notice_read.go
index 112d964..6a25522 100644
--- a/server/internal/dao/internal/admin_notice_read.go
+++ b/server/internal/dao/internal/admin_notice_read.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_oauth.go b/server/internal/dao/internal/admin_oauth.go
index 51ed37d..b3a9330 100644
--- a/server/internal/dao/internal/admin_oauth.go
+++ b/server/internal/dao/internal/admin_oauth.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_order.go b/server/internal/dao/internal/admin_order.go
index 5e69457..101af57 100644
--- a/server/internal/dao/internal/admin_order.go
+++ b/server/internal/dao/internal/admin_order.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_post.go b/server/internal/dao/internal/admin_post.go
index 23c4389..0c590e3 100644
--- a/server/internal/dao/internal/admin_post.go
+++ b/server/internal/dao/internal/admin_post.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
@@ -24,7 +24,7 @@ type AdminPostColumns struct {
Code string // 岗位编码
Name string // 岗位名称
Remark string // 备注
- Sort string // 显示顺序
+ Sort string // 排序
Status string // 状态
CreatedAt string // 创建时间
UpdatedAt string // 更新时间
diff --git a/server/internal/dao/internal/admin_role.go b/server/internal/dao/internal/admin_role.go
index 3e263c9..5e5e16f 100644
--- a/server/internal/dao/internal/admin_role.go
+++ b/server/internal/dao/internal/admin_role.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_role_casbin.go b/server/internal/dao/internal/admin_role_casbin.go
index 2dd2d9c..257ccf7 100644
--- a/server/internal/dao/internal/admin_role_casbin.go
+++ b/server/internal/dao/internal/admin_role_casbin.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/admin_role_menu.go b/server/internal/dao/internal/admin_role_menu.go
index 021a241..40b9978 100644
--- a/server/internal/dao/internal/admin_role_menu.go
+++ b/server/internal/dao/internal/admin_role_menu.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/pay_log.go b/server/internal/dao/internal/pay_log.go
index bd96565..d42efe6 100644
--- a/server/internal/dao/internal/pay_log.go
+++ b/server/internal/dao/internal/pay_log.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/pay_refund.go b/server/internal/dao/internal/pay_refund.go
index 7c4a419..83d7fce 100644
--- a/server/internal/dao/internal/pay_refund.go
+++ b/server/internal/dao/internal/pay_refund.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_addons_config.go b/server/internal/dao/internal/sys_addons_config.go
index b7c5761..d6e0c71 100644
--- a/server/internal/dao/internal/sys_addons_config.go
+++ b/server/internal/dao/internal/sys_addons_config.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_attachment.go b/server/internal/dao/internal/sys_attachment.go
index c8e4435..e76272f 100644
--- a/server/internal/dao/internal/sys_attachment.go
+++ b/server/internal/dao/internal/sys_attachment.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
@@ -27,7 +27,7 @@ type SysAttachmentColumns struct {
Drive string // 上传驱动
Name string // 文件原始名
Kind string // 上传类型
- MetaType string // 文件类型
+ MimeType string // 扩展类型
NaiveType string // NaiveUI类型
Path string // 本地路径
FileUrl string // url
@@ -48,7 +48,7 @@ var sysAttachmentColumns = SysAttachmentColumns{
Drive: "drive",
Name: "name",
Kind: "kind",
- MetaType: "meta_type",
+ MimeType: "mime_type",
NaiveType: "naive_type",
Path: "path",
FileUrl: "file_url",
diff --git a/server/internal/dao/internal/sys_blacklist.go b/server/internal/dao/internal/sys_blacklist.go
index 49bac2a..99498bf 100644
--- a/server/internal/dao/internal/sys_blacklist.go
+++ b/server/internal/dao/internal/sys_blacklist.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_config.go b/server/internal/dao/internal/sys_config.go
index 669d15f..cfd138a 100644
--- a/server/internal/dao/internal/sys_config.go
+++ b/server/internal/dao/internal/sys_config.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_cron.go b/server/internal/dao/internal/sys_cron.go
index 42cfb0b..e64818d 100644
--- a/server/internal/dao/internal/sys_cron.go
+++ b/server/internal/dao/internal/sys_cron.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_cron_group.go b/server/internal/dao/internal/sys_cron_group.go
index 34b4955..78c617f 100644
--- a/server/internal/dao/internal/sys_cron_group.go
+++ b/server/internal/dao/internal/sys_cron_group.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_dict_data.go b/server/internal/dao/internal/sys_dict_data.go
index ce2e3b4..7ea6495 100644
--- a/server/internal/dao/internal/sys_dict_data.go
+++ b/server/internal/dao/internal/sys_dict_data.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_dict_type.go b/server/internal/dao/internal/sys_dict_type.go
index ca076ee..5599329 100644
--- a/server/internal/dao/internal/sys_dict_type.go
+++ b/server/internal/dao/internal/sys_dict_type.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_ems_log.go b/server/internal/dao/internal/sys_ems_log.go
index 84f9967..ed44cd4 100644
--- a/server/internal/dao/internal/sys_ems_log.go
+++ b/server/internal/dao/internal/sys_ems_log.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_gen_codes.go b/server/internal/dao/internal/sys_gen_codes.go
index 62a3426..6e0784b 100644
--- a/server/internal/dao/internal/sys_gen_codes.go
+++ b/server/internal/dao/internal/sys_gen_codes.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_gen_curd_demo.go b/server/internal/dao/internal/sys_gen_curd_demo.go
index 7976c25..3ac3737 100644
--- a/server/internal/dao/internal/sys_gen_curd_demo.go
+++ b/server/internal/dao/internal/sys_gen_curd_demo.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_log.go b/server/internal/dao/internal/sys_log.go
index 4c76de6..d3af6c1 100644
--- a/server/internal/dao/internal/sys_log.go
+++ b/server/internal/dao/internal/sys_log.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_login_log.go b/server/internal/dao/internal/sys_login_log.go
index 33103f4..01ad0fa 100644
--- a/server/internal/dao/internal/sys_login_log.go
+++ b/server/internal/dao/internal/sys_login_log.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_provinces.go b/server/internal/dao/internal/sys_provinces.go
index 601ff96..76d3510 100644
--- a/server/internal/dao/internal/sys_provinces.go
+++ b/server/internal/dao/internal/sys_provinces.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_serve_license.go b/server/internal/dao/internal/sys_serve_license.go
index 0ec921f..b87e57f 100644
--- a/server/internal/dao/internal/sys_serve_license.go
+++ b/server/internal/dao/internal/sys_serve_license.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
@@ -25,16 +25,14 @@ type SysServeLicenseColumns struct {
Name string // 许可名称
Appid string // 应用ID
SecretKey string // 应用秘钥
- Desc string // 授权说明
RemoteAddr string // 最后连接地址
- Online string // 在线数量
- OnlineLimit string // 在线数量限制,默认1
+ OnlineLimit string // 在线限制
LoginTimes string // 登录次数
LastLoginAt string // 最后登录时间
- LastActiveAt string // 最后活跃时间
+ LastActiveAt string // 最后心跳
Routes string // 路由表,空使用默认分组路由
- AllowedIps string // 白名单,*代表所有,只有允许的IP才能连接到tcp服务
- EndAt string // 授权结束时间
+ AllowedIps string // IP白名单
+ EndAt string // 授权有效期
Remark string // 备注
Status string // 状态
CreatedAt string // 创建时间
@@ -48,9 +46,7 @@ var sysServeLicenseColumns = SysServeLicenseColumns{
Name: "name",
Appid: "appid",
SecretKey: "secret_key",
- Desc: "desc",
RemoteAddr: "remote_addr",
- Online: "online",
OnlineLimit: "online_limit",
LoginTimes: "login_times",
LastLoginAt: "last_login_at",
diff --git a/server/internal/dao/internal/sys_serve_log.go b/server/internal/dao/internal/sys_serve_log.go
index 7ce0554..df9c7e8 100644
--- a/server/internal/dao/internal/sys_serve_log.go
+++ b/server/internal/dao/internal/sys_serve_log.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/sys_sms_log.go b/server/internal/dao/internal/sys_sms_log.go
index 113dcb2..0103dea 100644
--- a/server/internal/dao/internal/sys_sms_log.go
+++ b/server/internal/dao/internal/sys_sms_log.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/dao/internal/test_category.go b/server/internal/dao/internal/test_category.go
index e779599..0a76820 100644
--- a/server/internal/dao/internal/test_category.go
+++ b/server/internal/dao/internal/test_category.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
diff --git a/server/internal/global/init.go b/server/internal/global/init.go
index b4bedf5..0cc3c31 100644
--- a/server/internal/global/init.go
+++ b/server/internal/global/init.go
@@ -48,6 +48,9 @@ func Init(ctx context.Context) {
// 初始化功能库配置
service.SysConfig().InitConfig(ctx)
+
+ // 加载超管数据
+ service.AdminMember().LoadSuperAdmin(ctx)
}
// LoggingServeLogHandler 服务日志处理
diff --git a/server/internal/library/casbin/enforcer.go b/server/internal/library/casbin/enforcer.go
index d2f6cf3..7744397 100644
--- a/server/internal/library/casbin/enforcer.go
+++ b/server/internal/library/casbin/enforcer.go
@@ -52,10 +52,9 @@ func loadPermissions(ctx context.Context) {
Permissions string `json:"permissions"`
}
var (
- rules [][]string
- polices []*Policy
- err error
- superRoleKey = g.Cfg().MustGet(ctx, "hotgo.admin.superRoleKey")
+ rules [][]string
+ polices []*Policy
+ err error
)
err = g.Model("hg_admin_role r").
@@ -65,7 +64,7 @@ func loadPermissions(ctx context.Context) {
Where("r.status", consts.StatusEnabled).
Where("m.status", consts.StatusEnabled).
Where("m.permissions !=?", "").
- Where("r.key !=?", superRoleKey.String()).
+ Where("r.key !=?", consts.SuperRoleKey).
Scan(&polices)
if err != nil {
g.Log().Fatalf(ctx, "loadPermissions Scan err:%v", err)
diff --git a/server/internal/library/cron/cron.go b/server/internal/library/cron/cron.go
index a37ab44..1e80ae4 100644
--- a/server/internal/library/cron/cron.go
+++ b/server/internal/library/cron/cron.go
@@ -25,9 +25,11 @@ var crons = &cronManager{
tasks: make(map[string]*TaskItem),
}
-// cronStrategy 任务接口
-type cronStrategy interface {
+// Cron 定时任务接口
+type Cron interface {
+ // GetName 获取任务名称
GetName() string
+ // Execute 执行一次任务
Execute(ctx context.Context)
}
@@ -51,7 +53,7 @@ func Logger() *glog.Logger {
}
// Register 注册任务
-func Register(c cronStrategy) {
+func Register(c Cron) {
crons.Lock()
defer crons.Unlock()
@@ -72,6 +74,9 @@ func StopALL() {
// StartALL 启动所有任务
func StartALL(sysCron []*entity.SysCron) (err error) {
+ crons.Lock()
+ defer crons.Unlock()
+
if len(crons.tasks) == 0 {
g.Log().Debug(gctx.GetInitCtx(), "no scheduled task is available.")
return
@@ -156,6 +161,9 @@ func Stop(sysCron *entity.SysCron) (err error) {
// Once 立即执行一次某个任务
func Once(ctx context.Context, sysCron *entity.SysCron) error {
+ crons.RLock()
+ defer crons.RUnlock()
+
for _, v := range crons.tasks {
if v.Name == sysCron.Name {
simple.SafeGo(ctx, func(ctx context.Context) {
diff --git a/server/internal/library/hggen/hggen.go b/server/internal/library/hggen/hggen.go
index fe9ba66..1ae1543 100644
--- a/server/internal/library/hggen/hggen.go
+++ b/server/internal/library/hggen/hggen.go
@@ -6,6 +6,9 @@
package hggen
import (
+ _ "hotgo/internal/library/hggen/internal/cmd/gendao"
+ _ "unsafe"
+
"context"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
@@ -23,6 +26,9 @@ import (
"sort"
)
+//go:linkname doGenDaoForArray hotgo/internal/library/hggen/internal/cmd/gendao.doGenDaoForArray
+func doGenDaoForArray(ctx context.Context, index int, in gendao.CGenDaoInput)
+
// Dao 生成数据库实体
func Dao(ctx context.Context) (err error) {
for _, v := range daoConfig {
@@ -31,7 +37,7 @@ func Dao(ctx context.Context) (err error) {
if err != nil {
return
}
- gendao.DoGenDaoForArray(ctx, inp)
+ doGenDaoForArray(ctx, -1, inp)
}
return
}
@@ -52,11 +58,11 @@ func ServiceWithCfg(ctx context.Context, cfg ...genservice.CGenServiceInput) (er
}
// TableColumns 获取指定表生成字段列表
-func TableColumns(ctx context.Context, in sysin.GenCodesColumnListInp) (fields []*sysin.GenCodesColumnListModel, err error) {
+func TableColumns(ctx context.Context, in *sysin.GenCodesColumnListInp) (fields []*sysin.GenCodesColumnListModel, err error) {
return views.DoTableColumns(ctx, in, GetDaoConfig(in.Name))
}
-func TableSelects(ctx context.Context, in sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error) {
+func TableSelects(ctx context.Context, in *sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error) {
res = new(sysin.GenCodesSelectsModel)
res.GenType, err = GenTypeSelect(ctx)
if err != nil {
@@ -110,7 +116,7 @@ func TableSelects(ctx context.Context, in sysin.GenCodesSelectsInp) (res *sysin.
}
sort.Sort(res.FormRole)
- dictMode, err := service.SysDictType().TreeSelect(ctx, sysin.DictTreeSelectInp{})
+ dictMode, err := service.SysDictType().TreeSelect(ctx, &sysin.DictTreeSelectInp{})
if err != nil {
return
}
@@ -183,7 +189,7 @@ func DbSelect(ctx context.Context) (res form.Selects) {
}
// Preview 生成预览
-func Preview(ctx context.Context, in sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error) {
+func Preview(ctx context.Context, in *sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error) {
genConfig, err := service.SysConfig().GetLoadGenerate(ctx)
if err != nil {
return nil, err
@@ -209,7 +215,7 @@ func Preview(ctx context.Context, in sysin.GenCodesPreviewInp) (res *sysin.GenCo
}
// Build 提交生成
-func Build(ctx context.Context, in sysin.GenCodesBuildInp) (err error) {
+func Build(ctx context.Context, in *sysin.GenCodesBuildInp) (err error) {
genConfig, err := service.SysConfig().GetLoadGenerate(ctx)
if err != nil {
return err
@@ -217,7 +223,7 @@ func Build(ctx context.Context, in sysin.GenCodesBuildInp) (err error) {
switch in.GenType {
case consts.GenCodesTypeCurd:
- pin := sysin.GenCodesPreviewInp(in)
+ pin := &sysin.GenCodesPreviewInp{SysGenCodes: in.SysGenCodes}
return views.Curd.DoBuild(ctx, &views.CurdBuildInput{
PreviewIn: &views.CurdPreviewInput{
In: pin,
diff --git a/server/internal/library/hggen/internal/cmd/cmd.go b/server/internal/library/hggen/internal/cmd/cmd.go
index 3a7e9c9..70c6290 100644
--- a/server/internal/library/hggen/internal/cmd/cmd.go
+++ b/server/internal/library/hggen/internal/cmd/cmd.go
@@ -1,9 +1,16 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
"context"
"strings"
+ "github.com/gogf/gf/v2"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/gogf/gf/v2/util/gtag"
@@ -48,17 +55,21 @@ func (c cGF) Index(ctx context.Context, in cGFInput) (out *cGFOutput, err error)
_, err = Version.Index(ctx, cVersionInput{})
return
}
+ answer := "n"
// No argument or option, do installation checks.
- if !service.Install.IsInstalled() {
+ if data, isInstalled := service.Install.IsInstalled(); !isInstalled {
mlog.Print("hi, it seams it's the first time you installing gf cli.")
- s := gcmd.Scanf("do you want to install gf binary to your system? [y/n]: ")
- if strings.EqualFold(s, "y") {
- if err = service.Install.Run(ctx); err != nil {
- return
- }
- gcmd.Scan("press `Enter` to exit...")
+ answer = gcmd.Scanf("do you want to install gf(%s) binary to your system? [y/n]: ", gf.VERSION)
+ } else if !data.IsSelf {
+ mlog.Print("hi, you have installed gf cli.")
+ answer = gcmd.Scanf("do you want to install gf(%s) binary to your system? [y/n]: ", gf.VERSION)
+ }
+ if strings.EqualFold(answer, "y") {
+ if err = service.Install.Run(ctx); err != nil {
return
}
+ gcmd.Scan("press `Enter` to exit...")
+ return
}
// Print help content.
gcmd.CommandFromCtx(ctx).Print()
diff --git a/server/internal/library/hggen/internal/cmd/cmd_build.go b/server/internal/library/hggen/internal/cmd/cmd_build.go
index 1b5d909..fb869d5 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_build.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_build.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
@@ -123,15 +129,21 @@ type cBuildInput struct {
VarMap g.Map `short:"r" name:"varMap" brief:"custom built embedded variable into binary"`
PackSrc string `short:"ps" name:"packSrc" brief:"pack one or more folders into one go file before building"`
PackDst string `short:"pd" name:"packDst" brief:"temporary go file path for pack, this go file will be automatically removed after built" d:"internal/packed/build_pack_data.go"`
- ExitWhenError bool `short:"ew" name:"exitWhenError" brief:"exit building when any error occurs, default is false" orphan:"true"`
+ ExitWhenError bool `short:"ew" name:"exitWhenError" brief:"exit building when any error occurs, specially for multiple arch and system buildings. default is false" orphan:"true"`
+ DumpENV bool `short:"de" name:"dumpEnv" brief:"dump current go build environment before building binary" orphan:"true"`
}
type cBuildOutput struct{}
func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, err error) {
+ // print used go env
+ if in.DumpENV {
+ _, _ = Env.Index(ctx, cEnvInput{})
+ }
+
mlog.SetHeaderPrint(true)
- mlog.Debugf(`build input: %+v`, in)
+ mlog.Debugf(`build command input: %+v`, in)
// Necessary check.
if gproc.SearchBinary("go") == "" {
mlog.Fatalf(`command "go" not found in your environment, please install golang first to proceed this command`)
@@ -236,7 +248,7 @@ func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, e
if len(customSystems) > 0 && customSystems[0] != "all" && !gstr.InArray(customSystems, system) {
continue
}
- for arch, _ := range item {
+ for arch := range item {
if len(customArches) > 0 && customArches[0] != "all" && !gstr.InArray(customArches, arch) {
continue
}
@@ -299,8 +311,9 @@ func (c cBuild) getBuildInVarStr(ctx context.Context, in cBuildInput) string {
if buildInVarMap == nil {
buildInVarMap = make(g.Map)
}
- buildInVarMap["builtGit"] = c.getGitCommit(ctx)
- buildInVarMap["builtTime"] = gtime.Now().String()
+ buildInVarMap[`builtGit`] = c.getGitCommit(ctx)
+ buildInVarMap[`builtTime`] = gtime.Now().String()
+ buildInVarMap[`builtVersion`] = in.Version
b, err := json.Marshal(buildInVarMap)
if err != nil {
mlog.Fatal(err)
diff --git a/server/internal/library/hggen/internal/cmd/cmd_docker.go b/server/internal/library/hggen/internal/cmd/cmd_docker.go
index 1160b63..3b53e74 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_docker.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_docker.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
@@ -33,6 +39,7 @@ gf docker main.go
gf docker main.go -t hub.docker.com/john/image:tag
gf docker main.go -t hub.docker.com/john/image:tag
gf docker main.go -p -t hub.docker.com/john/image:tag
+gf docker main.go -p -tp ["hub.docker.com/john","hub.docker.com/smith"] -tn image:tag
`
cDockerDc = `
The "docker" command builds the GF project to a docker images.
@@ -45,6 +52,7 @@ You should have docker installed, and there must be a Dockerfile in the root of
cDockerFileBrief = `file path of the Dockerfile. it's "manifest/docker/Dockerfile" in default`
cDockerShellBrief = `path of the shell file which is executed before docker build`
cDockerPushBrief = `auto push the docker image to docker registry if "-t" option passed`
+ cDockerTagBrief = `full tag for this docker, pattern like "xxx.xxx.xxx/image:tag"`
cDockerTagNameBrief = `tag name for this docker, pattern like "image:tag". this option is required with TagPrefixes`
cDockerTagPrefixesBrief = `tag prefixes for this docker, which are used for docker push. this option is required with TagName`
cDockerExtraBrief = `extra build options passed to "docker image"`
@@ -61,6 +69,7 @@ func init() {
`cDockerShellBrief`: cDockerShellBrief,
`cDockerBuildBrief`: cDockerBuildBrief,
`cDockerPushBrief`: cDockerPushBrief,
+ `cDockerTagBrief`: cDockerTagBrief,
`cDockerTagNameBrief`: cDockerTagNameBrief,
`cDockerTagPrefixesBrief`: cDockerTagPrefixesBrief,
`cDockerExtraBrief`: cDockerExtraBrief,
@@ -69,10 +78,11 @@ func init() {
type cDockerInput struct {
g.Meta `name:"docker" config:"gfcli.docker"`
- Main string `name:"MAIN" arg:"true" brief:"{cDockerMainBrief}" d:"main.go"`
+ Main string `name:"MAIN" arg:"true" brief:"{cDockerMainBrief}" d:"main.go"`
File string `name:"file" short:"f" brief:"{cDockerFileBrief}" d:"manifest/docker/Dockerfile"`
Shell string `name:"shell" short:"s" brief:"{cDockerShellBrief}" d:"manifest/docker/docker.sh"`
- Build string `name:"build" short:"b" brief:"{cDockerBuildBrief}" d:"-a amd64 -s linux"`
+ Build string `name:"build" short:"b" brief:"{cDockerBuildBrief}"`
+ Tag string `name:"tag" short:"t" brief:"{cDockerTagBrief}"`
TagName string `name:"tagName" short:"tn" brief:"{cDockerTagNameBrief}" v:"required-with:TagPrefixes"`
TagPrefixes []string `name:"tagPrefixes" short:"tp" brief:"{cDockerTagPrefixesBrief}" v:"required-with:TagName"`
Push bool `name:"push" short:"p" brief:"{cDockerPushBrief}" orphan:"true"`
@@ -87,17 +97,23 @@ func (c cDocker) Index(ctx context.Context, in cDockerInput) (out *cDockerOutput
mlog.Fatalf(`command "docker" not found in your environment, please install docker first to proceed this command`)
}
+ mlog.Debugf(`docker command input: %+v`, in)
+
// Binary build.
- in.Build += " --exit"
- if in.Main != "" {
- if err = gproc.ShellRun(ctx, fmt.Sprintf(`gf build %s %s`, in.Main, in.Build)); err != nil {
- return
+ if in.Main != "" && in.Build != "" {
+ in.Build += " --exitWhenError"
+ if in.Main != "" {
+ if err = gproc.ShellRun(ctx, fmt.Sprintf(`gf build %s %s`, in.Main, in.Build)); err != nil {
+ mlog.Debugf(`build binary failed with error: %+v`, err)
+ return
+ }
}
}
// Shell executing.
if in.Shell != "" && gfile.Exists(in.Shell) {
if err = c.exeDockerShell(ctx, in.Shell); err != nil {
+ mlog.Debugf(`build docker failed with error: %+v`, err)
return
}
}
@@ -114,7 +130,7 @@ func (c cDocker) Index(ctx context.Context, in cDockerInput) (out *cDockerOutput
}
}
if len(dockerTags) == 0 {
- dockerTags = []string{""}
+ dockerTags = []string{in.Tag}
}
for i, dockerTag := range dockerTags {
if i > 0 {
diff --git a/server/internal/library/hggen/internal/cmd/cmd_env.go b/server/internal/library/hggen/internal/cmd/cmd_env.go
index 581dd35..0954ad9 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_env.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_env.go
@@ -1,14 +1,21 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
"bytes"
"context"
+ "github.com/olekukonko/tablewriter"
+
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
- "github.com/olekukonko/tablewriter"
"hotgo/internal/library/hggen/internal/utility/mlog"
)
diff --git a/server/internal/library/hggen/internal/cmd/cmd_fix.go b/server/internal/library/hggen/internal/cmd/cmd_fix.go
index c9e6cba..2e605ee 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_fix.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_fix.go
@@ -1,8 +1,17 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
"context"
+ "github.com/gogf/gf/v2/os/gproc"
+ "github.com/gogf/gf/v2/text/gregex"
+
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
@@ -19,7 +28,9 @@ type cFix struct {
}
type cFixInput struct {
- g.Meta `name:"fix"`
+ g.Meta `name:"fix"`
+ Path string `name:"path" short:"p" brief:"directory path, it uses current working directory in default"`
+ Version string `name:"version" short:"v" brief:"custom specified version to fix, leave it empty to auto detect"`
}
type cFixOutput struct{}
@@ -30,35 +41,46 @@ type cFixItem struct {
}
func (c cFix) Index(ctx context.Context, in cFixInput) (out *cFixOutput, err error) {
- mlog.Print(`start auto fixing...`)
- defer mlog.Print(`done!`)
- err = c.doFix()
+
+ if in.Path == "" {
+ in.Path = gfile.Pwd()
+ }
+ if in.Version == "" {
+ in.Version, err = c.autoDetectVersion(in)
+ if err != nil {
+ mlog.Fatal(err)
+ }
+ if in.Version == "" {
+ mlog.Print(`no GoFrame usage found, exit fixing`)
+ return
+ }
+ mlog.Debugf(`current GoFrame version auto detect "%s"`, in.Version)
+ }
+
+ if !gproc.IsChild() {
+ mlog.Printf(`start auto fixing directory path "%s"...`, in.Path)
+ defer mlog.Print(`done!`)
+ }
+
+ err = c.doFix(in)
return
}
-func (c cFix) doFix() (err error) {
- version, err := c.getVersion()
- if err != nil {
- mlog.Fatal(err)
- }
- if version == "" {
- mlog.Print(`no GoFrame usage found, exit fixing`)
- return
- }
- mlog.Debugf(`current GoFrame version found "%s"`, version)
+func (c cFix) doFix(in cFixInput) (err error) {
var items = []cFixItem{
{Version: "v2.3", Func: c.doFixV23},
+ {Version: "v2.5", Func: c.doFixV25},
}
for _, item := range items {
- if gstr.CompareVersionGo(version, item.Version) < 0 {
+ if gstr.CompareVersionGo(in.Version, item.Version) < 0 {
mlog.Debugf(
- `current GoFrame version "%s" is lesser than "%s", nothing to do`,
- version, item.Version,
+ `current GoFrame or contrib package version "%s" is lesser than "%s", nothing to do`,
+ in.Version, item.Version,
)
continue
}
- if err = item.Func(version); err != nil {
+ if err = item.Func(in.Version); err != nil {
return
}
}
@@ -68,16 +90,47 @@ func (c cFix) doFix() (err error) {
// doFixV23 fixes code when upgrading to GoFrame v2.3.
func (c cFix) doFixV23(version string) error {
replaceFunc := func(path, content string) string {
+ // gdb.TX from struct to interface.
content = gstr.Replace(content, "*gdb.TX", "gdb.TX")
+ // function name changes for package gtcp/gudp.
+ if gstr.Contains(content, "/gf/v2/net/gtcp") || gstr.Contains(content, "/gf/v2/net/gudp") {
+ content = gstr.ReplaceByMap(content, g.MapStrStr{
+ ".SetSendDeadline": ".SetDeadlineSend",
+ ".SetReceiveDeadline": ".SetDeadlineRecv",
+ ".SetReceiveBufferWait": ".SetBufferWaitRecv",
+ })
+ }
return content
}
return gfile.ReplaceDirFunc(replaceFunc, ".", "*.go", true)
}
-func (c cFix) getVersion() (string, error) {
+// doFixV25 fixes code when upgrading to GoFrame v2.5.
+func (c cFix) doFixV25(version string) (err error) {
+ replaceFunc := func(path, content string) string {
+ content, err = c.doFixV25Content(content)
+ return content
+ }
+ return gfile.ReplaceDirFunc(replaceFunc, ".", "*.go", true)
+}
+
+func (c cFix) doFixV25Content(content string) (newContent string, err error) {
+ newContent = content
+ if gstr.Contains(content, `.BindHookHandlerByMap(`) {
+ var pattern = `\.BindHookHandlerByMap\((.+?), map\[string\]ghttp\.HandlerFunc`
+ newContent, err = gregex.ReplaceString(
+ pattern,
+ `.BindHookHandlerByMap($1, map[ghttp.HookName]ghttp.HandlerFunc`,
+ content,
+ )
+ }
+ return
+}
+
+func (c cFix) autoDetectVersion(in cFixInput) (string, error) {
var (
err error
- path = "go.mod"
+ path = gfile.Join(in.Path, "go.mod")
version string
)
if !gfile.Exists(path) {
@@ -86,7 +139,7 @@ func (c cFix) getVersion() (string, error) {
err = gfile.ReadLines(path, func(line string) error {
array := gstr.SplitAndTrim(line, " ")
if len(array) > 0 {
- if array[0] == gfPackage {
+ if gstr.HasPrefix(array[0], gfPackage) {
version = array[1]
}
}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_fix_test.go b/server/internal/library/hggen/internal/cmd/cmd_fix_test.go
new file mode 100644
index 0000000..70d8700
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/cmd_fix_test.go
@@ -0,0 +1,20 @@
+package cmd
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/gogf/gf/v2/test/gtest"
+)
+
+func Test_Fix_doFixV25Content(t *testing.T) {
+ gtest.C(t, func(t *gtest.T) {
+ var (
+ content = gtest.DataContent(`fix25_content.go.txt`)
+ f = cFix{}
+ )
+ newContent, err := f.doFixV25Content(content)
+ t.AssertNil(err)
+ fmt.Println(newContent)
+ })
+}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_gen.go b/server/internal/library/hggen/internal/cmd/cmd_gen.go
index 0e9ffec..10f03da 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_gen.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_gen.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
@@ -13,6 +19,7 @@ type cGen struct {
g.Meta `name:"gen" brief:"{cGenBrief}" dc:"{cGenDc}"`
cGenDao
cGenEnums
+ cGenCtrl
cGenPb
cGenPbEntity
cGenService
diff --git a/server/internal/library/hggen/internal/cmd/cmd_gen_ctrl.go b/server/internal/library/hggen/internal/cmd/cmd_gen_ctrl.go
new file mode 100644
index 0000000..cd116ac
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/cmd_gen_ctrl.go
@@ -0,0 +1,15 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package cmd
+
+import (
+ "hotgo/internal/library/hggen/internal/cmd/genctrl"
+)
+
+type (
+ cGenCtrl = genctrl.CGenCtrl
+)
diff --git a/server/internal/library/hggen/internal/cmd/cmd_gen_dao.go b/server/internal/library/hggen/internal/cmd/cmd_gen_dao.go
index 8d44406..71f92d6 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_gen_dao.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_gen_dao.go
@@ -1,8 +1,15 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
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/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"
diff --git a/server/internal/library/hggen/internal/cmd/cmd_gen_pb.go b/server/internal/library/hggen/internal/cmd/cmd_gen_pb.go
index 6fc28e8..1833d89 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_gen_pb.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_gen_pb.go
@@ -1,79 +1,13 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
-import (
- "context"
- "fmt"
-
- "github.com/gogf/gf/v2/container/gset"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/os/genv"
- "github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/os/gproc"
- "hotgo/internal/library/hggen/internal/utility/mlog"
-)
+import "hotgo/internal/library/hggen/internal/cmd/genpb"
type (
- cGenPb struct{}
- cGenPbInput struct {
- g.Meta `name:"pb" brief:"parse proto files and generate protobuf go files"`
- }
- cGenPbOutput struct{}
+ cGenPb = genpb.CGenPb
)
-
-func (c cGenPb) Pb(ctx context.Context, in cGenPbInput) (out *cGenPbOutput, err error) {
- // Necessary check.
- if gproc.SearchBinary("protoc") == "" {
- mlog.Fatalf(`command "protoc" not found in your environment, please install protoc first to proceed this command`)
- }
-
- // protocol fold checks.
- protoFolder := "protocol"
- if !gfile.Exists(protoFolder) {
- mlog.Fatalf(`proto files folder "%s" does not exist`, protoFolder)
- }
- // folder scanning.
- files, err := gfile.ScanDirFile(protoFolder, "*.proto", true)
- if err != nil {
- mlog.Fatal(err)
- }
- if len(files) == 0 {
- mlog.Fatalf(`no proto files found in folder "%s"`, protoFolder)
- }
- dirSet := gset.NewStrSet()
- for _, file := range files {
- dirSet.Add(gfile.Dir(file))
- }
- var (
- servicePath = gfile.RealPath(".")
- goPathSrc = gfile.RealPath(gfile.Join(genv.Get("GOPATH").String(), "src"))
- )
- dirSet.Iterator(func(protoDirPath string) bool {
- parsingCommand := fmt.Sprintf(
- "protoc --gofast_out=plugins=grpc:. %s/*.proto -I%s",
- protoDirPath,
- servicePath,
- )
- if goPathSrc != "" {
- parsingCommand += " -I" + goPathSrc
- }
- mlog.Print(parsingCommand)
- if output, err := gproc.ShellExec(ctx, parsingCommand); err != nil {
- mlog.Print(output)
- mlog.Fatal(err)
- }
- return true
- })
- // Custom replacement.
- //pbFolder := "protobuf"
- //_, _ = gfile.ScanDirFileFunc(pbFolder, "*.go", true, func(path string) string {
- // content := gfile.GetContents(path)
- // content = gstr.ReplaceByArray(content, g.SliceStr{
- // `gtime "gtime"`, `gtime "github.com/gogf/gf/v2/os/gtime"`,
- // })
- // _ = gfile.PutContents(path, content)
- // utils.GoFmt(path)
- // return path
- //})
- mlog.Print("done!")
- return
-}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_gen_pbentity.go b/server/internal/library/hggen/internal/cmd/cmd_gen_pbentity.go
index 5cd7790..58b26d8 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_gen_pbentity.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_gen_pbentity.go
@@ -1,411 +1,13 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
-import (
- "bytes"
- "context"
- "fmt"
- "strings"
-
- "github.com/gogf/gf/v2/database/gdb"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/os/gtime"
- "github.com/gogf/gf/v2/text/gregex"
- "github.com/gogf/gf/v2/text/gstr"
- "github.com/gogf/gf/v2/util/gconv"
- "github.com/gogf/gf/v2/util/gtag"
- "github.com/olekukonko/tablewriter"
-
- "hotgo/internal/library/hggen/internal/consts"
- "hotgo/internal/library/hggen/internal/utility/mlog"
-)
+import "hotgo/internal/library/hggen/internal/cmd/genpbentity"
type (
- cGenPbEntity struct{}
- cGenPbEntityInput struct {
- g.Meta `name:"pbentity" config:"{cGenPbEntityConfig}" brief:"{cGenPbEntityBrief}" eg:"{cGenPbEntityEg}" ad:"{cGenPbEntityAd}"`
- Path string `name:"path" short:"p" brief:"{cGenPbEntityBriefPath}"`
- Package string `name:"package" short:"k" brief:"{cGenPbEntityBriefPackage}"`
- Link string `name:"link" short:"l" brief:"{cGenPbEntityBriefLink}"`
- Tables string `name:"tables" short:"t" brief:"{cGenPbEntityBriefTables}"`
- Prefix string `name:"prefix" short:"f" brief:"{cGenPbEntityBriefPrefix}"`
- RemovePrefix string `name:"removePrefix" short:"r" brief:"{cGenPbEntityBriefRemovePrefix}"`
- NameCase string `name:"nameCase" short:"n" brief:"{cGenPbEntityBriefNameCase}" d:"Camel"`
- JsonCase string `name:"jsonCase" short:"j" brief:"{cGenPbEntityBriefJsonCase}" d:"CamelLower"`
- Option string `name:"option" short:"o" brief:"{cGenPbEntityBriefOption}"`
- }
- cGenPbEntityOutput struct{}
-
- cGenPbEntityInternalInput struct {
- cGenPbEntityInput
- TableName string // TableName specifies the table name of the table.
- NewTableName string // NewTableName specifies the prefix-stripped name of the table.
- }
+ cGenPbEntity = genpbentity.CGenPbEntity
)
-
-const (
- cGenPbEntityConfig = `gfcli.gen.pbentity`
- cGenPbEntityBrief = `generate entity message files in protobuf3 format`
- cGenPbEntityEg = `
-gf gen pbentity
-gf gen pbentity -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
-gf gen pbentity -p ./protocol/demos/entity -t user,user_detail,user_login
-gf gen pbentity -r user_
-`
-
- cGenPbEntityAd = `
-CONFIGURATION SUPPORT
- Options are also supported by configuration file.
- It's suggested using configuration file instead of command line arguments making producing.
- The configuration node name is "gf.gen.pbentity", which also supports multiple databases, for example(config.yaml):
- gfcli:
- gen:
- - pbentity:
- link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
- path: "protocol/demos/entity"
- tables: "order,products"
- package: "demos"
- - pbentity:
- link: "mysql:root:12345678@tcp(127.0.0.1:3306)/primary"
- path: "protocol/demos/entity"
- prefix: "primary_"
- tables: "user, userDetail"
- package: "demos"
- option: |
- option go_package = "protobuf/demos";
- option java_package = "protobuf/demos";
- option php_namespace = "protobuf/demos";
-`
- cGenPbEntityBriefPath = `directory path for generated files`
- cGenPbEntityBriefPackage = `package name for all entity proto files`
- cGenPbEntityBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
- cGenPbEntityBriefTables = `generate models only for given tables, multiple table names separated with ','`
- cGenPbEntityBriefPrefix = `add specified prefix for all entity names and entity proto files`
- cGenPbEntityBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
- cGenPbEntityBriefOption = `extra protobuf options`
- cGenPbEntityBriefGroup = `
-specifying the configuration group name of database for generated ORM instance,
-it's not necessary and the default value is "default"
-`
-
- cGenPbEntityBriefNameCase = `
-case for message attribute names, default is "Camel":
-| Case | Example |
-|---------------- |--------------------|
-| Camel | AnyKindOfString |
-| CamelLower | anyKindOfString | default
-| Snake | any_kind_of_string |
-| SnakeScreaming | ANY_KIND_OF_STRING |
-| SnakeFirstUpper | rgb_code_md5 |
-| Kebab | any-kind-of-string |
-| KebabScreaming | ANY-KIND-OF-STRING |
-`
-
- cGenPbEntityBriefJsonCase = `
-case for message json tag, cases are the same as "nameCase", default "CamelLower".
-set it to "none" to ignore json tag generating.
-`
-)
-
-func init() {
- gtag.Sets(g.MapStrStr{
- `cGenPbEntityConfig`: cGenPbEntityConfig,
- `cGenPbEntityBrief`: cGenPbEntityBrief,
- `cGenPbEntityEg`: cGenPbEntityEg,
- `cGenPbEntityAd`: cGenPbEntityAd,
- `cGenPbEntityBriefPath`: cGenPbEntityBriefPath,
- `cGenPbEntityBriefPackage`: cGenPbEntityBriefPackage,
- `cGenPbEntityBriefLink`: cGenPbEntityBriefLink,
- `cGenPbEntityBriefTables`: cGenPbEntityBriefTables,
- `cGenPbEntityBriefPrefix`: cGenPbEntityBriefPrefix,
- `cGenPbEntityBriefRemovePrefix`: cGenPbEntityBriefRemovePrefix,
- `cGenPbEntityBriefGroup`: cGenPbEntityBriefGroup,
- `cGenPbEntityBriefNameCase`: cGenPbEntityBriefNameCase,
- `cGenPbEntityBriefJsonCase`: cGenPbEntityBriefJsonCase,
- `cGenPbEntityBriefOption`: cGenPbEntityBriefOption,
- })
-}
-
-func (c cGenPbEntity) PbEntity(ctx context.Context, in cGenPbEntityInput) (out *cGenPbEntityOutput, err error) {
- var (
- config = g.Cfg()
- )
- if config.Available(ctx) {
- v := config.MustGet(ctx, cGenPbEntityConfig)
- if v.IsSlice() {
- for i := 0; i < len(v.Interfaces()); i++ {
- doGenPbEntityForArray(ctx, i, in)
- }
- } else {
- doGenPbEntityForArray(ctx, -1, in)
- }
- } else {
- doGenPbEntityForArray(ctx, -1, in)
- }
- mlog.Print("done!")
- return
-}
-
-func doGenPbEntityForArray(ctx context.Context, index int, in cGenPbEntityInput) {
- var (
- err error
- db gdb.DB
- )
- if index >= 0 {
- err = g.Cfg().MustGet(
- ctx,
- fmt.Sprintf(`%s.%d`, cGenPbEntityConfig, index),
- ).Scan(&in)
- if err != nil {
- mlog.Fatalf(`invalid configuration of "%s": %+v`, cGenPbEntityConfig, err)
- }
- }
- if in.Package == "" {
- mlog.Fatal("package name should not be empty")
- }
- removePrefixArray := gstr.SplitAndTrim(in.RemovePrefix, ",")
- // It uses user passed database configuration.
- if in.Link != "" {
- var (
- tempGroup = gtime.TimestampNanoStr()
- match, _ = gregex.MatchString(`([a-z]+):(.+)`, in.Link)
- )
- if len(match) == 3 {
- gdb.AddConfigNode(tempGroup, gdb.ConfigNode{
- Type: gstr.Trim(match[1]),
- Link: gstr.Trim(match[2]),
- })
- db, _ = gdb.Instance(tempGroup)
- }
- } else {
- db = g.DB()
- }
- if db == nil {
- mlog.Fatal("database initialization failed")
- }
-
- tableNames := ([]string)(nil)
- if in.Tables != "" {
- tableNames = gstr.SplitAndTrim(in.Tables, ",")
- } else {
- tableNames, err = db.Tables(context.TODO())
- if err != nil {
- mlog.Fatalf("fetching tables failed: \n %v", err)
- }
- }
-
- for _, tableName := range tableNames {
- newTableName := tableName
- for _, v := range removePrefixArray {
- newTableName = gstr.TrimLeftStr(newTableName, v, 1)
- }
- generatePbEntityContentFile(ctx, db, cGenPbEntityInternalInput{
- cGenPbEntityInput: in,
- TableName: tableName,
- NewTableName: newTableName,
- })
- }
-}
-
-// generatePbEntityContentFile generates the protobuf files for given table.
-func generatePbEntityContentFile(ctx context.Context, db gdb.DB, in cGenPbEntityInternalInput) {
- fieldMap, err := db.TableFields(ctx, in.TableName)
- if err != nil {
- mlog.Fatalf("fetching tables fields failed for table '%s':\n%v", in.TableName, err)
- }
- // Change the `newTableName` if `Prefix` is given.
- newTableName := "Entity_" + in.Prefix + in.NewTableName
- var (
- tableNameCamelCase = gstr.CaseCamel(newTableName)
- tableNameSnakeCase = gstr.CaseSnake(newTableName)
- entityMessageDefine = generateEntityMessageDefinition(tableNameCamelCase, fieldMap, in)
- fileName = gstr.Trim(tableNameSnakeCase, "-_.")
- path = gfile.Join(in.Path, fileName+".proto")
- )
- entityContent := gstr.ReplaceByMap(getTplPbEntityContent(""), g.MapStrStr{
- "{PackageName}": in.Package,
- "{OptionContent}": in.Option,
- "{EntityMessage}": entityMessageDefine,
- })
- if err := gfile.PutContents(path, strings.TrimSpace(entityContent)); err != nil {
- mlog.Fatalf("writing content to '%s' failed: %v", path, err)
- } else {
- mlog.Print("generated:", path)
- }
-}
-
-// generateEntityMessageDefinition generates and returns the message definition for specified table.
-func generateEntityMessageDefinition(entityName string, fieldMap map[string]*gdb.TableField, in cGenPbEntityInternalInput) string {
- var (
- buffer = bytes.NewBuffer(nil)
- array = make([][]string, len(fieldMap))
- names = sortFieldKeyForPbEntity(fieldMap)
- )
- for index, name := range names {
- array[index] = generateMessageFieldForPbEntity(index+1, fieldMap[name], in)
- }
- tw := tablewriter.NewWriter(buffer)
- tw.SetBorder(false)
- tw.SetRowLine(false)
- tw.SetAutoWrapText(false)
- tw.SetColumnSeparator("")
- tw.AppendBulk(array)
- tw.Render()
- stContent := buffer.String()
- // Let's do this hack of table writer for indent!
- stContent = gstr.Replace(stContent, " #", "")
- buffer.Reset()
- buffer.WriteString(fmt.Sprintf("message %s {\n", entityName))
- buffer.WriteString(stContent)
- buffer.WriteString("}")
- return buffer.String()
-}
-
-// generateMessageFieldForPbEntity generates and returns the message definition for specified field.
-func generateMessageFieldForPbEntity(index int, field *gdb.TableField, in cGenPbEntityInternalInput) []string {
- var (
- typeName string
- comment string
- jsonTagStr string
- )
- t, _ := gregex.ReplaceString(`\(.+\)`, "", field.Type)
- t = gstr.Split(gstr.Trim(t), " ")[0]
- t = gstr.ToLower(t)
- switch t {
- case "binary", "varbinary", "blob", "tinyblob", "mediumblob", "longblob":
- typeName = "bytes"
-
- case "bit", "int", "tinyint", "small_int", "smallint", "medium_int", "mediumint", "serial":
- if gstr.ContainsI(field.Type, "unsigned") {
- typeName = "uint32"
- } else {
- typeName = "int32"
- }
-
- case "int8", "big_int", "bigint", "bigserial":
- if gstr.ContainsI(field.Type, "unsigned") {
- typeName = "uint64"
- } else {
- typeName = "int64"
- }
-
- case "real":
- typeName = "float"
-
- case "float", "double", "decimal", "smallmoney":
- typeName = "double"
-
- case "bool":
- typeName = "bool"
-
- case "datetime", "timestamp", "date", "time":
- typeName = "int64"
-
- default:
- // Auto detecting type.
- switch {
- case strings.Contains(t, "int"):
- typeName = "int"
- case strings.Contains(t, "text") || strings.Contains(t, "char"):
- typeName = "string"
- case strings.Contains(t, "float") || strings.Contains(t, "double"):
- typeName = "double"
- case strings.Contains(t, "bool"):
- typeName = "bool"
- case strings.Contains(t, "binary") || strings.Contains(t, "blob"):
- typeName = "bytes"
- case strings.Contains(t, "date") || strings.Contains(t, "time"):
- typeName = "int64"
- default:
- typeName = "string"
- }
- }
- comment = gstr.ReplaceByArray(field.Comment, g.SliceStr{
- "\n", " ",
- "\r", " ",
- })
- comment = gstr.Trim(comment)
- comment = gstr.Replace(comment, `\n`, " ")
- comment, _ = gregex.ReplaceString(`\s{2,}`, ` `, comment)
- if jsonTagName := formatCase(field.Name, in.JsonCase); jsonTagName != "" {
- jsonTagStr = fmt.Sprintf(`[(gogoproto.jsontag) = "%s"]`, jsonTagName)
- // beautiful indent.
- if index < 10 {
- // 3 spaces
- jsonTagStr = " " + jsonTagStr
- } else if index < 100 {
- // 2 spaces
- jsonTagStr = " " + jsonTagStr
- } else {
- // 1 spaces
- jsonTagStr = " " + jsonTagStr
- }
- }
- return []string{
- " #" + typeName,
- " #" + formatCase(field.Name, in.NameCase),
- " #= " + gconv.String(index) + jsonTagStr + ";",
- " #" + fmt.Sprintf(`// %s`, comment),
- }
-}
-
-func getTplPbEntityContent(tplEntityPath string) string {
- if tplEntityPath != "" {
- return gfile.GetContents(tplEntityPath)
- }
- return consts.TemplatePbEntityMessageContent
-}
-
-// formatCase call gstr.Case* function to convert the s to specified case.
-func formatCase(str, caseStr string) string {
- switch gstr.ToLower(caseStr) {
- case gstr.ToLower("Camel"):
- return gstr.CaseCamel(str)
-
- case gstr.ToLower("CamelLower"):
- return gstr.CaseCamelLower(str)
-
- case gstr.ToLower("Kebab"):
- return gstr.CaseKebab(str)
-
- case gstr.ToLower("KebabScreaming"):
- return gstr.CaseKebabScreaming(str)
-
- case gstr.ToLower("Snake"):
- return gstr.CaseSnake(str)
-
- case gstr.ToLower("SnakeFirstUpper"):
- return gstr.CaseSnakeFirstUpper(str)
-
- case gstr.ToLower("SnakeScreaming"):
- return gstr.CaseSnakeScreaming(str)
-
- case "none":
- return ""
- }
- return str
-}
-
-func sortFieldKeyForPbEntity(fieldMap map[string]*gdb.TableField) []string {
- names := make(map[int]string)
- for _, field := range fieldMap {
- names[field.Index] = field.Name
- }
- var (
- result = make([]string, len(names))
- i = 0
- j = 0
- )
- for {
- if len(names) == 0 {
- break
- }
- if val, ok := names[i]; ok {
- result[j] = val
- j++
- delete(names, i)
- }
- i++
- }
- return result
-}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_gen_service.go b/server/internal/library/hggen/internal/cmd/cmd_gen_service.go
index 2eaced2..33b5689 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_gen_service.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_gen_service.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
diff --git a/server/internal/library/hggen/internal/cmd/cmd_init.go b/server/internal/library/hggen/internal/cmd/cmd_init.go
index 35348e3..fc08f81 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_init.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_init.go
@@ -1,9 +1,14 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
"context"
"fmt"
- "github.com/gogf/gf/v2/text/gstr"
"os"
"strings"
@@ -12,6 +17,7 @@ import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/os/gres"
+ "github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gtag"
"hotgo/internal/library/hggen/internal/utility/allyes"
diff --git a/server/internal/library/hggen/internal/cmd/cmd_install.go b/server/internal/library/hggen/internal/cmd/cmd_install.go
index 24377ca..0dd30ad 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_install.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_install.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
diff --git a/server/internal/library/hggen/internal/cmd/cmd_pack.go b/server/internal/library/hggen/internal/cmd/cmd_pack.go
index f185c8d..10f157b 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_pack.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_pack.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
diff --git a/server/internal/library/hggen/internal/cmd/cmd_run.go b/server/internal/library/hggen/internal/cmd/cmd_run.go
index 6e3d3ee..0e7eec2 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_run.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_run.go
@@ -1,9 +1,16 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
"context"
"fmt"
"runtime"
+ "strings"
"github.com/gogf/gf/v2/container/gtype"
"github.com/gogf/gf/v2/frame/g"
@@ -154,7 +161,7 @@ func (app *cRunApp) Run(ctx context.Context) {
if runtime.GOOS == "windows" {
// Special handling for windows platform.
// DO NOT USE "cmd /c" command.
- process = gproc.NewProcess(runCommand, nil)
+ process = gproc.NewProcess(outputPath, strings.Fields(app.Args))
} else {
process = gproc.NewProcessCmd(runCommand, nil)
}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_tpl.go b/server/internal/library/hggen/internal/cmd/cmd_tpl.go
index f854849..df1931b 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_tpl.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_tpl.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
diff --git a/server/internal/library/hggen/internal/cmd/cmd_up.go b/server/internal/library/hggen/internal/cmd/cmd_up.go
index 9bce070..43ed308 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_up.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_up.go
@@ -1,15 +1,26 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
"context"
"fmt"
+ "runtime"
+ "github.com/minio/selfupdate"
+
+ "github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gtag"
"hotgo/internal/library/hggen/internal/utility/mlog"
+ "hotgo/internal/library/hggen/internal/utility/utils"
)
var (
@@ -21,12 +32,12 @@ type cUp struct {
}
const (
- gfPackage = `github.com/gogf/gf/v2`
+ gfPackage = `github.com/gogf/gf/`
cUpEg = `
gf up
gf up -a
gf up -c
-gf up -f -c
+gf up -cf
`
)
@@ -39,51 +50,90 @@ func init() {
type cUpInput struct {
g.Meta `name:"up" config:"gfcli.up"`
All bool `name:"all" short:"a" brief:"upgrade both version and cli, auto fix codes" orphan:"true"`
- Fix bool `name:"fix" short:"f" brief:"auto fix codes" orphan:"true"`
- Cli bool `name:"cli" short:"c" brief:"also upgrade CLI tool (not supported yet)" orphan:"true"`
+ Cli bool `name:"cli" short:"c" brief:"also upgrade CLI tool" orphan:"true"`
+ Fix bool `name:"fix" short:"f" brief:"auto fix codes(it only make sense if cli is to be upgraded)" orphan:"true"`
}
type cUpOutput struct{}
func (c cUp) Index(ctx context.Context, in cUpInput) (out *cUpOutput, err error) {
- defer mlog.Print(`done!`)
+ defer func() {
+ if err == nil {
+ mlog.Print()
+ mlog.Print(`👏congratulations! you've upgraded to the latest version of GoFrame! enjoy it!👏`)
+ mlog.Print()
+ }
+ }()
+ var doUpgradeVersionOut *doUpgradeVersionOutput
if in.All {
in.Cli = true
in.Fix = true
}
- if err = c.doUpgradeVersion(ctx); err != nil {
+ if doUpgradeVersionOut, err = c.doUpgradeVersion(ctx, in); err != nil {
return nil, err
}
- if in.Fix {
- if err = c.doAutoFixing(ctx); err != nil {
+
+ if in.Cli {
+ if err = c.doUpgradeCLI(ctx); err != nil {
return nil, err
}
}
- //if in.Cli {
- // if err = c.doUpgradeCLI(ctx); err != nil {
- // return nil, err
- // }
- //}
+
+ if in.Cli && in.Fix {
+ if doUpgradeVersionOut != nil && len(doUpgradeVersionOut.Items) > 0 {
+ upgradedPathSet := gset.NewStrSet()
+ for _, item := range doUpgradeVersionOut.Items {
+ if !upgradedPathSet.AddIfNotExist(item.DirPath) {
+ continue
+ }
+ if err = c.doAutoFixing(ctx, item.DirPath, item.Version); err != nil {
+ return nil, err
+ }
+ }
+ }
+ }
return
}
-func (c cUp) doUpgradeVersion(ctx context.Context) (err error) {
+type doUpgradeVersionOutput struct {
+ Items []doUpgradeVersionOutputItem
+}
+
+type doUpgradeVersionOutputItem struct {
+ DirPath string
+ Version string
+}
+
+func (c cUp) doUpgradeVersion(ctx context.Context, in cUpInput) (out *doUpgradeVersionOutput, err error) {
mlog.Print(`start upgrading version...`)
+ out = &doUpgradeVersionOutput{
+ Items: make([]doUpgradeVersionOutputItem, 0),
+ }
+ type Package struct {
+ Name string
+ Version string
+ }
var (
- dir = gfile.Pwd()
- temp string
- path = gfile.Join(dir, "go.mod")
+ temp string
+ dirPath = gfile.Pwd()
+ goModPath = gfile.Join(dirPath, "go.mod")
)
+ // It recursively upgrades the go.mod from sub folder to its parent folders.
for {
- if gfile.Exists(path) {
- var packages []string
- err = gfile.ReadLines(path, func(line string) error {
+ if gfile.Exists(goModPath) {
+ var packages []Package
+ err = gfile.ReadLines(goModPath, func(line string) error {
+ line = gstr.Trim(line)
+ line = gstr.TrimLeftStr(line, "require ")
line = gstr.Trim(line)
if gstr.HasPrefix(line, gfPackage) {
- pkg := gstr.Explode(" ", line)[0]
- packages = append(packages, pkg)
+ array := gstr.SplitAndTrim(line, " ")
+ packages = append(packages, Package{
+ Name: array[0],
+ Version: array[1],
+ })
}
return nil
})
@@ -91,31 +141,79 @@ func (c cUp) doUpgradeVersion(ctx context.Context) (err error) {
return
}
for _, pkg := range packages {
- mlog.Printf(`upgrading %s`, pkg)
- command := fmt.Sprintf(`go get -u %s@latest`, pkg)
+ mlog.Printf(`upgrading "%s" from "%s" to "latest"`, pkg.Name, pkg.Version)
+ // go get -u
+ command := fmt.Sprintf(`cd %s && go get -u %s@latest`, dirPath, pkg.Name)
if err = gproc.ShellRun(ctx, command); err != nil {
return
}
+ // go mod tidy
+ if err = utils.GoModTidy(ctx, dirPath); err != nil {
+ return nil, err
+ }
+ out.Items = append(out.Items, doUpgradeVersionOutputItem{
+ DirPath: dirPath,
+ Version: pkg.Version,
+ })
}
return
}
- temp = gfile.Dir(dir)
- if temp == "" || temp == dir {
+ temp = gfile.Dir(dirPath)
+ if temp == "" || temp == dirPath {
return
}
- dir = temp
- path = gfile.Join(dir, "go.mod")
+ dirPath = temp
+ goModPath = gfile.Join(dirPath, "go.mod")
}
}
+// doUpgradeCLI downloads the new version binary with process.
func (c cUp) doUpgradeCLI(ctx context.Context) (err error) {
mlog.Print(`start upgrading cli...`)
+ var (
+ downloadUrl = fmt.Sprintf(
+ `https://github.com/gogf/gf/releases/latest/download/gf_%s_%s`,
+ runtime.GOOS, runtime.GOARCH,
+ )
+ localSaveFilePath = gfile.SelfPath() + "~"
+ )
+ if runtime.GOOS == "windows" {
+ downloadUrl += ".exe"
+ }
+
+ mlog.Printf(`start downloading "%s" to "%s", it may take some time`, downloadUrl, localSaveFilePath)
+ err = utils.HTTPDownloadFileWithPercent(downloadUrl, localSaveFilePath)
+ if err != nil {
+ return err
+ }
+
+ defer func() {
+ mlog.Printf(`new version cli binary is successfully installed to "%s"`, gfile.SelfPath())
+ mlog.Printf(`remove temporary buffer file "%s"`, localSaveFilePath)
+ _ = gfile.Remove(localSaveFilePath)
+ }()
+
+ // It fails if file not exist or its size is less than 1MB.
+ if !gfile.Exists(localSaveFilePath) || gfile.Size(localSaveFilePath) < 1024*1024 {
+ mlog.Fatalf(`download "%s" to "%s" failed`, downloadUrl, localSaveFilePath)
+ }
+
+ newFile, err := gfile.Open(localSaveFilePath)
+ if err != nil {
+ return err
+ }
+ // selfupdate
+ err = selfupdate.Apply(newFile, selfupdate.Options{})
+ if err != nil {
+ return err
+ }
return
}
-func (c cUp) doAutoFixing(ctx context.Context) (err error) {
- mlog.Print(`start auto fixing...`)
- err = cFix{}.doFix()
+func (c cUp) doAutoFixing(ctx context.Context, dirPath string, version string) (err error) {
+ mlog.Printf(`auto fixing directory path "%s" from version "%s" ...`, dirPath, version)
+ command := fmt.Sprintf(`gf fix -p %s`, dirPath)
+ _ = gproc.ShellRun(ctx, command)
return
}
diff --git a/server/internal/library/hggen/internal/cmd/cmd_version.go b/server/internal/library/hggen/internal/cmd/cmd_version.go
index c4127e3..04c5b84 100644
--- a/server/internal/library/hggen/internal/cmd/cmd_version.go
+++ b/server/internal/library/hggen/internal/cmd/cmd_version.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package cmd
import (
@@ -64,6 +70,8 @@ func (c cVersion) getGFVersionOfCurrentProject() (string, error) {
if gfile.Exists(goModPath) {
lines := gstr.SplitAndTrim(gfile.GetContents(goModPath), "\n")
for _, line := range lines {
+ line = gstr.Trim(line)
+ line = gstr.TrimLeftStr(line, "require ")
line = gstr.Trim(line)
// Version 1.
match, err := gregex.MatchString(`^github\.com/gogf/gf\s+(.+)$`, line)
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl.go
new file mode 100644
index 0000000..4336909
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl.go
@@ -0,0 +1,233 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genctrl
+
+import (
+ "context"
+
+ "github.com/gogf/gf/v2/container/gset"
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gtime"
+ "github.com/gogf/gf/v2/text/gregex"
+ "github.com/gogf/gf/v2/util/gconv"
+ "github.com/gogf/gf/v2/util/gtag"
+
+ "hotgo/internal/library/hggen/internal/utility/mlog"
+)
+
+const (
+ CGenCtrlConfig = `gfcli.gen.ctrl`
+ CGenCtrlUsage = `gf gen ctrl [OPTION]`
+ CGenCtrlBrief = `parse api definitions to generate controller/sdk go files`
+ CGenCtrlEg = `
+gf gen ctrl
+`
+ CGenCtrlBriefSrcFolder = `source folder path to be parsed. default: api`
+ CGenCtrlBriefDstFolder = `destination folder path storing automatically generated go files. default: internal/controller`
+ CGenCtrlBriefWatchFile = `used in file watcher, it re-generates go files only if given file is under srcFolder`
+ CGenCtrlBriefSdkPath = `also generate SDK go files for api definitions to specified directory`
+ CGenCtrlBriefSdkStdVersion = `use standard version prefix for generated sdk request path`
+ CGenCtrlBriefSdkNoV1 = `do not add version suffix for interface module name if version is v1`
+ CGenCtrlBriefClear = `auto delete generated and unimplemented controller go files if api definitions are missing`
+)
+
+const (
+ PatternApiDefinition = `type\s+(\w+)Req\s+struct\s+{`
+ PatternCtrlDefinition = `func\s+\(.+?\)\s+\w+\(.+?\*(\w+)\.(\w+)Req\)\s+\(.+?\*(\w+)\.(\w+)Res,\s+\w+\s+error\)\s+{`
+)
+
+const (
+ genCtrlFileLockSeconds = 10
+)
+
+func init() {
+ gtag.Sets(g.MapStrStr{
+ `CGenCtrlConfig`: CGenCtrlConfig,
+ `CGenCtrlUsage`: CGenCtrlUsage,
+ `CGenCtrlBrief`: CGenCtrlBrief,
+ `CGenCtrlEg`: CGenCtrlEg,
+ `CGenCtrlBriefSrcFolder`: CGenCtrlBriefSrcFolder,
+ `CGenCtrlBriefDstFolder`: CGenCtrlBriefDstFolder,
+ `CGenCtrlBriefWatchFile`: CGenCtrlBriefWatchFile,
+ `CGenCtrlBriefSdkPath`: CGenCtrlBriefSdkPath,
+ `CGenCtrlBriefSdkStdVersion`: CGenCtrlBriefSdkStdVersion,
+ `CGenCtrlBriefSdkNoV1`: CGenCtrlBriefSdkNoV1,
+ `CGenCtrlBriefClear`: CGenCtrlBriefClear,
+ })
+}
+
+type (
+ CGenCtrl struct{}
+ CGenCtrlInput struct {
+ g.Meta `name:"ctrl" config:"{CGenCtrlConfig}" usage:"{CGenCtrlUsage}" brief:"{CGenCtrlBrief}" eg:"{CGenCtrlEg}"`
+ SrcFolder string `short:"s" name:"srcFolder" brief:"{CGenCtrlBriefSrcFolder}" d:"api"`
+ DstFolder string `short:"d" name:"dstFolder" brief:"{CGenCtrlBriefDstFolder}" d:"internal/controller"`
+ WatchFile string `short:"w" name:"watchFile" brief:"{CGenCtrlBriefWatchFile}"`
+ SdkPath string `short:"k" name:"sdkPath" brief:"{CGenCtrlBriefSdkPath}"`
+ SdkStdVersion bool `short:"v" name:"sdkStdVersion" brief:"{CGenCtrlBriefSdkStdVersion}" orphan:"true"`
+ SdkNoV1 bool `short:"n" name:"sdkNoV1" brief:"{CGenCtrlBriefSdkNoV1}" orphan:"true"`
+ Clear bool `short:"c" name:"clear" brief:"{CGenCtrlBriefClear}" orphan:"true"`
+ }
+ CGenCtrlOutput struct{}
+)
+
+func (c CGenCtrl) Ctrl(ctx context.Context, in CGenCtrlInput) (out *CGenCtrlOutput, err error) {
+ if in.WatchFile != "" {
+ err = c.generateByWatchFile(
+ in.WatchFile, in.SdkPath, in.SdkStdVersion, in.SdkNoV1, in.Clear,
+ )
+ mlog.Print(`done!`)
+ return
+ }
+
+ if !gfile.Exists(in.SrcFolder) {
+ mlog.Fatalf(`source folder path "%s" does not exist`, in.SrcFolder)
+ }
+ // retrieve all api modules.
+ apiModuleFolderPaths, err := gfile.ScanDir(in.SrcFolder, "*", false)
+ if err != nil {
+ return nil, err
+ }
+ for _, apiModuleFolderPath := range apiModuleFolderPaths {
+ if !gfile.IsDir(apiModuleFolderPath) {
+ continue
+ }
+ // generate go files by api module.
+ var (
+ module = gfile.Basename(apiModuleFolderPath)
+ dstModuleFolderPath = gfile.Join(in.DstFolder, module)
+ )
+ err = c.generateByModule(
+ apiModuleFolderPath, dstModuleFolderPath, in.SdkPath,
+ in.SdkStdVersion, in.SdkNoV1, in.Clear,
+ )
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ mlog.Print(`done!`)
+ return
+}
+
+func (c CGenCtrl) generateByWatchFile(watchFile, sdkPath string, sdkStdVersion, sdkNoV1, clear bool) (err error) {
+ // File lock to avoid multiple processes.
+ var (
+ flockFilePath = gfile.Temp("gf.cli.gen.service.lock")
+ flockContent = gfile.GetContents(flockFilePath)
+ )
+ if flockContent != "" {
+ if gtime.Timestamp()-gconv.Int64(flockContent) < genCtrlFileLockSeconds {
+ // If another generating process is running, it just exits.
+ mlog.Debug(`another "gen service" process is running, exit`)
+ return
+ }
+ }
+ defer gfile.Remove(flockFilePath)
+ _ = gfile.PutContents(flockFilePath, gtime.TimestampStr())
+
+ // check this updated file is an api file.
+ // watch file should be in standard goframe project structure.
+ var (
+ apiVersionPath = gfile.Dir(watchFile)
+ apiModuleFolderPath = gfile.Dir(apiVersionPath)
+ shouldBeNameOfAPi = gfile.Basename(gfile.Dir(apiModuleFolderPath))
+ )
+ if shouldBeNameOfAPi != "api" {
+ return nil
+ }
+ // watch file should have api definitions.
+ if gfile.Exists(watchFile) {
+ if !gregex.IsMatchString(PatternApiDefinition, gfile.GetContents(watchFile)) {
+ return nil
+ }
+ }
+
+ var (
+ projectRootPath = gfile.Dir(gfile.Dir(apiModuleFolderPath))
+ module = gfile.Basename(apiModuleFolderPath)
+ dstModuleFolderPath = gfile.Join(projectRootPath, "internal", "controller", module)
+ )
+ return c.generateByModule(
+ apiModuleFolderPath, dstModuleFolderPath, sdkPath, sdkStdVersion, sdkNoV1, clear,
+ )
+}
+
+// parseApiModule parses certain api and generate associated go files by certain module, not all api modules.
+func (c CGenCtrl) generateByModule(
+ apiModuleFolderPath, dstModuleFolderPath, sdkPath string,
+ sdkStdVersion, sdkNoV1, clear bool,
+) (err error) {
+ // parse src and dst folder go files.
+ apiItemsInSrc, err := c.getApiItemsInSrc(apiModuleFolderPath)
+ if err != nil {
+ return err
+ }
+ apiItemsInDst, err := c.getApiItemsInDst(dstModuleFolderPath)
+ if err != nil {
+ return err
+ }
+
+ // generate api interface go files.
+ if err = newApiInterfaceGenerator().Generate(apiModuleFolderPath, apiItemsInSrc); err != nil {
+ return
+ }
+
+ // generate controller go files.
+ // api filtering for already implemented api controllers.
+ var (
+ alreadyImplementedCtrlSet = gset.NewStrSet()
+ toBeImplementedApiItems = make([]apiItem, 0)
+ )
+ for _, item := range apiItemsInDst {
+ alreadyImplementedCtrlSet.Add(item.String())
+ }
+ for _, item := range apiItemsInSrc {
+ if alreadyImplementedCtrlSet.Contains(item.String()) {
+ continue
+ }
+ toBeImplementedApiItems = append(toBeImplementedApiItems, item)
+ }
+ if len(toBeImplementedApiItems) > 0 {
+ err = newControllerGenerator().Generate(dstModuleFolderPath, toBeImplementedApiItems)
+ if err != nil {
+ return
+ }
+ }
+
+ // delete unimplemented controllers if api definitions are missing.
+ if clear {
+ var (
+ apiDefinitionSet = gset.NewStrSet()
+ extraApiItemsInCtrl = make([]apiItem, 0)
+ )
+ for _, item := range apiItemsInSrc {
+ apiDefinitionSet.Add(item.String())
+ }
+ for _, item := range apiItemsInDst {
+ if apiDefinitionSet.Contains(item.String()) {
+ continue
+ }
+ extraApiItemsInCtrl = append(extraApiItemsInCtrl, item)
+ }
+ if len(extraApiItemsInCtrl) > 0 {
+ err = newControllerClearer().Clear(dstModuleFolderPath, extraApiItemsInCtrl)
+ if err != nil {
+ return
+ }
+ }
+ }
+
+ // generate sdk go files.
+ if sdkPath != "" {
+ if err = newApiSdkGenerator().Generate(apiItemsInSrc, sdkPath, sdkStdVersion, sdkNoV1); err != nil {
+ return
+ }
+ }
+ return
+}
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_api_item.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_api_item.go
new file mode 100644
index 0000000..997c38a
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_api_item.go
@@ -0,0 +1,22 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genctrl
+
+import "github.com/gogf/gf/v2/text/gstr"
+
+type apiItem struct {
+ Import string `eg:"demo.com/api/user/v1"`
+ Module string `eg:"user"`
+ Version string `eg:"v1"`
+ MethodName string `eg:"GetList"`
+}
+
+func (a apiItem) String() string {
+ return gstr.Join([]string{
+ a.Import, a.Module, a.Version, a.MethodName,
+ }, ",")
+}
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_calculate.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_calculate.go
new file mode 100644
index 0000000..3c73153
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_calculate.go
@@ -0,0 +1,136 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genctrl
+
+import (
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/text/gregex"
+ "github.com/gogf/gf/v2/text/gstr"
+ "hotgo/internal/library/hggen/internal/utility/utils"
+)
+
+func (c CGenCtrl) getApiItemsInSrc(apiModuleFolderPath string) (items []apiItem, err error) {
+ var (
+ fileContent string
+ importPath string
+ )
+ // The second level folders: versions.
+ apiVersionFolderPaths, err := gfile.ScanDir(apiModuleFolderPath, "*", false)
+ if err != nil {
+ return nil, err
+ }
+ for _, apiVersionFolderPath := range apiVersionFolderPaths {
+ if !gfile.IsDir(apiVersionFolderPath) {
+ continue
+ }
+ // The second level folders: versions.
+ apiFileFolderPaths, err := gfile.ScanDir(apiVersionFolderPath, "*.go", false)
+ if err != nil {
+ return nil, err
+ }
+ importPath = utils.GetImportPath(apiVersionFolderPath)
+ for _, apiFileFolderPath := range apiFileFolderPaths {
+ if gfile.IsDir(apiFileFolderPath) {
+ continue
+ }
+ fileContent = gfile.GetContents(apiFileFolderPath)
+ matches, err := gregex.MatchAllString(PatternApiDefinition, fileContent)
+ if err != nil {
+ return nil, err
+ }
+ for _, match := range matches {
+ item := apiItem{
+ Import: gstr.Trim(importPath, `"`),
+ Module: gfile.Basename(apiModuleFolderPath),
+ Version: gfile.Basename(apiVersionFolderPath),
+ MethodName: match[1],
+ }
+ items = append(items, item)
+ }
+ }
+ }
+ return
+}
+
+func (c CGenCtrl) getApiItemsInDst(dstFolder string) (items []apiItem, err error) {
+ if !gfile.Exists(dstFolder) {
+ return nil, nil
+ }
+ type importItem struct {
+ Path string
+ Alias string
+ }
+ var fileContent string
+ filePaths, err := gfile.ScanDir(dstFolder, "*.go", true)
+ if err != nil {
+ return nil, err
+ }
+ for _, filePath := range filePaths {
+ fileContent = gfile.GetContents(filePath)
+ match, err := gregex.MatchString(`import\s+\(([\s\S]+?)\)`, fileContent)
+ if err != nil {
+ return nil, err
+ }
+ if len(match) < 2 {
+ continue
+ }
+ var (
+ array []string
+ importItems []importItem
+ importLines = gstr.SplitAndTrim(match[1], "\n")
+ module = gfile.Basename(gfile.Dir(filePath))
+ )
+ // retrieve all imports.
+ for _, importLine := range importLines {
+ array = gstr.SplitAndTrim(importLine, " ")
+ if len(array) == 2 {
+ importItems = append(importItems, importItem{
+ Path: gstr.Trim(array[1], `"`),
+ Alias: array[0],
+ })
+ } else {
+ importItems = append(importItems, importItem{
+ Path: gstr.Trim(array[0], `"`),
+ })
+ }
+ }
+ // retrieve all api usages.
+ matches, err := gregex.MatchAllString(PatternCtrlDefinition, fileContent)
+ if err != nil {
+ return nil, err
+ }
+ for _, match = range matches {
+ // try to find the import path of the api.
+ var (
+ importPath string
+ version = match[1]
+ methodName = match[2] // not the function name, but the method name in api definition.
+ )
+ for _, item := range importItems {
+ if item.Alias != "" {
+ if item.Alias == version {
+ importPath = item.Path
+ break
+ }
+ continue
+ }
+ if gfile.Basename(item.Path) == version {
+ importPath = item.Path
+ break
+ }
+ }
+ item := apiItem{
+ Import: gstr.Trim(importPath, `"`),
+ Module: module,
+ Version: gfile.Basename(importPath),
+ MethodName: methodName,
+ }
+ items = append(items, item)
+ }
+ }
+ return
+}
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl.go
new file mode 100644
index 0000000..9ac546c
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl.go
@@ -0,0 +1,137 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genctrl
+
+import (
+ "fmt"
+
+ "github.com/gogf/gf/v2/container/gset"
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/text/gstr"
+ "hotgo/internal/library/hggen/internal/consts"
+ "hotgo/internal/library/hggen/internal/utility/mlog"
+)
+
+type controllerGenerator struct{}
+
+func newControllerGenerator() *controllerGenerator {
+ return &controllerGenerator{}
+}
+
+func (c *controllerGenerator) Generate(dstModuleFolderPath string, apiModuleApiItems []apiItem) (err error) {
+ var (
+ doneApiItemSet = gset.NewStrSet()
+ )
+ for _, item := range apiModuleApiItems {
+ if doneApiItemSet.Contains(item.String()) {
+ continue
+ }
+ // retrieve all api items of the same module.
+ subItems := c.getSubItemsByModuleAndVersion(apiModuleApiItems, item.Module, item.Version)
+ if err = c.doGenerateCtrlNewByModuleAndVersion(
+ dstModuleFolderPath, item.Module, item.Version, gfile.Dir(item.Import),
+ ); err != nil {
+ return
+ }
+ for _, subItem := range subItems {
+ if err = c.doGenerateCtrlItem(dstModuleFolderPath, subItem); err != nil {
+ return
+ }
+ doneApiItemSet.Add(subItem.String())
+ }
+ }
+ return
+}
+
+func (c *controllerGenerator) getSubItemsByModuleAndVersion(items []apiItem, module, version string) (subItems []apiItem) {
+ for _, item := range items {
+ if item.Module == module && item.Version == version {
+ subItems = append(subItems, item)
+ }
+ }
+ return
+}
+
+func (c *controllerGenerator) doGenerateCtrlNewByModuleAndVersion(
+ dstModuleFolderPath, module, version, importPath string,
+) (err error) {
+ var (
+ moduleFilePath = gfile.Join(dstModuleFolderPath, module+".go")
+ moduleFilePathNew = gfile.Join(dstModuleFolderPath, module+"_new.go")
+ ctrlName = fmt.Sprintf(`Controller%s`, gstr.UcFirst(version))
+ interfaceName = fmt.Sprintf(`%s.I%s%s`, module, gstr.CaseCamel(module), gstr.UcFirst(version))
+ newFuncName = fmt.Sprintf(`New%s`, gstr.UcFirst(version))
+ newFuncNameDefinition = fmt.Sprintf(`func %s()`, newFuncName)
+ alreadyCreated bool
+ )
+ // replace "\" to "/", fix import error
+ importPath = gstr.Replace(importPath, "\\", "/", -1)
+ if !gfile.Exists(moduleFilePath) {
+ content := gstr.ReplaceByMap(consts.TemplateGenCtrlControllerEmpty, g.MapStrStr{
+ "{Module}": module,
+ })
+ if err = gfile.PutContents(moduleFilePath, gstr.TrimLeft(content)); err != nil {
+ return err
+ }
+ mlog.Printf(`generated: %s`, moduleFilePath)
+ }
+ if !gfile.Exists(moduleFilePathNew) {
+ content := gstr.ReplaceByMap(consts.TemplateGenCtrlControllerNewEmpty, g.MapStrStr{
+ "{Module}": module,
+ "{ImportPath}": fmt.Sprintf(`"%s"`, importPath),
+ })
+ if err = gfile.PutContents(moduleFilePathNew, gstr.TrimLeft(content)); err != nil {
+ return err
+ }
+ mlog.Printf(`generated: %s`, moduleFilePathNew)
+ }
+ filePaths, err := gfile.ScanDir(dstModuleFolderPath, "*.go", false)
+ if err != nil {
+ return err
+ }
+ for _, filePath := range filePaths {
+ if gstr.Contains(gfile.GetContents(filePath), newFuncNameDefinition) {
+ alreadyCreated = true
+ break
+ }
+ }
+ if !alreadyCreated {
+ content := gstr.ReplaceByMap(consts.TemplateGenCtrlControllerNewFunc, g.MapStrStr{
+ "{CtrlName}": ctrlName,
+ "{NewFuncName}": newFuncName,
+ "{InterfaceName}": interfaceName,
+ })
+ err = gfile.PutContentsAppend(moduleFilePathNew, gstr.TrimLeft(content))
+ if err != nil {
+ return err
+ }
+ }
+ return
+}
+
+func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, item apiItem) (err error) {
+ var (
+ methodNameSnake = gstr.CaseSnake(item.MethodName)
+ ctrlName = fmt.Sprintf(`Controller%s`, gstr.UcFirst(item.Version))
+ methodFilePath = gfile.Join(dstModuleFolderPath, fmt.Sprintf(
+ `%s_%s_%s.go`, item.Module, item.Version, methodNameSnake,
+ ))
+ )
+ content := gstr.ReplaceByMap(consts.TemplateGenCtrlControllerMethodFunc, g.MapStrStr{
+ "{Module}": item.Module,
+ "{ImportPath}": item.Import,
+ "{CtrlName}": ctrlName,
+ "{Version}": item.Version,
+ "{MethodName}": item.MethodName,
+ })
+ if err = gfile.PutContents(methodFilePath, gstr.TrimLeft(content)); err != nil {
+ return err
+ }
+ mlog.Printf(`generated: %s`, methodFilePath)
+ return
+}
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl_clear.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl_clear.go
new file mode 100644
index 0000000..af59ada
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_ctrl_clear.go
@@ -0,0 +1,57 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genctrl
+
+import (
+ "fmt"
+
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/text/gregex"
+ "github.com/gogf/gf/v2/text/gstr"
+ "hotgo/internal/library/hggen/internal/utility/mlog"
+)
+
+type controllerClearer struct{}
+
+func newControllerClearer() *controllerClearer {
+ return &controllerClearer{}
+}
+
+func (c *controllerClearer) Clear(dstModuleFolderPath string, extraApiItemsInCtrl []apiItem) (err error) {
+ for _, item := range extraApiItemsInCtrl {
+ if err = c.doClear(dstModuleFolderPath, item); err != nil {
+ return err
+ }
+ }
+ return
+}
+
+func (c *controllerClearer) doClear(dstModuleFolderPath string, item apiItem) (err error) {
+ var (
+ methodNameSnake = gstr.CaseSnake(item.MethodName)
+ methodFilePath = gfile.Join(dstModuleFolderPath, fmt.Sprintf(
+ `%s_%s_%s.go`, item.Module, item.Version, methodNameSnake,
+ ))
+ fileContent = gstr.Trim(gfile.GetContents(methodFilePath))
+ )
+ match, err := gregex.MatchString(`.+?Req.+?Res.+?{([\s\S]+?)}`, fileContent)
+ if err != nil {
+ return err
+ }
+ if len(match) > 1 {
+ implements := gstr.Trim(match[1])
+ // One line.
+ if !gstr.Contains(implements, "\n") && gstr.Contains(implements, `CodeNotImplemented`) {
+ mlog.Printf(
+ `remove unimplemented and of no api definitions controller file: %s`,
+ methodFilePath,
+ )
+ err = gfile.Remove(methodFilePath)
+ }
+ }
+ return
+}
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_interface.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_interface.go
new file mode 100644
index 0000000..e714036
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_interface.go
@@ -0,0 +1,111 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genctrl
+
+import (
+ "fmt"
+
+ "github.com/gogf/gf/v2/container/gmap"
+ "github.com/gogf/gf/v2/container/gset"
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/text/gstr"
+ "github.com/gogf/gf/v2/util/gconv"
+ "hotgo/internal/library/hggen/internal/consts"
+ "hotgo/internal/library/hggen/internal/utility/mlog"
+)
+
+type apiInterfaceGenerator struct{}
+
+func newApiInterfaceGenerator() *apiInterfaceGenerator {
+ return &apiInterfaceGenerator{}
+}
+
+func (c *apiInterfaceGenerator) Generate(apiModuleFolderPath string, apiModuleApiItems []apiItem) (err error) {
+ if len(apiModuleApiItems) == 0 {
+ return nil
+ }
+ var firstApiItem = apiModuleApiItems[0]
+ if err = c.doGenerate(apiModuleFolderPath, firstApiItem.Module, apiModuleApiItems); err != nil {
+ return
+ }
+ return
+}
+
+func (c *apiInterfaceGenerator) doGenerate(apiModuleFolderPath string, module string, items []apiItem) (err error) {
+ var (
+ moduleFilePath = gfile.Join(apiModuleFolderPath, fmt.Sprintf(`%s.go`, module))
+ importPathMap = gmap.NewListMap()
+ importPaths []string
+ )
+ // all import paths.
+ importPathMap.Set("\t"+`"context"`, 1)
+ importPathMap.Set("\t"+``, 1)
+ for _, item := range items {
+ importPathMap.Set(fmt.Sprintf("\t"+`"%s"`, item.Import), 1)
+ }
+ importPaths = gconv.Strings(importPathMap.Keys())
+ // interface definitions.
+ var (
+ doneApiItemSet = gset.NewStrSet()
+ interfaceDefinition string
+ interfaceContent = gstr.TrimLeft(gstr.ReplaceByMap(consts.TemplateGenCtrlApiInterface, g.MapStrStr{
+ "{Module}": module,
+ "{ImportPaths}": gstr.Join(importPaths, "\n"),
+ }))
+ )
+ for _, item := range items {
+ if doneApiItemSet.Contains(item.String()) {
+ continue
+ }
+ // retrieve all api items of the same module.
+ subItems := c.getSubItemsByModuleAndVersion(items, item.Module, item.Version)
+ var (
+ method string
+ methods = make([]string, 0)
+ interfaceName = fmt.Sprintf(`I%s%s`, gstr.CaseCamel(item.Module), gstr.UcFirst(item.Version))
+ )
+ for _, subItem := range subItems {
+ method = fmt.Sprintf(
+ "\t%s(ctx context.Context, req *%s.%sReq) (res *%s.%sRes, err error)",
+ subItem.MethodName, subItem.Version, subItem.MethodName, subItem.Version, subItem.MethodName,
+ )
+ methods = append(methods, method)
+ doneApiItemSet.Add(subItem.String())
+ }
+ interfaceDefinition += fmt.Sprintf("type %s interface {", interfaceName)
+ interfaceDefinition += "\n"
+ interfaceDefinition += gstr.Join(methods, "\n")
+ interfaceDefinition += "\n"
+ interfaceDefinition += fmt.Sprintf("}")
+ interfaceDefinition += "\n\n"
+ }
+ interfaceContent = gstr.TrimLeft(gstr.ReplaceByMap(interfaceContent, g.MapStrStr{
+ "{Interfaces}": interfaceDefinition,
+ }))
+ err = gfile.PutContents(moduleFilePath, interfaceContent)
+ mlog.Printf(`generated: %s`, moduleFilePath)
+ return
+}
+
+func (c *apiInterfaceGenerator) getSubItemsByModule(items []apiItem, module string) (subItems []apiItem) {
+ for _, item := range items {
+ if item.Module == module {
+ subItems = append(subItems, item)
+ }
+ }
+ return
+}
+
+func (c *apiInterfaceGenerator) getSubItemsByModuleAndVersion(items []apiItem, module, version string) (subItems []apiItem) {
+ for _, item := range items {
+ if item.Module == module && item.Version == version {
+ subItems = append(subItems, item)
+ }
+ }
+ return
+}
diff --git a/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_sdk.go b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_sdk.go
new file mode 100644
index 0000000..2d9f45e
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genctrl/genctrl_generate_sdk.go
@@ -0,0 +1,194 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genctrl
+
+import (
+ "fmt"
+
+ "github.com/gogf/gf/v2/container/gset"
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/text/gregex"
+ "github.com/gogf/gf/v2/text/gstr"
+ "hotgo/internal/library/hggen/internal/consts"
+ "hotgo/internal/library/hggen/internal/utility/mlog"
+)
+
+type apiSdkGenerator struct{}
+
+func newApiSdkGenerator() *apiSdkGenerator {
+ return &apiSdkGenerator{}
+}
+
+func (c *apiSdkGenerator) Generate(apiModuleApiItems []apiItem, sdkFolderPath string, sdkStdVersion, sdkNoV1 bool) (err error) {
+ if err = c.doGenerateSdkPkgFile(sdkFolderPath); err != nil {
+ return
+ }
+
+ var doneApiItemSet = gset.NewStrSet()
+ for _, item := range apiModuleApiItems {
+ if doneApiItemSet.Contains(item.String()) {
+ continue
+ }
+ // retrieve all api items of the same module.
+ subItems := c.getSubItemsByModuleAndVersion(apiModuleApiItems, item.Module, item.Version)
+ if err = c.doGenerateSdkIClient(sdkFolderPath, item.Import, item.Module, item.Version, sdkNoV1); err != nil {
+ return
+ }
+ if err = c.doGenerateSdkImplementer(
+ subItems, sdkFolderPath, item.Import, item.Module, item.Version, sdkStdVersion, sdkNoV1,
+ ); err != nil {
+ return
+ }
+ for _, subItem := range subItems {
+ doneApiItemSet.Add(subItem.String())
+ }
+ }
+ return
+}
+
+func (c *apiSdkGenerator) doGenerateSdkPkgFile(sdkFolderPath string) (err error) {
+ var (
+ pkgName = gfile.Basename(sdkFolderPath)
+ pkgFilePath = gfile.Join(sdkFolderPath, fmt.Sprintf(`%s.go`, pkgName))
+ fileContent string
+ )
+ if gfile.Exists(pkgFilePath) {
+ return nil
+ }
+ fileContent = gstr.TrimLeft(gstr.ReplaceByMap(consts.TemplateGenCtrlSdkPkgNew, g.MapStrStr{
+ "{PkgName}": pkgName,
+ }))
+ err = gfile.PutContents(pkgFilePath, fileContent)
+ mlog.Printf(`generated: %s`, pkgFilePath)
+ return
+}
+
+func (c *apiSdkGenerator) doGenerateSdkIClient(
+ sdkFolderPath, versionImportPath, module, version string, sdkNoV1 bool,
+) (err error) {
+ var (
+ fileContent string
+ isDirty bool
+ isExist bool
+ pkgName = gfile.Basename(sdkFolderPath)
+ funcName = gstr.CaseCamel(module) + gstr.UcFirst(version)
+ interfaceName = fmt.Sprintf(`I%s`, funcName)
+ moduleImportPath = fmt.Sprintf(`"%s"`, gfile.Dir(versionImportPath))
+ iClientFilePath = gfile.Join(sdkFolderPath, fmt.Sprintf(`%s.iclient.go`, pkgName))
+ interfaceFuncDefinition = fmt.Sprintf(
+ `%s() %s.%s`,
+ gstr.CaseCamel(module)+gstr.UcFirst(version), module, interfaceName,
+ )
+ )
+ if sdkNoV1 && version == "v1" {
+ interfaceFuncDefinition = fmt.Sprintf(
+ `%s() %s.%s`,
+ gstr.CaseCamel(module), module, interfaceName,
+ )
+ }
+ if isExist = gfile.Exists(iClientFilePath); isExist {
+ fileContent = gfile.GetContents(iClientFilePath)
+ } else {
+ fileContent = gstr.TrimLeft(gstr.ReplaceByMap(consts.TemplateGenCtrlSdkIClient, g.MapStrStr{
+ "{PkgName}": pkgName,
+ }))
+ }
+
+ // append the import path to current import paths.
+ if !gstr.Contains(fileContent, moduleImportPath) {
+ isDirty = true
+ fileContent, err = gregex.ReplaceString(
+ `(import \([\s\S]*?)\)`,
+ fmt.Sprintf("$1\t%s\n)", moduleImportPath),
+ fileContent,
+ )
+ if err != nil {
+ return
+ }
+ }
+
+ // append the function definition to interface definition.
+ if !gstr.Contains(fileContent, interfaceFuncDefinition) {
+ isDirty = true
+ fileContent, err = gregex.ReplaceString(
+ `(type iClient interface {[\s\S]*?)}`,
+ fmt.Sprintf("$1\t%s\n}", interfaceFuncDefinition),
+ fileContent,
+ )
+ if err != nil {
+ return
+ }
+ }
+ if isDirty {
+ err = gfile.PutContents(iClientFilePath, fileContent)
+ if isExist {
+ mlog.Printf(`updated: %s`, iClientFilePath)
+ } else {
+ mlog.Printf(`generated: %s`, iClientFilePath)
+ }
+ }
+ return
+}
+
+func (c *apiSdkGenerator) doGenerateSdkImplementer(
+ items []apiItem, sdkFolderPath, versionImportPath, module, version string, sdkStdVersion, sdkNoV1 bool,
+) (err error) {
+ var (
+ pkgName = gfile.Basename(sdkFolderPath)
+ moduleNameCamel = gstr.CaseCamel(module)
+ moduleNameSnake = gstr.CaseSnake(module)
+ moduleImportPath = gfile.Dir(versionImportPath)
+ versionPrefix = ""
+ implementerName = moduleNameCamel + gstr.UcFirst(version)
+ implementerFilePath = gfile.Join(sdkFolderPath, fmt.Sprintf(
+ `%s_%s_%s.go`, pkgName, moduleNameSnake, version,
+ ))
+ )
+ if sdkNoV1 && version == "v1" {
+ implementerName = moduleNameCamel
+ }
+ // implementer file template.
+ var importPaths = make([]string, 0)
+ importPaths = append(importPaths, fmt.Sprintf("\t\"%s\"", moduleImportPath))
+ importPaths = append(importPaths, fmt.Sprintf("\t\"%s\"", versionImportPath))
+ implementerFileContent := gstr.TrimLeft(gstr.ReplaceByMap(consts.TemplateGenCtrlSdkImplementer, g.MapStrStr{
+ "{PkgName}": pkgName,
+ "{ImportPaths}": gstr.Join(importPaths, "\n"),
+ "{ImplementerName}": implementerName,
+ }))
+ // implementer new function definition.
+ if sdkStdVersion {
+ versionPrefix = fmt.Sprintf(`/api/%s`, version)
+ }
+ implementerFileContent += gstr.TrimLeft(gstr.ReplaceByMap(consts.TemplateGenCtrlSdkImplementerNew, g.MapStrStr{
+ "{Module}": module,
+ "{VersionPrefix}": versionPrefix,
+ "{ImplementerName}": implementerName,
+ }))
+ // implementer functions definitions.
+ for _, item := range items {
+ implementerFileContent += gstr.TrimLeft(gstr.ReplaceByMap(consts.TemplateGenCtrlSdkImplementerFunc, g.MapStrStr{
+ "{Version}": item.Version,
+ "{MethodName}": item.MethodName,
+ "{ImplementerName}": implementerName,
+ }))
+ implementerFileContent += "\n"
+ }
+ err = gfile.PutContents(implementerFilePath, implementerFileContent)
+ mlog.Printf(`generated: %s`, implementerFilePath)
+ return
+}
+
+func (c *apiSdkGenerator) getSubItemsByModuleAndVersion(items []apiItem, module, version string) (subItems []apiItem) {
+ for _, item := range items {
+ if item.Module == module && item.Version == version {
+ subItems = append(subItems, item)
+ }
+ }
+ return
+}
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao.go b/server/internal/library/hggen/internal/cmd/gendao/gendao.go
index 046225a..fd6147f 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao.go
@@ -1,18 +1,26 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package gendao
import (
"context"
"fmt"
+ "golang.org/x/mod/modfile"
"strings"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/os/gtime"
- "github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gtag"
+ "hotgo/internal/library/hggen/internal/utility/utils"
"hotgo/internal/library/hggen/internal/utility/mlog"
)
@@ -43,6 +51,12 @@ CONFIGURATION SUPPORT
path: "./my-app"
prefix: "primary_"
tables: "user, userDetail"
+ typeMapping:
+ decimal:
+ type: decimal.Decimal
+ import: github.com/shopspring/decimal
+ numeric:
+ type: string
`
CGenDaoBriefPath = `directory path for generated files`
CGenDaoBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
@@ -64,6 +78,7 @@ CONFIGURATION SUPPORT
CGenDaoBriefNoJsonTag = `no json tag will be added for each field`
CGenDaoBriefNoModelComment = `no model comment will be added for each field`
CGenDaoBriefClear = `delete all generated go files that do not exist in database`
+ CGenDaoBriefTypeMapping = `custom local type mapping for generated struct attributes relevant to fields of table`
CGenDaoBriefGroup = `
specifying the configuration group name of database for generated ORM instance,
it's not necessary and the default value is "default"
@@ -99,7 +114,21 @@ generated json tag case for model struct, cases are as follows:
)
var (
- createdAt = gtime.Now()
+ createdAt = gtime.Now()
+ defaultTypeMapping = map[string]TypeMapping{
+ "decimal": {
+ Type: "float64",
+ },
+ "money": {
+ Type: "float64",
+ },
+ "numeric": {
+ Type: "float64",
+ },
+ "smallmoney": {
+ Type: "float64",
+ },
+ }
)
func init() {
@@ -129,6 +158,7 @@ func init() {
`CGenDaoBriefNoJsonTag`: CGenDaoBriefNoJsonTag,
`CGenDaoBriefNoModelComment`: CGenDaoBriefNoModelComment,
`CGenDaoBriefClear`: CGenDaoBriefClear,
+ `CGenDaoBriefTypeMapping`: CGenDaoBriefTypeMapping,
`CGenDaoBriefGroup`: CGenDaoBriefGroup,
`CGenDaoBriefJsonCase`: CGenDaoBriefJsonCase,
`CGenDaoBriefTplDaoIndexPath`: CGenDaoBriefTplDaoIndexPath,
@@ -142,30 +172,31 @@ type (
CGenDao struct{}
CGenDaoInput struct {
g.Meta `name:"dao" config:"{CGenDaoConfig}" usage:"{CGenDaoUsage}" brief:"{CGenDaoBrief}" eg:"{CGenDaoEg}" ad:"{CGenDaoAd}"`
- Path string `name:"path" short:"p" brief:"{CGenDaoBriefPath}" d:"internal"`
- Link string `name:"link" short:"l" brief:"{CGenDaoBriefLink}"`
- Tables string `name:"tables" short:"t" brief:"{CGenDaoBriefTables}"`
- TablesEx string `name:"tablesEx" short:"x" brief:"{CGenDaoBriefTablesEx}"`
- Group string `name:"group" short:"g" brief:"{CGenDaoBriefGroup}" d:"default"`
- Prefix string `name:"prefix" short:"f" brief:"{CGenDaoBriefPrefix}"`
- RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenDaoBriefRemovePrefix}"`
- JsonCase string `name:"jsonCase" short:"j" brief:"{CGenDaoBriefJsonCase}" d:"CamelLower"`
- ImportPrefix string `name:"importPrefix" short:"i" brief:"{CGenDaoBriefImportPrefix}"`
- DaoPath string `name:"daoPath" short:"d" brief:"{CGenDaoBriefDaoPath}" d:"dao"`
- DoPath string `name:"doPath" short:"o" brief:"{CGenDaoBriefDoPath}" d:"model/do"`
- EntityPath string `name:"entityPath" short:"e" brief:"{CGenDaoBriefEntityPath}" d:"model/entity"`
- TplDaoIndexPath string `name:"tplDaoIndexPath" short:"t1" brief:"{CGenDaoBriefTplDaoIndexPath}"`
- TplDaoInternalPath string `name:"tplDaoInternalPath" short:"t2" brief:"{CGenDaoBriefTplDaoInternalPath}"`
- TplDaoDoPath string `name:"tplDaoDoPath" short:"t3" brief:"{CGenDaoBriefTplDaoDoPathPath}"`
- TplDaoEntityPath string `name:"tplDaoEntityPath" short:"t4" brief:"{CGenDaoBriefTplDaoEntityPath}"`
- StdTime bool `name:"stdTime" short:"s" brief:"{CGenDaoBriefStdTime}" orphan:"true"`
- WithTime bool `name:"withTime" short:"w" brief:"{CGenDaoBriefWithTime}" orphan:"true"`
- GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{CGenDaoBriefGJsonSupport}" orphan:"true"`
- OverwriteDao bool `name:"overwriteDao" short:"v" brief:"{CGenDaoBriefOverwriteDao}" orphan:"true"`
- DescriptionTag bool `name:"descriptionTag" short:"c" brief:"{CGenDaoBriefDescriptionTag}" orphan:"true"`
- NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{CGenDaoBriefNoJsonTag}" orphan:"true"`
- NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
- Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
+ Path string `name:"path" short:"p" brief:"{CGenDaoBriefPath}" d:"internal"`
+ Link string `name:"link" short:"l" brief:"{CGenDaoBriefLink}"`
+ Tables string `name:"tables" short:"t" brief:"{CGenDaoBriefTables}"`
+ TablesEx string `name:"tablesEx" short:"x" brief:"{CGenDaoBriefTablesEx}"`
+ Group string `name:"group" short:"g" brief:"{CGenDaoBriefGroup}" d:"default"`
+ Prefix string `name:"prefix" short:"f" brief:"{CGenDaoBriefPrefix}"`
+ RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenDaoBriefRemovePrefix}"`
+ JsonCase string `name:"jsonCase" short:"j" brief:"{CGenDaoBriefJsonCase}" d:"CamelLower"`
+ ImportPrefix string `name:"importPrefix" short:"i" brief:"{CGenDaoBriefImportPrefix}"`
+ DaoPath string `name:"daoPath" short:"d" brief:"{CGenDaoBriefDaoPath}" d:"dao"`
+ DoPath string `name:"doPath" short:"o" brief:"{CGenDaoBriefDoPath}" d:"model/do"`
+ EntityPath string `name:"entityPath" short:"e" brief:"{CGenDaoBriefEntityPath}" d:"model/entity"`
+ TplDaoIndexPath string `name:"tplDaoIndexPath" short:"t1" brief:"{CGenDaoBriefTplDaoIndexPath}"`
+ TplDaoInternalPath string `name:"tplDaoInternalPath" short:"t2" brief:"{CGenDaoBriefTplDaoInternalPath}"`
+ TplDaoDoPath string `name:"tplDaoDoPath" short:"t3" brief:"{CGenDaoBriefTplDaoDoPathPath}"`
+ TplDaoEntityPath string `name:"tplDaoEntityPath" short:"t4" brief:"{CGenDaoBriefTplDaoEntityPath}"`
+ StdTime bool `name:"stdTime" short:"s" brief:"{CGenDaoBriefStdTime}" orphan:"true"`
+ WithTime bool `name:"withTime" short:"w" brief:"{CGenDaoBriefWithTime}" orphan:"true"`
+ GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{CGenDaoBriefGJsonSupport}" orphan:"true"`
+ OverwriteDao bool `name:"overwriteDao" short:"v" brief:"{CGenDaoBriefOverwriteDao}" orphan:"true"`
+ DescriptionTag bool `name:"descriptionTag" short:"c" brief:"{CGenDaoBriefDescriptionTag}" orphan:"true"`
+ NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{CGenDaoBriefNoJsonTag}" orphan:"true"`
+ NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
+ Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
+ TypeMapping map[string]TypeMapping `name:"typeMapping" short:"y" brief:"{CGenDaoBriefTypeMapping}" orphan:"true"`
}
CGenDaoOutput struct{}
@@ -174,7 +205,11 @@ type (
DB gdb.DB
TableNames []string
NewTableNames []string
- ModName string // Module name of current golang project, which is used for import purpose.
+ }
+
+ TypeMapping struct {
+ Type string `brief:"custom attribute type name"`
+ Import string `brief:"custom import for this type"`
}
)
@@ -195,16 +230,11 @@ func (c CGenDao) Dao(ctx context.Context, in CGenDaoInput) (out *CGenDaoOutput,
return
}
-func DoGenDaoForArray(ctx context.Context, in CGenDaoInput) {
- doGenDaoForArray(ctx, -1, in)
-}
-
// doGenDaoForArray implements the "gen dao" command for configuration array.
func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
var (
- err error
- db gdb.DB
- modName string // Go module name, eg: github.com/gogf/gf.
+ err error
+ db gdb.DB
)
if index >= 0 {
err = g.Cfg().MustGet(
@@ -219,20 +249,6 @@ func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
mlog.Fatalf(`path "%s" does not exist`, in.Path)
}
removePrefixArray := gstr.SplitAndTrim(in.RemovePrefix, ",")
- if in.ImportPrefix == "" {
- if !gfile.Exists("go.mod") {
- mlog.Fatal("go.mod does not exist in current working directory")
- }
- var (
- goModContent = gfile.GetContents("go.mod")
- match, _ = gregex.MatchString(`^module\s+(.+)\s*`, goModContent)
- )
- if len(match) > 1 {
- modName = gstr.Trim(match[1])
- } else {
- mlog.Fatal("module name does not found in go.mod")
- }
- }
// It uses user passed database configuration.
if in.Link != "" {
@@ -268,6 +284,17 @@ func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
tableNames = array.Slice()
}
+ // merge default typeMapping to input typeMapping.
+ if in.TypeMapping == nil {
+ in.TypeMapping = defaultTypeMapping
+ } else {
+ for key, typeMapping := range defaultTypeMapping {
+ if _, ok := in.TypeMapping[key]; !ok {
+ in.TypeMapping[key] = typeMapping
+ }
+ }
+ }
+
// Generating dao & model go files one by one according to given table name.
newTableNames := make([]string, len(tableNames))
for i, tableName := range tableNames {
@@ -278,13 +305,13 @@ func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
newTableName = in.Prefix + newTableName
newTableNames[i] = newTableName
}
+
// Dao: index and internal.
generateDao(ctx, CGenDaoInternalInput{
CGenDaoInput: in,
DB: db,
TableNames: tableNames,
NewTableNames: newTableNames,
- ModName: modName,
})
// Do.
generateDo(ctx, CGenDaoInternalInput{
@@ -292,7 +319,6 @@ func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
DB: db,
TableNames: tableNames,
NewTableNames: newTableNames,
- ModName: modName,
})
// Entity.
generateEntity(ctx, CGenDaoInternalInput{
@@ -300,15 +326,11 @@ func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
DB: db,
TableNames: tableNames,
NewTableNames: newTableNames,
- ModName: modName,
})
}
-func getImportPartContent(source string, isDo bool) string {
- var (
- packageImportsArray = garray.NewStrArray()
- )
-
+func getImportPartContent(ctx context.Context, source string, isDo bool, appendImports []string) string {
+ var packageImportsArray = garray.NewStrArray()
if isDo {
packageImportsArray.Append(`"github.com/gogf/gf/v2/frame/g"`)
}
@@ -325,6 +347,32 @@ func getImportPartContent(source string, isDo bool) string {
packageImportsArray.Append(`"github.com/gogf/gf/v2/encoding/gjson"`)
}
+ // Check and update imports in go.mod
+ if appendImports != nil && len(appendImports) > 0 {
+ goModPath := utils.GetModPath()
+ if goModPath == "" {
+ mlog.Fatal("go.mod not found in current project")
+ }
+ mod, err := modfile.Parse(goModPath, gfile.GetBytes(goModPath), nil)
+ if err != nil {
+ mlog.Fatalf("parse go.mod failed: %+v", err)
+ }
+ for _, appendImport := range appendImports {
+ found := false
+ for _, require := range mod.Require {
+ if gstr.Contains(appendImport, require.Mod.Path) {
+ found = true
+ break
+ }
+ }
+ if !found {
+ err = gproc.ShellRun(ctx, `go get `+appendImport)
+ mlog.Fatalf(`%+v`, err)
+ }
+ packageImportsArray.Append(fmt.Sprintf(`"%s"`, appendImport))
+ }
+ }
+
// Generate and write content to golang file.
packageImportsStr := ""
if packageImportsArray.Len() > 0 {
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_clear.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_clear.go
index fd7d51a..91c624e 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao_clear.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_clear.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package gendao
import (
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go
index 0760c81..fca9661 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package gendao
import (
@@ -6,12 +12,12 @@ import (
"fmt"
"strings"
+ "github.com/olekukonko/tablewriter"
+
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
- "github.com/olekukonko/tablewriter"
"hotgo/internal/library/hggen/internal/consts"
"hotgo/internal/library/hggen/internal/utility/mlog"
@@ -53,23 +59,13 @@ func generateDaoSingle(ctx context.Context, in generateDaoSingleInput) {
mlog.Fatalf(`fetching tables fields failed for table "%s": %+v`, in.TableName, err)
}
var (
- dirRealPath = gfile.RealPath(in.Path)
tableNameCamelCase = gstr.CaseCamel(in.NewTableName)
tableNameCamelLowerCase = gstr.CaseCamelLower(in.NewTableName)
tableNameSnakeCase = gstr.CaseSnake(in.NewTableName)
importPrefix = in.ImportPrefix
)
if importPrefix == "" {
- if dirRealPath == "" {
- dirRealPath = in.Path
- importPrefix = dirRealPath
- importPrefix = gstr.Trim(dirRealPath, "./")
- } else {
- importPrefix = gstr.Replace(dirRealPath, gfile.Pwd(), "")
- }
- importPrefix = gstr.Replace(importPrefix, gfile.Separator, "/")
- importPrefix = gstr.Join(g.SliceStr{in.ModName, importPrefix, in.DaoPath}, "/")
- importPrefix, _ = gregex.ReplaceString(`\/{2,}`, `/`, gstr.Trim(importPrefix, "/"))
+ importPrefix = utils.GetImportPath(gfile.Join(in.Path, in.DaoPath))
} else {
importPrefix = gstr.Join(g.SliceStr{importPrefix, in.DaoPath}, "/")
}
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_do.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_do.go
index c3686ea..d801557 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao_do.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_do.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package gendao
import (
@@ -30,9 +36,9 @@ func generateDo(ctx context.Context, in CGenDaoInternalInput) {
mlog.Fatalf("fetching tables fields failed for table '%s':\n%v", tableName, err)
}
var (
- newTableName = in.NewTableNames[i]
- doFilePath = gfile.Join(dirPathDo, gstr.CaseSnake(newTableName)+".go")
- structDefinition = generateStructDefinition(ctx, generateStructDefinitionInput{
+ newTableName = in.NewTableNames[i]
+ doFilePath = gfile.Join(dirPathDo, gstr.CaseSnake(newTableName)+".go")
+ structDefinition, _ = generateStructDefinition(ctx, generateStructDefinitionInput{
CGenDaoInternalInput: in,
TableName: tableName,
StructName: gstr.CaseCamel(newTableName),
@@ -53,6 +59,7 @@ func generateDo(ctx context.Context, in CGenDaoInternalInput) {
},
)
modelContent := generateDoContent(
+ ctx,
in,
tableName,
gstr.CaseCamel(newTableName),
@@ -68,15 +75,18 @@ func generateDo(ctx context.Context, in CGenDaoInternalInput) {
}
}
-func generateDoContent(in CGenDaoInternalInput, tableName, tableNameCamelCase, structDefine string) string {
+func generateDoContent(
+ ctx context.Context, in CGenDaoInternalInput, tableName, tableNameCamelCase, structDefine string,
+) string {
doContent := gstr.ReplaceByMap(
getTemplateFromPathOrDefault(in.TplDaoDoPath, consts.TemplateGenDaoDoContent),
g.MapStrStr{
tplVarTableName: tableName,
- tplVarPackageImports: getImportPartContent(structDefine, true),
+ tplVarPackageImports: getImportPartContent(ctx, structDefine, true, nil),
tplVarTableNameCamelCase: tableNameCamelCase,
tplVarStructDefine: structDefine,
- })
+ },
+ )
doContent = replaceDefaultVar(in, doContent)
return doContent
}
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_entity.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_entity.go
index 0d21061..a6a7140 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao_entity.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_entity.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package gendao
import (
@@ -24,22 +30,27 @@ func generateEntity(ctx context.Context, in CGenDaoInternalInput) {
if err != nil {
mlog.Fatalf("fetching tables fields failed for table '%s':\n%v", tableName, err)
}
+
var (
- newTableName = in.NewTableNames[i]
- entityFilePath = gfile.Join(dirPathEntity, gstr.CaseSnake(newTableName)+".go")
- entityContent = generateEntityContent(
+ newTableName = in.NewTableNames[i]
+ entityFilePath = gfile.Join(dirPathEntity, gstr.CaseSnake(newTableName)+".go")
+ structDefinition, appendImports = generateStructDefinition(ctx, generateStructDefinitionInput{
+ CGenDaoInternalInput: in,
+ TableName: tableName,
+ StructName: gstr.CaseCamel(newTableName),
+ FieldMap: fieldMap,
+ IsDo: false,
+ })
+ entityContent = generateEntityContent(
+ ctx,
in,
newTableName,
gstr.CaseCamel(newTableName),
- generateStructDefinition(ctx, generateStructDefinitionInput{
- CGenDaoInternalInput: in,
- TableName: tableName,
- StructName: gstr.CaseCamel(newTableName),
- FieldMap: fieldMap,
- IsDo: false,
- }),
+ structDefinition,
+ appendImports,
)
)
+
err = gfile.PutContents(entityFilePath, strings.TrimSpace(entityContent))
if err != nil {
mlog.Fatalf("writing content to '%s' failed: %v", entityFilePath, err)
@@ -50,15 +61,18 @@ func generateEntity(ctx context.Context, in CGenDaoInternalInput) {
}
}
-func generateEntityContent(in CGenDaoInternalInput, tableName, tableNameCamelCase, structDefine string) string {
+func generateEntityContent(
+ ctx context.Context, in CGenDaoInternalInput, tableName, tableNameCamelCase, structDefine string, appendImports []string,
+) string {
entityContent := gstr.ReplaceByMap(
getTemplateFromPathOrDefault(in.TplDaoEntityPath, consts.TemplateGenDaoEntityContent),
g.MapStrStr{
tplVarTableName: tableName,
- tplVarPackageImports: getImportPartContent(structDefine, false),
+ tplVarPackageImports: getImportPartContent(ctx, structDefine, false, appendImports),
tplVarTableNameCamelCase: tableNameCamelCase,
tplVarStructDefine: structDefine,
- })
+ },
+ )
entityContent = replaceDefaultVar(in, entityContent)
return entityContent
}
diff --git a/server/internal/library/hggen/internal/cmd/gendao/gendao_structure.go b/server/internal/library/hggen/internal/cmd/gendao/gendao_structure.go
index 0891fa4..a88fa5c 100644
--- a/server/internal/library/hggen/internal/cmd/gendao/gendao_structure.go
+++ b/server/internal/library/hggen/internal/cmd/gendao/gendao_structure.go
@@ -1,15 +1,22 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package gendao
import (
"bytes"
"context"
"fmt"
+ "github.com/olekukonko/tablewriter"
+ "strings"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
- "github.com/olekukonko/tablewriter"
)
type generateStructDefinitionInput struct {
@@ -20,13 +27,18 @@ type generateStructDefinitionInput struct {
IsDo bool // Is generating DTO struct.
}
-func generateStructDefinition(ctx context.Context, in generateStructDefinitionInput) string {
+func generateStructDefinition(ctx context.Context, in generateStructDefinitionInput) (string, []string) {
+ var appendImports []string
buffer := bytes.NewBuffer(nil)
array := make([][]string, len(in.FieldMap))
names := sortFieldKeyForDao(in.FieldMap)
for index, name := range names {
+ var imports string
field := in.FieldMap[name]
- array[index] = generateStructFieldDefinition(ctx, field, in)
+ array[index], imports = generateStructFieldDefinition(ctx, field, in)
+ if imports != "" {
+ appendImports = append(appendImports, imports)
+ }
}
tw := tablewriter.NewWriter(buffer)
tw.SetBorder(false)
@@ -47,21 +59,42 @@ func generateStructDefinition(ctx context.Context, in generateStructDefinitionIn
}
buffer.WriteString(stContent)
buffer.WriteString("}")
- return buffer.String()
+ return buffer.String(), appendImports
}
// generateStructFieldDefinition generates and returns the attribute definition for specified field.
func generateStructFieldDefinition(
ctx context.Context, field *gdb.TableField, in generateStructDefinitionInput,
-) []string {
+) (attrLines []string, appendImport string) {
var (
err error
typeName string
jsonTag = getJsonTagFromCase(field.Name, in.JsonCase)
)
- typeName, err = in.DB.CheckLocalTypeForField(ctx, field.Type, nil)
- if err != nil {
- panic(err)
+
+ if in.TypeMapping != nil && len(in.TypeMapping) > 0 {
+ var (
+ tryTypeName string
+ )
+ tryTypeMatch, _ := gregex.MatchString(`(.+?)\((.+)\)`, field.Type)
+ if len(tryTypeMatch) == 3 {
+ tryTypeName = gstr.Trim(tryTypeMatch[1])
+ } else {
+ tryTypeName = gstr.Split(field.Type, " ")[0]
+ }
+ if tryTypeName != "" {
+ if typeMapping, ok := in.TypeMapping[strings.ToLower(tryTypeName)]; ok {
+ typeName = typeMapping.Type
+ appendImport = typeMapping.Import
+ }
+ }
+ }
+
+ if typeName == "" {
+ typeName, err = in.DB.CheckLocalTypeForField(ctx, field.Type, nil)
+ if err != nil {
+ panic(err)
+ }
}
switch typeName {
case gdb.LocalTypeDate, gdb.LocalTypeDatetime:
@@ -87,19 +120,18 @@ func generateStructFieldDefinition(
}
var (
- tagKey = "`"
- result = []string{
- " #" + gstr.CaseCamel(field.Name),
- " #" + typeName,
- }
+ tagKey = "`"
descriptionTag = gstr.Replace(formatComment(field.Comment), `"`, `\"`)
)
+ attrLines = []string{
+ " #" + gstr.CaseCamel(field.Name),
+ " #" + typeName,
+ }
+ attrLines = append(attrLines, " #"+fmt.Sprintf(tagKey+`json:"%s"`, jsonTag))
+ attrLines = append(attrLines, " #"+fmt.Sprintf(`description:"%s"`+tagKey, descriptionTag))
+ attrLines = append(attrLines, " #"+fmt.Sprintf(`// %s`, formatComment(field.Comment)))
- result = append(result, " #"+fmt.Sprintf(tagKey+`json:"%s"`, jsonTag))
- result = append(result, " #"+fmt.Sprintf(`description:"%s"`+tagKey, descriptionTag))
- result = append(result, " #"+fmt.Sprintf(`// %s`, formatComment(field.Comment)))
-
- for k, v := range result {
+ for k, v := range attrLines {
if in.NoJsonTag {
v, _ = gregex.ReplaceString(`json:".+"`, ``, v)
}
@@ -109,9 +141,9 @@ func generateStructFieldDefinition(
if in.NoModelComment {
v, _ = gregex.ReplaceString(`//.+`, ``, v)
}
- result[k] = v
+ attrLines[k] = v
}
- return result
+ return attrLines, appendImport
}
// formatComment formats the comment string to fit the golang code without any lines.
diff --git a/server/internal/library/hggen/internal/cmd/genenums/genenums.go b/server/internal/library/hggen/internal/cmd/genenums/genenums.go
index a07baeb..962818f 100644
--- a/server/internal/library/hggen/internal/cmd/genenums/genenums.go
+++ b/server/internal/library/hggen/internal/cmd/genenums/genenums.go
@@ -21,10 +21,10 @@ import (
type (
CGenEnums struct{}
CGenEnumsInput struct {
- g.Meta `name:"enums" config:"{CGenEnumsConfig}" brief:"{CGenEnumsBrief}" eg:"{CGenEnumsEg}"`
- Src string `name:"src" short:"s" dc:"source folder path to be parsed" d:"."`
- Path string `name:"path" short:"p" dc:"output go file path storing enums content" d:"internal/boot/boot_enums.go"`
- Prefix string `name:"prefix" short:"x" dc:"only exports packages that starts with specified prefix"`
+ g.Meta `name:"enums" config:"{CGenEnumsConfig}" brief:"{CGenEnumsBrief}" eg:"{CGenEnumsEg}"`
+ Src string `name:"src" short:"s" dc:"source folder path to be parsed" d:"."`
+ Path string `name:"path" short:"p" dc:"output go file path storing enums content" d:"internal/boot/boot_enums.go"`
+ Prefixes []string `name:"prefixes" short:"x" dc:"only exports packages that starts with specified prefixes"`
}
CGenEnumsOutput struct{}
)
@@ -57,7 +57,7 @@ func (c CGenEnums) Enums(ctx context.Context, in CGenEnumsInput) (out *CGenEnums
if err != nil {
mlog.Fatal(err)
}
- mlog.Printf(`scanning: %s`, realPath)
+ mlog.Printf(`scanning for enums: %s`, realPath)
cfg := &packages.Config{
Dir: realPath,
Mode: pkgLoadMode,
@@ -67,7 +67,7 @@ func (c CGenEnums) Enums(ctx context.Context, in CGenEnumsInput) (out *CGenEnums
if err != nil {
mlog.Fatal(err)
}
- p := NewEnumsParser(in.Prefix)
+ p := NewEnumsParser(in.Prefixes)
p.ParsePackages(pkgs)
var enumsContent = gstr.ReplaceByMap(consts.TemplateGenEnums, g.MapStrStr{
"{PackageName}": gfile.Basename(gfile.Dir(in.Path)),
@@ -77,7 +77,7 @@ func (c CGenEnums) Enums(ctx context.Context, in CGenEnumsInput) (out *CGenEnums
if err = gfile.PutContents(in.Path, enumsContent); err != nil {
return
}
- mlog.Printf(`generated: %s`, in.Path)
+ mlog.Printf(`generated enums go file: %s`, in.Path)
mlog.Print("done!")
return
}
diff --git a/server/internal/library/hggen/internal/cmd/genenums/genenums_parser.go b/server/internal/library/hggen/internal/cmd/genenums/genenums_parser.go
index b12b339..5e38492 100644
--- a/server/internal/library/hggen/internal/cmd/genenums/genenums_parser.go
+++ b/server/internal/library/hggen/internal/cmd/genenums/genenums_parser.go
@@ -21,7 +21,7 @@ const pkgLoadMode = 0xffffff
type EnumsParser struct {
enums []EnumItem
parsedPkg map[string]struct{}
- prefix string
+ prefixes []string
}
type EnumItem struct {
@@ -33,21 +33,21 @@ type EnumItem struct {
var standardPackages = make(map[string]struct{})
-//func init() {
-// stdPackages, err := packages.Load(nil, "std")
-// if err != nil {
-// panic(err)
-// }
-// for _, p := range stdPackages {
-// standardPackages[p.ID] = struct{}{}
-// }
-//}
+func init() {
+ stdPackages, err := packages.Load(nil, "std")
+ if err != nil {
+ panic(err)
+ }
+ for _, p := range stdPackages {
+ standardPackages[p.ID] = struct{}{}
+ }
+}
-func NewEnumsParser(prefix string) *EnumsParser {
+func NewEnumsParser(prefixes []string) *EnumsParser {
return &EnumsParser{
enums: make([]EnumItem, 0),
parsedPkg: make(map[string]struct{}),
- prefix: prefix,
+ prefixes: prefixes,
}
}
@@ -67,9 +67,16 @@ func (p *EnumsParser) ParsePackage(pkg *packages.Package) {
return
}
p.parsedPkg[pkg.ID] = struct{}{}
- // Only parse specified prefix.
- if p.prefix != "" {
- if !gstr.HasPrefix(pkg.ID, p.prefix) {
+
+ // Only parse specified prefixes.
+ if len(p.prefixes) > 0 {
+ var hasPrefix bool
+ for _, prefix := range p.prefixes {
+ if hasPrefix = gstr.HasPrefix(pkg.ID, prefix); hasPrefix {
+ break
+ }
+ }
+ if !hasPrefix {
return
}
}
@@ -108,7 +115,6 @@ func (p *EnumsParser) ParsePackage(pkg *packages.Package) {
Type: enumType,
Kind: enumKind,
})
-
}
for _, im := range pkg.Imports {
p.ParsePackage(im)
diff --git a/server/internal/library/hggen/internal/cmd/genpb/genpb.go b/server/internal/library/hggen/internal/cmd/genpb/genpb.go
new file mode 100644
index 0000000..768926c
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genpb/genpb.go
@@ -0,0 +1,128 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genpb
+
+import (
+ "context"
+
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gproc"
+ "github.com/gogf/gf/v2/util/gtag"
+ "hotgo/internal/library/hggen/internal/utility/mlog"
+)
+
+type (
+ CGenPb struct{}
+ CGenPbInput struct {
+ g.Meta `name:"pb" config:"{CGenPbConfig}" brief:"{CGenPbBrief}" eg:"{CGenPbEg}"`
+ Path string `name:"path" short:"p" dc:"protobuf file folder path" d:"manifest/protobuf"`
+ OutputApi string `name:"api" short:"a" dc:"output folder path storing generated go files of api" d:"api"`
+ OutputCtrl string `name:"ctrl" short:"c" dc:"output folder path storing generated go files of controller" d:"internal/controller"`
+ }
+ CGenPbOutput struct{}
+)
+
+const (
+ CGenPbConfig = `gfcli.gen.pb`
+ CGenPbBrief = `parse proto files and generate protobuf go files`
+ CGenPbEg = `
+gf gen pb
+gf gen pb -p . -a . -p .
+`
+)
+
+func init() {
+ gtag.Sets(g.MapStrStr{
+ `CGenPbEg`: CGenPbEg,
+ `CGenPbBrief`: CGenPbBrief,
+ `CGenPbConfig`: CGenPbConfig,
+ })
+}
+
+func (c CGenPb) Pb(ctx context.Context, in CGenPbInput) (out *CGenPbOutput, err error) {
+ // Necessary check.
+ protoc := gproc.SearchBinary("protoc")
+ if protoc == "" {
+ mlog.Fatalf(`command "protoc" not found in your environment, please install protoc first: https://grpc.io/docs/languages/go/quickstart/`)
+ }
+
+ // protocol fold checks.
+ var (
+ protoPath = gfile.RealPath(in.Path)
+ isParsingPWD bool
+ )
+ if protoPath == "" {
+ // Use current working directory as protoPath if there are proto files under.
+ currentPath := gfile.Pwd()
+ currentFiles, _ := gfile.ScanDirFile(currentPath, "*.proto")
+ if len(currentFiles) > 0 {
+ protoPath = currentPath
+ isParsingPWD = true
+ } else {
+ mlog.Fatalf(`proto files folder "%s" does not exist`, in.Path)
+ }
+ }
+ // output path checks.
+ outputApiPath := gfile.RealPath(in.OutputApi)
+ if outputApiPath == "" {
+ if isParsingPWD {
+ outputApiPath = protoPath
+ } else {
+ mlog.Fatalf(`output api folder "%s" does not exist`, in.OutputApi)
+ }
+ }
+ outputCtrlPath := gfile.RealPath(in.OutputCtrl)
+ if outputCtrlPath == "" {
+ if isParsingPWD {
+ outputCtrlPath = ""
+ } else {
+ mlog.Fatalf(`output controller folder "%s" does not exist`, in.OutputCtrl)
+ }
+ }
+
+ // folder scanning.
+ files, err := gfile.ScanDirFile(protoPath, "*.proto", true)
+ if err != nil {
+ mlog.Fatal(err)
+ }
+ if len(files) == 0 {
+ mlog.Fatalf(`no proto files found in folder "%s"`, in.Path)
+ }
+
+ if err = gfile.Chdir(protoPath); err != nil {
+ mlog.Fatal(err)
+ }
+ for _, file := range files {
+ var command = gproc.NewProcess(protoc, nil)
+ command.Args = append(command.Args, "--proto_path="+gfile.Pwd())
+ command.Args = append(command.Args, "--go_out=paths=source_relative:"+outputApiPath)
+ command.Args = append(command.Args, "--go-grpc_out=paths=source_relative:"+outputApiPath)
+ command.Args = append(command.Args, file)
+ mlog.Print(command.String())
+ if err = command.Run(ctx); err != nil {
+ mlog.Fatal(err)
+ }
+ }
+ // Generate struct tag according comment rules.
+ err = c.generateStructTag(ctx, generateStructTagInput{OutputApiPath: outputApiPath})
+ if err != nil {
+ return
+ }
+ // Generate controllers according comment rules.
+ if outputCtrlPath != "" {
+ err = c.generateController(ctx, generateControllerInput{
+ OutputApiPath: outputApiPath,
+ OutputCtrlPath: outputCtrlPath,
+ })
+ if err != nil {
+ return
+ }
+ }
+ mlog.Print("done!")
+ return
+}
diff --git a/server/internal/library/hggen/internal/cmd/genpb/genpb_controller.go b/server/internal/library/hggen/internal/cmd/genpb/genpb_controller.go
new file mode 100644
index 0000000..f29ec5b
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genpb/genpb_controller.go
@@ -0,0 +1,196 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genpb
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/text/gregex"
+ "github.com/gogf/gf/v2/text/gstr"
+ "hotgo/internal/library/hggen/internal/utility/utils"
+)
+
+type generateControllerInput struct {
+ OutputApiPath string
+ OutputCtrlPath string
+}
+
+type generateCtrl struct {
+ Name string
+ Package string
+ Version string
+ Methods []generateCtrlMethod
+}
+
+type generateCtrlMethod struct {
+ Name string
+ Definition string
+}
+
+const (
+ controllerTemplate = `
+package {Package}
+
+type Controller struct {
+ {Version}.Unimplemented{Name}Server
+}
+
+func Register(s *grpcx.GrpcServer) {
+ {Version}.Register{Name}Server(s.Server, &Controller{})
+}
+`
+ controllerMethodTemplate = `
+func (*Controller) {Definition} {
+ return nil, gerror.NewCode(gcode.CodeNotImplemented)
+}
+`
+)
+
+func (c CGenPb) generateController(ctx context.Context, in generateControllerInput) (err error) {
+ files, err := gfile.ScanDirFile(in.OutputApiPath, "*_grpc.pb.go", true)
+ if err != nil {
+ return err
+ }
+ var controllers []generateCtrl
+ for _, file := range files {
+ fileControllers, err := c.parseControllers(file)
+ if err != nil {
+ return err
+ }
+ controllers = append(controllers, fileControllers...)
+ }
+ if len(controllers) == 0 {
+ return nil
+ }
+ // Generate controller files.
+ err = c.doGenerateControllers(in, controllers)
+ return
+}
+
+func (c CGenPb) parseControllers(filePath string) ([]generateCtrl, error) {
+ var (
+ controllers []generateCtrl
+ content = gfile.GetContents(filePath)
+ )
+ _, err := gregex.ReplaceStringFuncMatch(
+ `type (\w+)Server interface {([\s\S]+?)}`,
+ content,
+ func(match []string) string {
+ ctrl := generateCtrl{
+ Name: match[1],
+ Package: strings.ReplaceAll(gfile.Basename(gfile.Dir(gfile.Dir(filePath))), "-", "_"),
+ Version: gfile.Basename(gfile.Dir(filePath)),
+ Methods: make([]generateCtrlMethod, 0),
+ }
+ lines := gstr.Split(match[2], "\n")
+ for _, line := range lines {
+ line = gstr.Trim(line)
+ if line == "" || !gstr.IsLetterUpper(line[0]) {
+ continue
+ }
+ // Comment.
+ if gregex.IsMatchString(`^//.+`, line) {
+ continue
+ }
+ line, _ = gregex.ReplaceStringFuncMatch(
+ `^(\w+)\(context\.Context, \*(\w+)\) \(\*(\w+), error\)$`,
+ line,
+ func(match []string) string {
+ return fmt.Sprintf(
+ `%s(ctx context.Context, req *%s.%s) (res *%s.%s, err error)`,
+ match[1], ctrl.Version, match[2], ctrl.Version, match[3],
+ )
+ },
+ )
+ ctrl.Methods = append(ctrl.Methods, generateCtrlMethod{
+ Name: gstr.Split(line, "(")[0],
+ Definition: line,
+ })
+ }
+ if len(ctrl.Methods) > 0 {
+ controllers = append(controllers, ctrl)
+ }
+ return match[0]
+ },
+ )
+ return controllers, err
+}
+
+func (c CGenPb) doGenerateControllers(in generateControllerInput, controllers []generateCtrl) (err error) {
+ for _, controller := range controllers {
+ err = c.doGenerateController(in, controller)
+ if err != nil {
+ return err
+ }
+ }
+ err = utils.ReplaceGeneratedContentGFV2(in.OutputCtrlPath)
+ return nil
+}
+
+func (c CGenPb) doGenerateController(in generateControllerInput, controller generateCtrl) (err error) {
+ var (
+ folderPath = gfile.Join(in.OutputCtrlPath, controller.Package)
+ filePath = gfile.Join(folderPath, controller.Package+".go")
+ isDirty bool
+ )
+ if !gfile.Exists(folderPath) {
+ if err = gfile.Mkdir(folderPath); err != nil {
+ return err
+ }
+ }
+ if !gfile.Exists(filePath) {
+ templateContent := gstr.ReplaceByMap(controllerTemplate, g.MapStrStr{
+ "{Name}": controller.Name,
+ "{Version}": controller.Version,
+ "{Package}": controller.Package,
+ })
+ if err = gfile.PutContents(filePath, templateContent); err != nil {
+ return err
+ }
+ isDirty = true
+ }
+ // Exist controller content.
+ var ctrlContent string
+ files, err := gfile.ScanDirFile(folderPath, "*.go", false)
+ if err != nil {
+ return err
+ }
+ for _, file := range files {
+ if ctrlContent != "" {
+ ctrlContent += "\n"
+ }
+ ctrlContent += gfile.GetContents(file)
+ }
+ // Generate method content.
+ var generatedContent string
+ for _, method := range controller.Methods {
+ if gstr.Contains(ctrlContent, fmt.Sprintf(`%s(`, method.Name)) {
+ continue
+ }
+ if generatedContent != "" {
+ generatedContent += "\n"
+ }
+ generatedContent += gstr.ReplaceByMap(controllerMethodTemplate, g.MapStrStr{
+ "{Definition}": method.Definition,
+ })
+ }
+ if generatedContent != "" {
+ err = gfile.PutContentsAppend(filePath, generatedContent)
+ if err != nil {
+ return err
+ }
+ isDirty = true
+ }
+ if isDirty {
+ utils.GoFmt(filePath)
+ }
+ return nil
+}
diff --git a/server/internal/library/hggen/internal/cmd/genpb/genpb_tag.go b/server/internal/library/hggen/internal/cmd/genpb/genpb_tag.go
new file mode 100644
index 0000000..cd6281b
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genpb/genpb_tag.go
@@ -0,0 +1,113 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genpb
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/gogf/gf/v2/container/gmap"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/text/gregex"
+ "github.com/gogf/gf/v2/text/gstr"
+ "github.com/gogf/gf/v2/util/gconv"
+ "hotgo/internal/library/hggen/internal/utility/utils"
+)
+
+type generateStructTagInput struct {
+ OutputApiPath string
+}
+
+func (c CGenPb) generateStructTag(ctx context.Context, in generateStructTagInput) (err error) {
+ files, err := gfile.ScanDirFile(in.OutputApiPath, "*.pb.go", true)
+ if err != nil {
+ return err
+ }
+ var content string
+ for _, file := range files {
+ content = gfile.GetContents(file)
+ content, err = c.doTagReplacement(ctx, content)
+ if err != nil {
+ return err
+ }
+ if err = gfile.PutContents(file, content); err != nil {
+ return err
+ }
+ utils.GoFmt(file)
+ }
+ return
+}
+
+func (c CGenPb) doTagReplacement(ctx context.Context, content string) (string, error) {
+ content, err := gregex.ReplaceStringFuncMatch(`type (\w+) struct {([\s\S]+?)}`, content, func(match []string) string {
+ var (
+ topCommentMatch []string
+ tailCommentMatch []string
+ lines = gstr.Split(match[2], "\n")
+ lineTagMap = gmap.NewListMap()
+ )
+ for index, line := range lines {
+ line = gstr.Trim(line)
+ if line == "" {
+ continue
+ }
+ // Top comment.
+ topCommentMatch, _ = gregex.MatchString(`^/[/|\*](.+)`, line)
+ if len(topCommentMatch) > 1 {
+ c.tagCommentIntoListMap(gstr.Trim(topCommentMatch[1]), lineTagMap)
+ continue
+ }
+ // Tail comment.
+ tailCommentMatch, _ = gregex.MatchString(".+?`.+?`.+?//(.+)", line)
+ if len(tailCommentMatch) > 1 {
+ c.tagCommentIntoListMap(gstr.Trim(tailCommentMatch[1]), lineTagMap)
+ }
+ // Tag injection.
+ if !lineTagMap.IsEmpty() {
+ tagContent := c.listMapToStructTag(lineTagMap)
+ lineTagMap.Clear()
+ line, _ = gregex.ReplaceString("`(.+)`", fmt.Sprintf("`$1 %s`", tagContent), line)
+ }
+ lines[index] = line
+ }
+ match[2] = gstr.Join(lines, "\n")
+ return fmt.Sprintf("type %s struct {%s}", match[1], match[2])
+ })
+ return content, err
+}
+
+func (c CGenPb) tagCommentIntoListMap(comment string, lineTagMap *gmap.ListMap) {
+ tagCommentMatch, _ := gregex.MatchString(`^(\w+):(.+)`, comment)
+ if len(tagCommentMatch) > 1 {
+ var (
+ tagName = gstr.Trim(tagCommentMatch[1])
+ tagContent = gstr.Trim(tagCommentMatch[2])
+ )
+ lineTagMap.Set(tagName, lineTagMap.GetVar(tagName).String()+tagContent)
+ } else {
+ var (
+ tagName = "dc"
+ tagContent = comment
+ )
+ lineTagMap.Set(tagName, lineTagMap.GetVar(tagName).String()+tagContent)
+ }
+}
+
+func (c CGenPb) listMapToStructTag(lineTagMap *gmap.ListMap) string {
+ var tag string
+ lineTagMap.Iterator(func(key, value interface{}) bool {
+ if tag != "" {
+ tag += " "
+ }
+ tag += fmt.Sprintf(
+ `%s:"%s"`,
+ key, gstr.Replace(gconv.String(value), `"`, `\"`),
+ )
+ return true
+ })
+ return tag
+}
diff --git a/server/internal/library/hggen/internal/cmd/genpbentity/genpbentity.go b/server/internal/library/hggen/internal/cmd/genpbentity/genpbentity.go
new file mode 100644
index 0000000..daf0400
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/genpbentity/genpbentity.go
@@ -0,0 +1,419 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package genpbentity
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "strings"
+
+ "github.com/gogf/gf/v2/database/gdb"
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gctx"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gtime"
+ "github.com/gogf/gf/v2/text/gregex"
+ "github.com/gogf/gf/v2/text/gstr"
+ "github.com/gogf/gf/v2/util/gconv"
+ "github.com/gogf/gf/v2/util/gtag"
+ "github.com/olekukonko/tablewriter"
+ "hotgo/internal/library/hggen/internal/consts"
+ "hotgo/internal/library/hggen/internal/utility/mlog"
+)
+
+type (
+ CGenPbEntity struct{}
+ CGenPbEntityInput struct {
+ g.Meta `name:"pbentity" config:"{CGenPbEntityConfig}" brief:"{CGenPbEntityBrief}" eg:"{CGenPbEntityEg}" ad:"{CGenPbEntityAd}"`
+ Path string `name:"path" short:"p" brief:"{CGenPbEntityBriefPath}" d:"manifest/protobuf/pbentity"`
+ Package string `name:"package" short:"k" brief:"{CGenPbEntityBriefPackage}"`
+ Link string `name:"link" short:"l" brief:"{CGenPbEntityBriefLink}"`
+ Tables string `name:"tables" short:"t" brief:"{CGenPbEntityBriefTables}"`
+ Prefix string `name:"prefix" short:"f" brief:"{CGenPbEntityBriefPrefix}"`
+ RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenPbEntityBriefRemovePrefix}"`
+ NameCase string `name:"nameCase" short:"n" brief:"{CGenPbEntityBriefNameCase}" d:"Camel"`
+ JsonCase string `name:"jsonCase" short:"j" brief:"{CGenPbEntityBriefJsonCase}" d:"CamelLower"`
+ Option string `name:"option" short:"o" brief:"{CGenPbEntityBriefOption}"`
+ }
+ CGenPbEntityOutput struct{}
+
+ CGenPbEntityInternalInput struct {
+ CGenPbEntityInput
+ DB gdb.DB
+ TableName string // TableName specifies the table name of the table.
+ NewTableName string // NewTableName specifies the prefix-stripped name of the table.
+ }
+)
+
+const (
+ defaultPackageSuffix = `api/pbentity`
+ CGenPbEntityConfig = `gfcli.gen.pbentity`
+ CGenPbEntityBrief = `generate entity message files in protobuf3 format`
+ CGenPbEntityEg = `
+gf gen pbentity
+gf gen pbentity -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
+gf gen pbentity -p ./protocol/demos/entity -t user,user_detail,user_login
+gf gen pbentity -r user_ -k github.com/gogf/gf/example/protobuf
+gf gen pbentity -r user_
+`
+
+ CGenPbEntityAd = `
+CONFIGURATION SUPPORT
+ Options are also supported by configuration file.
+ It's suggested using configuration file instead of command line arguments making producing.
+ The configuration node name is "gf.gen.pbentity", which also supports multiple databases, for example(config.yaml):
+ gfcli:
+ gen:
+ - pbentity:
+ link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
+ path: "protocol/demos/entity"
+ tables: "order,products"
+ package: "demos"
+ - pbentity:
+ link: "mysql:root:12345678@tcp(127.0.0.1:3306)/primary"
+ path: "protocol/demos/entity"
+ prefix: "primary_"
+ tables: "user, userDetail"
+ package: "demos"
+ option: |
+ option go_package = "protobuf/demos";
+ option java_package = "protobuf/demos";
+ option php_namespace = "protobuf/demos";
+`
+ CGenPbEntityBriefPath = `directory path for generated files storing`
+ CGenPbEntityBriefPackage = `package path for all entity proto files`
+ CGenPbEntityBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
+ CGenPbEntityBriefTables = `generate models only for given tables, multiple table names separated with ','`
+ CGenPbEntityBriefPrefix = `add specified prefix for all entity names and entity proto files`
+ CGenPbEntityBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
+ CGenPbEntityBriefOption = `extra protobuf options`
+ CGenPbEntityBriefGroup = `
+specifying the configuration group name of database for generated ORM instance,
+it's not necessary and the default value is "default"
+`
+
+ CGenPbEntityBriefNameCase = `
+case for message attribute names, default is "Camel":
+| Case | Example |
+|---------------- |--------------------|
+| Camel | AnyKindOfString |
+| CamelLower | anyKindOfString | default
+| Snake | any_kind_of_string |
+| SnakeScreaming | ANY_KIND_OF_STRING |
+| SnakeFirstUpper | rgb_code_md5 |
+| Kebab | any-kind-of-string |
+| KebabScreaming | ANY-KIND-OF-STRING |
+`
+
+ CGenPbEntityBriefJsonCase = `
+case for message json tag, cases are the same as "nameCase", default "CamelLower".
+set it to "none" to ignore json tag generating.
+`
+)
+
+func init() {
+ gtag.Sets(g.MapStrStr{
+ `CGenPbEntityConfig`: CGenPbEntityConfig,
+ `CGenPbEntityBrief`: CGenPbEntityBrief,
+ `CGenPbEntityEg`: CGenPbEntityEg,
+ `CGenPbEntityAd`: CGenPbEntityAd,
+ `CGenPbEntityBriefPath`: CGenPbEntityBriefPath,
+ `CGenPbEntityBriefPackage`: CGenPbEntityBriefPackage,
+ `CGenPbEntityBriefLink`: CGenPbEntityBriefLink,
+ `CGenPbEntityBriefTables`: CGenPbEntityBriefTables,
+ `CGenPbEntityBriefPrefix`: CGenPbEntityBriefPrefix,
+ `CGenPbEntityBriefRemovePrefix`: CGenPbEntityBriefRemovePrefix,
+ `CGenPbEntityBriefGroup`: CGenPbEntityBriefGroup,
+ `CGenPbEntityBriefNameCase`: CGenPbEntityBriefNameCase,
+ `CGenPbEntityBriefJsonCase`: CGenPbEntityBriefJsonCase,
+ `CGenPbEntityBriefOption`: CGenPbEntityBriefOption,
+ })
+}
+
+func (c CGenPbEntity) PbEntity(ctx context.Context, in CGenPbEntityInput) (out *CGenPbEntityOutput, err error) {
+ var (
+ config = g.Cfg()
+ )
+ if config.Available(ctx) {
+ v := config.MustGet(ctx, CGenPbEntityConfig)
+ if v.IsSlice() {
+ for i := 0; i < len(v.Interfaces()); i++ {
+ doGenPbEntityForArray(ctx, i, in)
+ }
+ } else {
+ doGenPbEntityForArray(ctx, -1, in)
+ }
+ } else {
+ doGenPbEntityForArray(ctx, -1, in)
+ }
+ mlog.Print("done!")
+ return
+}
+
+func doGenPbEntityForArray(ctx context.Context, index int, in CGenPbEntityInput) {
+ var (
+ err error
+ db gdb.DB
+ )
+ if index >= 0 {
+ err = g.Cfg().MustGet(
+ ctx,
+ fmt.Sprintf(`%s.%d`, CGenPbEntityConfig, index),
+ ).Scan(&in)
+ if err != nil {
+ mlog.Fatalf(`invalid configuration of "%s": %+v`, CGenPbEntityConfig, err)
+ }
+ }
+ if in.Package == "" {
+ mlog.Debug(`package parameter is empty, trying calculating the package path using go.mod`)
+ if !gfile.Exists("go.mod") {
+ mlog.Fatal("go.mod does not exist in current working directory")
+ }
+ var (
+ modName string
+ goModContent = gfile.GetContents("go.mod")
+ match, _ = gregex.MatchString(`^module\s+(.+)\s*`, goModContent)
+ )
+ if len(match) > 1 {
+ modName = gstr.Trim(match[1])
+ in.Package = modName + "/" + defaultPackageSuffix
+ } else {
+ mlog.Fatal("module name does not found in go.mod")
+ }
+ }
+ removePrefixArray := gstr.SplitAndTrim(in.RemovePrefix, ",")
+ // It uses user passed database configuration.
+ if in.Link != "" {
+ var (
+ tempGroup = gtime.TimestampNanoStr()
+ match, _ = gregex.MatchString(`([a-z]+):(.+)`, in.Link)
+ )
+ if len(match) == 3 {
+ gdb.AddConfigNode(tempGroup, gdb.ConfigNode{
+ Type: gstr.Trim(match[1]),
+ Link: gstr.Trim(match[2]),
+ })
+ db, _ = gdb.Instance(tempGroup)
+ }
+ } else {
+ db = g.DB()
+ }
+ if db == nil {
+ mlog.Fatal("database initialization failed")
+ }
+
+ tableNames := ([]string)(nil)
+ if in.Tables != "" {
+ tableNames = gstr.SplitAndTrim(in.Tables, ",")
+ } else {
+ tableNames, err = db.Tables(context.TODO())
+ if err != nil {
+ mlog.Fatalf("fetching tables failed: \n %v", err)
+ }
+ }
+
+ for _, tableName := range tableNames {
+ newTableName := tableName
+ for _, v := range removePrefixArray {
+ newTableName = gstr.TrimLeftStr(newTableName, v, 1)
+ }
+ generatePbEntityContentFile(ctx, CGenPbEntityInternalInput{
+ CGenPbEntityInput: in,
+ DB: db,
+ TableName: tableName,
+ NewTableName: newTableName,
+ })
+ }
+}
+
+// generatePbEntityContentFile generates the protobuf files for given table.
+func generatePbEntityContentFile(ctx context.Context, in CGenPbEntityInternalInput) {
+ fieldMap, err := in.DB.TableFields(ctx, in.TableName)
+ if err != nil {
+ mlog.Fatalf("fetching tables fields failed for table '%s':\n%v", in.TableName, err)
+ }
+ // Change the `newTableName` if `Prefix` is given.
+ newTableName := in.Prefix + in.NewTableName
+ var (
+ imports string
+ tableNameCamelCase = gstr.CaseCamel(newTableName)
+ tableNameSnakeCase = gstr.CaseSnake(newTableName)
+ entityMessageDefine = generateEntityMessageDefinition(tableNameCamelCase, fieldMap, in)
+ fileName = gstr.Trim(tableNameSnakeCase, "-_.")
+ path = gfile.Join(in.Path, fileName+".proto")
+ )
+ if gstr.Contains(entityMessageDefine, "google.protobuf.Timestamp") {
+ imports = `import "google/protobuf/timestamp.proto";`
+ }
+ entityContent := gstr.ReplaceByMap(getTplPbEntityContent(""), g.MapStrStr{
+ "{Imports}": imports,
+ "{PackageName}": gfile.Basename(in.Package),
+ "{GoPackage}": in.Package,
+ "{OptionContent}": in.Option,
+ "{EntityMessage}": entityMessageDefine,
+ })
+ if err := gfile.PutContents(path, strings.TrimSpace(entityContent)); err != nil {
+ mlog.Fatalf("writing content to '%s' failed: %v", path, err)
+ } else {
+ mlog.Print("generated:", path)
+ }
+}
+
+// generateEntityMessageDefinition generates and returns the message definition for specified table.
+func generateEntityMessageDefinition(entityName string, fieldMap map[string]*gdb.TableField, in CGenPbEntityInternalInput) string {
+ var (
+ buffer = bytes.NewBuffer(nil)
+ array = make([][]string, len(fieldMap))
+ names = sortFieldKeyForPbEntity(fieldMap)
+ )
+ for index, name := range names {
+ array[index] = generateMessageFieldForPbEntity(index+1, fieldMap[name], in)
+ }
+ tw := tablewriter.NewWriter(buffer)
+ tw.SetBorder(false)
+ tw.SetRowLine(false)
+ tw.SetAutoWrapText(false)
+ tw.SetColumnSeparator("")
+ tw.AppendBulk(array)
+ tw.Render()
+ stContent := buffer.String()
+ // Let's do this hack of table writer for indent!
+ stContent = gstr.Replace(stContent, " #", "")
+ buffer.Reset()
+ buffer.WriteString(fmt.Sprintf("message %s {\n", entityName))
+ buffer.WriteString(stContent)
+ buffer.WriteString("}")
+ return buffer.String()
+}
+
+// generateMessageFieldForPbEntity generates and returns the message definition for specified field.
+func generateMessageFieldForPbEntity(index int, field *gdb.TableField, in CGenPbEntityInternalInput) []string {
+ var (
+ typeName string
+ comment string
+ jsonTagStr string
+ err error
+ ctx = gctx.GetInitCtx()
+ )
+ typeName, err = in.DB.CheckLocalTypeForField(ctx, field.Type, nil)
+ if err != nil {
+ panic(err)
+ }
+ var typeMapping = map[string]string{
+ gdb.LocalTypeString: "string",
+ gdb.LocalTypeDate: "google.protobuf.Timestamp",
+ gdb.LocalTypeDatetime: "google.protobuf.Timestamp",
+ gdb.LocalTypeInt: "int32",
+ gdb.LocalTypeUint: "uint32",
+ gdb.LocalTypeInt64: "int64",
+ gdb.LocalTypeUint64: "uint64",
+ gdb.LocalTypeIntSlice: "repeated int32",
+ gdb.LocalTypeInt64Slice: "repeated int64",
+ gdb.LocalTypeUint64Slice: "repeated uint64",
+ gdb.LocalTypeInt64Bytes: "repeated int64",
+ gdb.LocalTypeUint64Bytes: "repeated uint64",
+ gdb.LocalTypeFloat32: "float",
+ gdb.LocalTypeFloat64: "double",
+ gdb.LocalTypeBytes: "bytes",
+ gdb.LocalTypeBool: "bool",
+ gdb.LocalTypeJson: "string",
+ gdb.LocalTypeJsonb: "string",
+ }
+ typeName = typeMapping[typeName]
+ if typeName == "" {
+ typeName = "string"
+ }
+
+ comment = gstr.ReplaceByArray(field.Comment, g.SliceStr{
+ "\n", " ",
+ "\r", " ",
+ })
+ comment = gstr.Trim(comment)
+ comment = gstr.Replace(comment, `\n`, " ")
+ comment, _ = gregex.ReplaceString(`\s{2,}`, ` `, comment)
+ if jsonTagName := formatCase(field.Name, in.JsonCase); jsonTagName != "" {
+ // beautiful indent.
+ if index < 10 {
+ // 3 spaces
+ jsonTagStr = " " + jsonTagStr
+ } else if index < 100 {
+ // 2 spaces
+ jsonTagStr = " " + jsonTagStr
+ } else {
+ // 1 spaces
+ jsonTagStr = " " + jsonTagStr
+ }
+ }
+ return []string{
+ " #" + typeName,
+ " #" + formatCase(field.Name, in.NameCase),
+ " #= " + gconv.String(index) + jsonTagStr + ";",
+ " #" + fmt.Sprintf(`// %s`, comment),
+ }
+}
+
+func getTplPbEntityContent(tplEntityPath string) string {
+ if tplEntityPath != "" {
+ return gfile.GetContents(tplEntityPath)
+ }
+ return consts.TemplatePbEntityMessageContent
+}
+
+// formatCase call gstr.Case* function to convert the s to specified case.
+func formatCase(str, caseStr string) string {
+ switch gstr.ToLower(caseStr) {
+ case gstr.ToLower("Camel"):
+ return gstr.CaseCamel(str)
+
+ case gstr.ToLower("CamelLower"):
+ return gstr.CaseCamelLower(str)
+
+ case gstr.ToLower("Kebab"):
+ return gstr.CaseKebab(str)
+
+ case gstr.ToLower("KebabScreaming"):
+ return gstr.CaseKebabScreaming(str)
+
+ case gstr.ToLower("Snake"):
+ return gstr.CaseSnake(str)
+
+ case gstr.ToLower("SnakeFirstUpper"):
+ return gstr.CaseSnakeFirstUpper(str)
+
+ case gstr.ToLower("SnakeScreaming"):
+ return gstr.CaseSnakeScreaming(str)
+
+ case "none":
+ return ""
+ }
+ return str
+}
+
+func sortFieldKeyForPbEntity(fieldMap map[string]*gdb.TableField) []string {
+ names := make(map[int]string)
+ for _, field := range fieldMap {
+ names[field.Index] = field.Name
+ }
+ var (
+ result = make([]string, len(names))
+ i = 0
+ j = 0
+ )
+ for {
+ if len(names) == 0 {
+ break
+ }
+ if val, ok := names[i]; ok {
+ result[j] = val
+ j++
+ delete(names, i)
+ }
+ i++
+ }
+ return result
+}
diff --git a/server/internal/library/hggen/internal/cmd/genservice/genservice.go b/server/internal/library/hggen/internal/cmd/genservice/genservice.go
index d771763..b1986b0 100644
--- a/server/internal/library/hggen/internal/cmd/genservice/genservice.go
+++ b/server/internal/library/hggen/internal/cmd/genservice/genservice.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package genservice
import (
@@ -5,10 +11,10 @@ import (
"fmt"
"github.com/gogf/gf/v2/container/garray"
+ "github.com/gogf/gf/v2/container/gmap"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
@@ -44,7 +50,7 @@ destination file name storing automatically generated go files, cases are as fol
`
CGenServiceBriefWatchFile = `used in file watcher, it re-generates all service go files only if given file is under srcFolder`
CGenServiceBriefStPattern = `regular expression matching struct name for generating service. default: ^s([A-Z]\\\\w+)$`
- CGenServiceBriefPackages = `produce go files only for given source packages`
+ CGenServiceBriefPackages = `produce go files only for given source packages(source folders)`
CGenServiceBriefImportPrefix = `custom import prefix to calculate import path for generated importing go file of logic`
CGenServiceBriefClear = `delete all generated go files that are not used any further`
)
@@ -87,21 +93,6 @@ const (
)
func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGenServiceOutput, err error) {
- // File lock to avoid multiple processes.
- var (
- flockFilePath = gfile.Temp("gf.cli.gen.service.lock")
- flockContent = gfile.GetContents(flockFilePath)
- )
- if flockContent != "" {
- if gtime.Timestamp()-gconv.Int64(flockContent) < genServiceFileLockSeconds {
- // If another "gen service" process is running, it just exits.
- mlog.Debug(`another "gen service" process is running, exit`)
- return
- }
- }
- defer gfile.Remove(flockFilePath)
- _ = gfile.PutContents(flockFilePath, gtime.TimestampStr())
-
in.SrcFolder = gstr.TrimRight(in.SrcFolder, `\/`)
in.SrcFolder = gstr.Replace(in.SrcFolder, "\\", "/")
in.WatchFile = gstr.TrimRight(in.WatchFile, `\/`)
@@ -109,6 +100,21 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
// Watch file handling.
if in.WatchFile != "" {
+ // File lock to avoid multiple processes.
+ var (
+ flockFilePath = gfile.Temp("gf.cli.gen.service.lock")
+ flockContent = gfile.GetContents(flockFilePath)
+ )
+ if flockContent != "" {
+ if gtime.Timestamp()-gconv.Int64(flockContent) < genServiceFileLockSeconds {
+ // If another "gen service" process is running, it just exits.
+ mlog.Debug(`another "gen service" process is running, exit`)
+ return
+ }
+ }
+ defer gfile.Remove(flockFilePath)
+ _ = gfile.PutContents(flockFilePath, gtime.TimestampStr())
+
// It works only if given WatchFile is in SrcFolder.
var (
watchFileDir = gfile.Dir(in.WatchFile)
@@ -125,13 +131,10 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
mlog.Fatalf(`%+v`, err)
}
mlog.Debug("Chdir:", newWorkingDir)
- _ = gfile.Remove(flockFilePath)
- var command = fmt.Sprintf(
- `%s gen service -packages=%s`,
- gfile.SelfName(), gfile.Basename(watchFileDir),
- )
- err = gproc.ShellRun(ctx, command)
- return
+
+ in.WatchFile = ""
+ in.Packages = []string{gfile.Basename(watchFileDir)}
+ return c.Service(ctx, in)
}
if !gfile.Exists(in.SrcFolder) {
@@ -139,16 +142,7 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
}
if in.ImportPrefix == "" {
- if !gfile.Exists("go.mod") {
- mlog.Fatal("ImportPrefix is empty and go.mod does not exist in current working directory")
- }
- var (
- goModContent = gfile.GetContents("go.mod")
- match, _ = gregex.MatchString(`^module\s+(.+)\s*`, goModContent)
- )
- if len(match) > 1 {
- in.ImportPrefix = fmt.Sprintf(`%s/%s`, gstr.Trim(match[1]), gstr.Replace(in.SrcFolder, `\`, `/`))
- }
+ in.ImportPrefix = utils.GetImportPath(in.SrcFolder)
}
var (
@@ -176,30 +170,118 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
if len(files) == 0 {
continue
}
+ // Parse single logic package folder.
var (
// StructName => FunctionDefinitions
- srcPkgInterfaceMap = make(map[string]*garray.StrArray)
- srcImportedPackages = garray.NewSortedStrArray().SetUnique(true)
- srcPackageName = gfile.Basename(srcFolderPath)
- ok bool
- dstFilePath = gfile.Join(in.DstFolder,
+ srcPkgInterfaceMap = make(map[string]*garray.StrArray)
+ srcImportedPackages = garray.NewSortedStrArray().SetUnique(true)
+ importAliasToPathMap = gmap.NewStrStrMap() // for conflict imports check. alias => import path(with `"`)
+ importPathToAliasMap = gmap.NewStrStrMap() // for conflict imports check. import path(with `"`) => alias
+ srcPackageName = gfile.Basename(srcFolderPath)
+ ok bool
+ dstFilePath = gfile.Join(in.DstFolder,
c.getDstFileNameCase(srcPackageName, in.DstFileNameCase)+".go",
)
+ srcCodeCommentedMap = make(map[string]string)
)
generatedDstFilePathSet.Add(dstFilePath)
for _, file := range files {
+ var packageItems []packageItem
fileContent = gfile.GetContents(file)
- // Calculate imported packages of source go files.
- err = c.calculateImportedPackages(fileContent, srcImportedPackages)
+ // Calculate code comments in source Go files.
+ err = c.calculateCodeCommented(in, fileContent, srcCodeCommentedMap)
if err != nil {
return nil, err
}
+ // remove all comments.
+ fileContent, err = gregex.ReplaceString(`/[/|\*](.*)`, "", fileContent)
+ if err != nil {
+ return nil, err
+ }
+
+ // Calculate imported packages of source go files.
+ packageItems, err = c.calculateImportedPackages(fileContent)
+ if err != nil {
+ return nil, err
+ }
+ // try finding the conflicts imports between files.
+ for _, item := range packageItems {
+ var alias = item.Alias
+ if alias == "" {
+ alias = gfile.Basename(gstr.Trim(item.Path, `"`))
+ }
+
+ // ignore unused import paths, which do not exist in function definitions.
+ if !gregex.IsMatchString(fmt.Sprintf(`func .+?([^\w])%s(\.\w+).+?{`, alias), fileContent) {
+ mlog.Debugf(`ignore unused package: %s`, item.RawImport)
+ continue
+ }
+
+ // find the exist alias with the same import path.
+ var existAlias = importPathToAliasMap.Get(item.Path)
+ if existAlias != "" {
+ fileContent, err = gregex.ReplaceStringFuncMatch(
+ fmt.Sprintf(`([^\w])%s(\.\w+)`, alias), fileContent,
+ func(match []string) string {
+ return match[1] + existAlias + match[2]
+ },
+ )
+ if err != nil {
+ return nil, err
+ }
+ continue
+ }
+
+ // resolve alias conflicts.
+ var importPath = importAliasToPathMap.Get(alias)
+ if importPath == "" {
+ importAliasToPathMap.Set(alias, item.Path)
+ importPathToAliasMap.Set(item.Path, alias)
+ srcImportedPackages.Add(item.RawImport)
+ continue
+ }
+ if importPath != item.Path {
+ // update the conflicted alias for import path with suffix.
+ // eg:
+ // v1 -> v10
+ // v11 -> v110
+ for aliasIndex := 0; ; aliasIndex++ {
+ item.Alias = fmt.Sprintf(`%s%d`, alias, aliasIndex)
+ var existPathForAlias = importAliasToPathMap.Get(item.Alias)
+ if existPathForAlias != "" {
+ if existPathForAlias == item.Path {
+ break
+ }
+ continue
+ }
+ break
+ }
+ importPathToAliasMap.Set(item.Path, item.Alias)
+ importAliasToPathMap.Set(item.Alias, item.Path)
+ // reformat the import path with alias.
+ item.RawImport = fmt.Sprintf(`%s %s`, item.Alias, item.Path)
+
+ // update the file content with new alias import.
+ fileContent, err = gregex.ReplaceStringFuncMatch(
+ fmt.Sprintf(`([^\w])%s(\.\w+)`, alias), fileContent,
+ func(match []string) string {
+ return match[1] + item.Alias + match[2]
+ },
+ )
+ if err != nil {
+ return nil, err
+ }
+ srcImportedPackages.Add(item.RawImport)
+ }
+ }
+
// Calculate functions and interfaces for service generating.
- err = c.calculateInterfaceFunctions(in, fileContent, srcPkgInterfaceMap, dstPackageName)
+ err = c.calculateInterfaceFunctions(in, fileContent, srcPkgInterfaceMap)
if err != nil {
return nil, err
}
}
+
initImportSrcPackages = append(
initImportSrcPackages,
fmt.Sprintf(`%s/%s`, in.ImportPrefix, srcPackageName),
@@ -212,7 +294,7 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
)
continue
}
- // Generating service go file for logic.
+ // Generating service go file for single logic package.
if ok, err = c.generateServiceFile(generateServiceFilesInput{
CGenServiceInput: in,
SrcStructFunctions: srcPkgInterfaceMap,
@@ -220,6 +302,7 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
SrcPackageName: srcPackageName,
DstPackageName: dstPackageName,
DstFilePath: dstFilePath,
+ SrcCodeCommentedMap: srcCodeCommentedMap,
}); err != nil {
return
}
@@ -254,24 +337,71 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
}
// Replace v1 to v2 for GoFrame.
- if err = c.replaceGeneratedServiceContentGFV2(in); err != nil {
+ if err = utils.ReplaceGeneratedContentGFV2(in.DstFolder); err != nil {
return nil, err
}
mlog.Printf(`gofmt go files in "%s"`, in.DstFolder)
utils.GoFmt(in.DstFolder)
}
+ // auto update main.go.
+ if err = c.checkAndUpdateMain(in.SrcFolder); err != nil {
+ return nil, err
+ }
+
mlog.Print(`done!`)
return
}
-func (c CGenService) replaceGeneratedServiceContentGFV2(in CGenServiceInput) (err error) {
- return gfile.ReplaceDirFunc(func(path, content string) string {
- if gstr.Contains(content, `"github.com/gogf/gf`) && !gstr.Contains(content, `"github.com/gogf/gf/v2`) {
- content = gstr.Replace(content, `"github.com/gogf/gf"`, `"github.com/gogf/gf/v2"`)
- content = gstr.Replace(content, `"github.com/gogf/gf/`, `"github.com/gogf/gf/v2/`)
- return content
+func (c CGenService) checkAndUpdateMain(srcFolder string) (err error) {
+ var (
+ logicPackageName = gstr.ToLower(gfile.Basename(srcFolder))
+ logicFilePath = gfile.Join(srcFolder, logicPackageName+".go")
+ importPath = utils.GetImportPath(logicFilePath)
+ importStr = fmt.Sprintf(`_ "%s"`, importPath)
+ mainFilePath = gfile.Join(gfile.Dir(gfile.Dir(gfile.Dir(logicFilePath))), "main.go")
+ mainFileContent = gfile.GetContents(mainFilePath)
+ )
+ // No main content found.
+ if mainFileContent == "" {
+ return nil
+ }
+ if gstr.Contains(mainFileContent, importStr) {
+ return nil
+ }
+ match, err := gregex.MatchString(`import \(([\s\S]+?)\)`, mainFileContent)
+ if err != nil {
+ return err
+ }
+ // No match.
+ if len(match) < 2 {
+ return nil
+ }
+ lines := garray.NewStrArrayFrom(gstr.Split(match[1], "\n"))
+ for i, line := range lines.Slice() {
+ line = gstr.Trim(line)
+ if len(line) == 0 {
+ continue
}
- return content
- }, in.DstFolder, "*.go", false)
+ if line[0] == '_' {
+ continue
+ }
+ // Insert the logic import into imports.
+ if err = lines.InsertBefore(i, fmt.Sprintf("\t%s\n\n", importStr)); err != nil {
+ return err
+ }
+ break
+ }
+ mainFileContent, err = gregex.ReplaceString(
+ `import \(([\s\S]+?)\)`,
+ fmt.Sprintf(`import (%s)`, lines.Join("\n")),
+ mainFileContent,
+ )
+ if err != nil {
+ return err
+ }
+ mlog.Print(`update main.go`)
+ err = gfile.PutContents(mainFilePath, mainFileContent)
+ utils.GoFmt(mainFilePath)
+ return
}
diff --git a/server/internal/library/hggen/internal/cmd/genservice/genservice_calculate.go b/server/internal/library/hggen/internal/cmd/genservice/genservice_calculate.go
index b3e8f4e..68fe746 100644
--- a/server/internal/library/hggen/internal/cmd/genservice/genservice_calculate.go
+++ b/server/internal/library/hggen/internal/cmd/genservice/genservice_calculate.go
@@ -1,6 +1,13 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package genservice
import (
+ "fmt"
"go/parser"
"go/token"
@@ -9,29 +16,90 @@ import (
"github.com/gogf/gf/v2/text/gstr"
)
-func (c CGenService) calculateImportedPackages(fileContent string, srcImportedPackages *garray.SortedStrArray) (err error) {
+type packageItem struct {
+ Alias string
+ Path string
+ RawImport string
+}
+
+func (c CGenService) calculateImportedPackages(fileContent string) (packages []packageItem, err error) {
f, err := parser.ParseFile(token.NewFileSet(), "", fileContent, parser.ImportsOnly)
if err != nil {
- return err
+ return nil, err
}
+ packages = make([]packageItem, 0)
for _, s := range f.Imports {
if s.Path != nil {
if s.Name != nil {
// If it has alias, and it is not `_`.
if pkgAlias := s.Name.String(); pkgAlias != "_" {
- srcImportedPackages.Add(pkgAlias + " " + s.Path.Value)
+ packages = append(packages, packageItem{
+ Alias: pkgAlias,
+ Path: s.Path.Value,
+ RawImport: pkgAlias + " " + s.Path.Value,
+ })
}
} else {
// no alias
- srcImportedPackages.Add(s.Path.Value)
+ packages = append(packages, packageItem{
+ Alias: "",
+ Path: s.Path.Value,
+ RawImport: s.Path.Value,
+ })
}
}
}
+ return packages, nil
+}
+
+func (c CGenService) calculateCodeCommented(in CGenServiceInput, fileContent string, srcCodeCommentedMap map[string]string) error {
+ matches, err := gregex.MatchAllString(`((((//.*)|(/\*[\s\S]*?\*/))\s)+)func \((.+?)\) ([\s\S]+?) {`, fileContent)
+ if err != nil {
+ return err
+ }
+ for _, match := range matches {
+ var (
+ structName string
+ structMatch []string
+ funcReceiver = gstr.Trim(match[1+5])
+ receiverArray = gstr.SplitAndTrim(funcReceiver, " ")
+ functionHead = gstr.Trim(gstr.Replace(match[2+5], "\n", ""))
+ commentedInfo = ""
+ )
+ if len(receiverArray) > 1 {
+ structName = receiverArray[1]
+ } else if len(receiverArray) == 1 {
+ structName = receiverArray[0]
+ }
+ structName = gstr.Trim(structName, "*")
+
+ // Case of:
+ // Xxx(\n ctx context.Context, req *v1.XxxReq,\n) -> Xxx(ctx context.Context, req *v1.XxxReq)
+ functionHead = gstr.Replace(functionHead, `,)`, `)`)
+ functionHead, _ = gregex.ReplaceString(`\(\s+`, `(`, functionHead)
+ functionHead, _ = gregex.ReplaceString(`\s{2,}`, ` `, functionHead)
+ if !gstr.IsLetterUpper(functionHead[0]) {
+ continue
+ }
+ // Match and pick the struct name from receiver.
+ if structMatch, err = gregex.MatchString(in.StPattern, structName); err != nil {
+ return err
+ }
+ if len(structMatch) < 1 {
+ continue
+ }
+ structName = gstr.CaseCamel(structMatch[1])
+
+ commentedInfo = match[1]
+ if len(commentedInfo) > 0 {
+ srcCodeCommentedMap[fmt.Sprintf("%s-%s", structName, functionHead)] = commentedInfo
+ }
+ }
return nil
}
func (c CGenService) calculateInterfaceFunctions(
- in CGenServiceInput, fileContent string, srcPkgInterfaceMap map[string]*garray.StrArray, dstPackageName string,
+ in CGenServiceInput, fileContent string, srcPkgInterfaceMap map[string]*garray.StrArray,
) (err error) {
var (
ok bool
@@ -53,7 +121,7 @@ func (c CGenService) calculateInterfaceFunctions(
)
if len(receiverArray) > 1 {
structName = receiverArray[1]
- } else {
+ } else if len(receiverArray) == 1 {
structName = receiverArray[0]
}
structName = gstr.Trim(structName, "*")
diff --git a/server/internal/library/hggen/internal/cmd/genservice/genservice_generate.go b/server/internal/library/hggen/internal/cmd/genservice/genservice_generate.go
index 73be120..7b9c834 100644
--- a/server/internal/library/hggen/internal/cmd/genservice/genservice_generate.go
+++ b/server/internal/library/hggen/internal/cmd/genservice/genservice_generate.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package genservice
import (
@@ -21,6 +27,7 @@ type generateServiceFilesInput struct {
SrcImportedPackages []string
SrcPackageName string
DstPackageName string
+ SrcCodeCommentedMap map[string]string
}
func (c CGenService) generateServiceFile(in generateServiceFilesInput) (ok bool, err error) {
@@ -41,6 +48,13 @@ func (c CGenService) generateServiceFile(in generateServiceFilesInput) (ok bool,
generatedContent += "\n"
for structName, funcArray := range in.SrcStructFunctions {
allFuncArray.Append(funcArray.Slice()...)
+ // Add comments to a method.
+ for index, funcName := range funcArray.Slice() {
+ if commentedInfo, exist := in.SrcCodeCommentedMap[fmt.Sprintf("%s-%s", structName, funcName)]; exist {
+ funcName = commentedInfo + funcName
+ _ = funcArray.Set(index, funcName)
+ }
+ }
generatedContent += gstr.Trim(gstr.ReplaceByMap(consts.TemplateGenServiceContentInterface, g.MapStrStr{
"{InterfaceName}": "I" + structName,
"{FuncDefinition}": funcArray.Join("\n\t"),
@@ -56,7 +70,7 @@ func (c CGenService) generateServiceFile(in generateServiceFilesInput) (ok bool,
generatingInterfaceCheck string
)
// Variable definitions.
- for structName, _ := range in.SrcStructFunctions {
+ for structName := range in.SrcStructFunctions {
generatingInterfaceCheck = fmt.Sprintf(`[^\w\d]+%s.I%s[^\w\d]`, in.DstPackageName, structName)
if gregex.IsMatchString(generatingInterfaceCheck, generatedContent) {
continue
@@ -75,7 +89,7 @@ func (c CGenService) generateServiceFile(in generateServiceFilesInput) (ok bool,
generatedContent += "\n"
}
// Variable register function definitions.
- for structName, _ := range in.SrcStructFunctions {
+ for structName := range in.SrcStructFunctions {
generatingInterfaceCheck = fmt.Sprintf(`[^\w\d]+%s.I%s[^\w\d]`, in.DstPackageName, structName)
if gregex.IsMatchString(generatingInterfaceCheck, generatedContent) {
continue
@@ -114,6 +128,7 @@ func (c CGenService) generateServiceFile(in generateServiceFilesInput) (ok bool,
// isToGenerateServiceGoFile checks and returns whether the service content dirty.
func (c CGenService) isToGenerateServiceGoFile(dstPackageName, filePath string, funcArray *garray.StrArray) bool {
var (
+ err error
fileContent = gfile.GetContents(filePath)
generatedFuncArray = garray.NewSortedStrArrayFrom(funcArray.Slice())
contentFuncArray = garray.NewSortedStrArray()
@@ -121,6 +136,12 @@ func (c CGenService) isToGenerateServiceGoFile(dstPackageName, filePath string,
if fileContent == "" {
return true
}
+ // remove all comments.
+ fileContent, err = gregex.ReplaceString(`/[/|\*](.*)`, "", fileContent)
+ if err != nil {
+ panic(err)
+ return false
+ }
matches, _ := gregex.MatchAllString(`\s+interface\s+{([\s\S]+?)}`, fileContent)
for _, match := range matches {
contentFuncArray.Append(gstr.SplitAndTrim(match[1], "\n")...)
@@ -145,29 +166,30 @@ func (c CGenService) isToGenerateServiceGoFile(dstPackageName, filePath string,
return false
}
+// generateInitializationFile generates `logic.go`.
func (c CGenService) generateInitializationFile(in CGenServiceInput, importSrcPackages []string) (err error) {
var (
- srcPackageName = gstr.ToLower(gfile.Basename(in.SrcFolder))
- srcFilePath = gfile.Join(in.SrcFolder, srcPackageName+".go")
- srcImports string
+ logicPackageName = gstr.ToLower(gfile.Basename(in.SrcFolder))
+ logicFilePath = gfile.Join(in.SrcFolder, logicPackageName+".go")
+ logicImports string
generatedContent string
)
- if !utils.IsFileDoNotEdit(srcFilePath) {
- mlog.Debugf(`ignore file as it is manually maintained: %s`, srcFilePath)
+ if !utils.IsFileDoNotEdit(logicFilePath) {
+ mlog.Debugf(`ignore file as it is manually maintained: %s`, logicFilePath)
return nil
}
for _, importSrcPackage := range importSrcPackages {
- srcImports += fmt.Sprintf(`%s_ "%s"%s`, "\t", importSrcPackage, "\n")
+ logicImports += fmt.Sprintf(`%s_ "%s"%s`, "\t", importSrcPackage, "\n")
}
generatedContent = gstr.ReplaceByMap(consts.TemplateGenServiceLogicContent, g.MapStrStr{
- "{PackageName}": srcPackageName,
- "{Imports}": srcImports,
+ "{PackageName}": logicPackageName,
+ "{Imports}": logicImports,
})
- mlog.Printf(`generating init go file: %s`, srcFilePath)
- if err = gfile.PutContents(srcFilePath, generatedContent); err != nil {
+ mlog.Printf(`generating init go file: %s`, logicFilePath)
+ if err = gfile.PutContents(logicFilePath, generatedContent); err != nil {
return err
}
- utils.GoFmt(srcFilePath)
+ utils.GoFmt(logicFilePath)
return nil
}
diff --git a/server/internal/library/hggen/internal/cmd/testdata/fix25_content.go.txt b/server/internal/library/hggen/internal/cmd/testdata/fix25_content.go.txt
new file mode 100644
index 0000000..0c2db7d
--- /dev/null
+++ b/server/internal/library/hggen/internal/cmd/testdata/fix25_content.go.txt
@@ -0,0 +1,30 @@
+package testdata
+
+import (
+ "fmt"
+ "testing"
+ "time"
+
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/net/ghttp"
+ "github.com/gogf/gf/v2/test/gtest"
+ "github.com/gogf/gf/v2/util/guid"
+)
+
+func Test_Router_Hook_Multi(t *testing.T) {
+ s := g.Server(guid.S())
+ s.BindHandler("/multi-hook", func(r *ghttp.Request) {
+ r.Response.Write("show")
+ })
+
+ s.BindHookHandlerByMap("/multi-hook", map[string]ghttp.HandlerFunc{
+ ghttp.HookBeforeServe: func(r *ghttp.Request) {
+ r.Response.Write("1")
+ },
+ })
+ s.BindHookHandlerByMap("/multi-hook/{id}", map[string]ghttp.HandlerFunc{
+ ghttp.HookBeforeServe: func(r *ghttp.Request) {
+ r.Response.Write("2")
+ },
+ })
+}
\ No newline at end of file
diff --git a/server/internal/library/hggen/internal/consts/consts.go b/server/internal/library/hggen/internal/consts/consts.go
index ab72444..cece25d 100644
--- a/server/internal/library/hggen/internal/consts/consts.go
+++ b/server/internal/library/hggen/internal/consts/consts.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package consts
const (
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template.go b/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template.go
new file mode 100644
index 0000000..de01e04
--- /dev/null
+++ b/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template.go
@@ -0,0 +1,65 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package consts
+
+const TemplateGenCtrlControllerEmpty = `
+package {Module}
+
+`
+
+const TemplateGenCtrlControllerNewEmpty = `
+// =================================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package {Module}
+
+import (
+ {ImportPath}
+)
+
+`
+
+const TemplateGenCtrlControllerNewFunc = `
+type {CtrlName} struct{}
+
+func {NewFuncName}() {InterfaceName} {
+ return &{CtrlName}{}
+}
+
+`
+
+const TemplateGenCtrlControllerMethodFunc = `
+package {Module}
+
+import (
+ "context"
+
+ "github.com/gogf/gf/v2/errors/gcode"
+ "github.com/gogf/gf/v2/errors/gerror"
+
+ "{ImportPath}"
+)
+
+func (c *{CtrlName}) {MethodName}(ctx context.Context, req *{Version}.{MethodName}Req) (res *{Version}.{MethodName}Res, err error) {
+ return nil, gerror.NewCode(gcode.CodeNotImplemented)
+}
+`
+
+const TemplateGenCtrlApiInterface = `
+// =================================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package {Module}
+
+import (
+{ImportPaths}
+)
+
+{Interfaces}
+`
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template_sdk.go b/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template_sdk.go
new file mode 100644
index 0000000..7ab1d80
--- /dev/null
+++ b/server/internal/library/hggen/internal/consts/consts_gen_ctrl_template_sdk.go
@@ -0,0 +1,94 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package consts
+
+const TemplateGenCtrlSdkPkgNew = `
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package {PkgName}
+
+import (
+ "fmt"
+
+ "github.com/gogf/gf/contrib/sdk/httpclient/v2"
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/text/gstr"
+)
+
+type implementer struct {
+ config httpclient.Config
+}
+
+func New(config httpclient.Config) iClient {
+ if !gstr.HasPrefix(config.URL, "http") {
+ config.URL = fmt.Sprintf("http://%s", config.URL)
+ }
+ if config.Logger == nil {
+ config.Logger = g.Log()
+ }
+ return &implementer{
+ config: config,
+ }
+}
+
+`
+
+const TemplateGenCtrlSdkIClient = `
+// =================================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package {PkgName}
+
+import (
+)
+
+type iClient interface {
+}
+`
+
+const TemplateGenCtrlSdkImplementer = `
+// =================================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package {PkgName}
+
+import (
+ "context"
+
+ "github.com/gogf/gf/contrib/sdk/httpclient/v2"
+ "github.com/gogf/gf/v2/text/gstr"
+
+{ImportPaths}
+)
+
+type implementer{ImplementerName} struct {
+ *httpclient.Client
+}
+
+`
+
+const TemplateGenCtrlSdkImplementerNew = `
+func (i *implementer) {ImplementerName}() {Module}.I{ImplementerName} {
+ var (
+ client = httpclient.New(i.config)
+ prefix = gstr.TrimRight(i.config.URL, "/") + "{VersionPrefix}"
+ )
+ client.Client = client.Prefix(prefix)
+ return &implementer{ImplementerName}{client}
+}
+`
+
+const TemplateGenCtrlSdkImplementerFunc = `
+func (i *implementer{ImplementerName}) {MethodName}(ctx context.Context, req *{Version}.{MethodName}Req) (res *{Version}.{MethodName}Res, err error) {
+ err = i.Request(ctx, req, &res)
+ return
+}
+`
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_dao.go b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_dao.go
index e2d3ec3..bcf2373 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_dao.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_dao.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package consts
const TemplateGenDaoIndexContent = `
@@ -33,7 +39,7 @@ var (
const TemplateGenDaoInternalContent = `
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
// ==========================================================================
package internal
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_do.go b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_do.go
index 4847adc..11914b0 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_do.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_do.go
@@ -1,8 +1,14 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package consts
const TemplateGenDaoDoContent = `
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
// =================================================================================
package do
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_entity.go b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_entity.go
index 49a3311..44af06a 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_dao_template_entity.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_dao_template_entity.go
@@ -1,8 +1,14 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package consts
const TemplateGenDaoEntityContent = `
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
// =================================================================================
package entity
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_enums_template.go b/server/internal/library/hggen/internal/consts/consts_gen_enums_template.go
index e97f40d..9477787 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_enums_template.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_enums_template.go
@@ -8,7 +8,7 @@ package consts
const TemplateGenEnums = `
// ================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ================================================================================
package {PackageName}
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_pbentity_template.go b/server/internal/library/hggen/internal/consts/consts_gen_pbentity_template.go
index bbb184a..73b693e 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_pbentity_template.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_pbentity_template.go
@@ -1,17 +1,23 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package consts
const TemplatePbEntityMessageContent = `
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
syntax = "proto3";
package {PackageName};
-import "github.com/gogo/protobuf/gogoproto/gogo.proto";
-
+option go_package = "{GoPackage}";
{OptionContent}
+{Imports}
{EntityMessage}
`
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_service_template.go b/server/internal/library/hggen/internal/consts/consts_gen_service_template.go
index 1ab216a..f5c4f5a 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_service_template.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_service_template.go
@@ -1,8 +1,14 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package consts
const TemplateGenServiceContentHead = `
// ================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
diff --git a/server/internal/library/hggen/internal/consts/consts_gen_service_template_logic.go b/server/internal/library/hggen/internal/consts/consts_gen_service_template_logic.go
index 1479834..eb43a03 100644
--- a/server/internal/library/hggen/internal/consts/consts_gen_service_template_logic.go
+++ b/server/internal/library/hggen/internal/consts/consts_gen_service_template_logic.go
@@ -1,8 +1,14 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package consts
const TemplateGenServiceLogicContent = `
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package {PackageName}
diff --git a/server/internal/library/hggen/internal/packed/packed.go b/server/internal/library/hggen/internal/packed/packed.go
index e20ab1e..2c43d27 100644
--- a/server/internal/library/hggen/internal/packed/packed.go
+++ b/server/internal/library/hggen/internal/packed/packed.go
@@ -1 +1,7 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package packed
diff --git a/server/internal/library/hggen/internal/packed/template-mono.go b/server/internal/library/hggen/internal/packed/template-mono.go
index 62fabb3..d08011d 100644
--- a/server/internal/library/hggen/internal/packed/template-mono.go
+++ b/server/internal/library/hggen/internal/packed/template-mono.go
@@ -3,7 +3,7 @@ package packed
import "github.com/gogf/gf/v2/os/gres"
func init() {
- if err := gres.Add("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"); err != nil {
+ if err := gres.Add("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"); err != nil {
panic("add binary content to resource manager failed: " + err.Error())
}
}
diff --git a/server/internal/library/hggen/internal/packed/template-single.go b/server/internal/library/hggen/internal/packed/template-single.go
index b42b9c5..ee20193 100644
--- a/server/internal/library/hggen/internal/packed/template-single.go
+++ b/server/internal/library/hggen/internal/packed/template-single.go
@@ -3,7 +3,7 @@ package packed
import "github.com/gogf/gf/v2/os/gres"
func init() {
- if err := gres.Add("H4sIAAAAAAAC/7ScBVhVy9rHF53S3SBdWxAp6ZCWklK6uzsVQboRkJQuaRGQlu6SBlEQpLvze8797vG6PYqC9/I85+wH3f7e//vOmjWz5j+z5KSgoLEAeAAeQNR1VgK++SEBEAB7Awtrcx17AyY7E0sjcwMQs5GJvY69va2JroO9gZ3SAxgA4rm2l96gQntHtxSoh5F5oEeiWwokIy1b7nAABw0AFxdyUnDwQ3Is3EQAAOAAAPDzgAQ/CWhiZGlla/A1GFtPo3zzLeR7n060OkkyqBe1kbRL3xSLYkjpdaR6PLvl5j4zP2C2JO/RhbIsM1lMh8WPsm0yo4Chr0h4LpNvjozY8X7AW1AFK/9dpf6DhGDd7EftGU2doVlLDNyifhshW4ONtAcYYXBDbTs7L9hhojE6ODmIi5/XreMd77VZiXMleUH9nVXEQjeLLwAAJZdmhfeDrGR0zAwMTcz/k1Oi0ozV5BtML/aLQCgzOBwCiRkcrdVGwVJXmwVosxUyCVLvt/B4W5ToWeIyGYmuJucHnygnbaf0oRbggtpOpor6iDvyx1cXLG1tYABr5LPULnkzWlL9Br4w/iQNrVDZPgLs2LjAh2691EaxpEYVThlZHmGiub5t/XRRJp/NWe+eza0uO/C6QeG2uqQ6nGZGv7vpjMQnRha9Y328BVlTzq07MH+0urMGj1Ggmjbsv8fHuYs2i96ttkGevodcimW7IcUROCd9VFMXhvGo+UXPIKfUHOIdRD9my9q2QT48C9/gsl1LRUtDiB6MrLJxh82dhcPlXZ7HT6ECX3z2fb65fxfGwimNU0qwfE+g8uGGMky4t3xJNhc1Eto9Sx2QMl5BublRrYpNjFClD6Y/FbOeotmNDVmUD41hpC8VDo+xnS9UUFIFP17Mba5NopeYavcCrrzStkjupl64MOwItHCtxzL3aVEbXeRdaBkSyCQNWNHKKwgfb3bG0wY6R0kUoSFlvCKkUxKTyVRkU5UXzsZRyBwQNGWICzba0sdJwS86zWNQQ+zKKO4z2/BoV2jvZ5tQ4dXUK3+A4FinXt04MqPibim3euNUmYFJEJuiSThc1bTaNDNLlkHemKAzo5CejQRnj5dac4gnpzPeex9+NFxuolNRGTUtUj/DgoINi6Lj+bhMRLtBz4WmCiFIZvO+ueKyPqLteypmi9KGvDvLQmwUZucHeIuoNnRsU9PB2dVtPIokr3vI3OF04iby0M7jUDHwb9ii6Igb7VROk2w1rr3Ea288+jj0MR4OQjG3kV/H+bD7xc67UZR3xa+VvB/SQm3IvhkigAbpC+WTReZt5z9OjaD3gMhQWOT/EJwt61es8UrGKUnTs4pvY5MS3bKMjDLkXXxNsc8miTOtANZ27IXwogCDohcNzLQakZDVS/6pql5v+YsIb77yuXM7UHzuS0VF+CKM1D3Ezol5NhwzVd/M6RVVEbQRJhOety+AznNOxsnwqItbeXfFCksM14x2E7+MGsdUilh0kWm7KVaH55GX8E/VkAtK17QETbg8yqnf9GeWPkKWg08fXCCwtF0sLtHQzWzpbCEM/PKqYvidh/BeBz90kH/ASI4BIBCdqSkYd56PzXObwVfWFj73YJLmlqqdmHvr2adeTDw0uFObXo2AjsQwki+TuEXPEXeFEEEPJYLc3hdqdOHc/pJw8z3PMys45rgdmmMb0+MZiL/7eJrDDeLnUACQBndZH8f/QR9XEBUUkRFllhH52smjwxtDCViQn23w+GYmIx1EuKquOaIrMKBlOvk1Yw5KzEbM5b6U1TLQBgSVTGQDdC9mjL5gMh5pSFOMyS+ny3s74Ryil4a9zkw2KgvZBJUizsiIWfhDFyVGdhSy3TpBjpMW09ZrgFWuyglAV/1otEEvhb8rIFclWpQ3asUgt8BZv5CkY64t8SKjlUf4DraxGlBveMP1YU3tK1wrM2g9piCkcVn7rqobnmjpT3bwfJQ5IUiC19AehoZ+XqCnrH9KZa6tl4GmrU+6+l4l1TP+pj6VSUhtAq2+QUPAFjRqh7P3dNd215ZzM+wbYVh787sYY6jk3K+8txyXaguednzuVxho4XqMOubCH910MU5dvaK4Vlc2PAh/+HhEnvRoN2f1WVriO1LXiRxu5hc7EbRmTE5NyZRRCvj1KdA1m/0XboEsATv1X9skFwvTVAQCABIg/9MmwD/aBPMHbaJjbfK1Nf4iffv9n5NwfkwCObL8EvbPS4X0pzCQsYG5uRWzkdVXqnlPyf2nLMjQH6s8EbswGUO0uzHtdXT08o9sEv3jfJpzH5J/IJanzgilmZ4edXEzwubhBbBWLDg/NIa+dtYsOilQ68+iM0bMbguHTYCmqoTblMLlES9YU+OzOVZNmMNdtb+g7HVeXeVSaK+/IWSUFIHi1dhs5xaUMetj92KrUsTVBEkRf2jrreC6b+jmGWo8BxkDdYR6L0npI6ro24+KMEyOaUldeY8Q/m4WjIdE5nkAAHy5NP8fFdPIitnCSv9r2vpdkzcekyHD9F/cb4SMEbAnI52XhFSOYK2H4mzIdVVF95uSnXQeXU4Vr5Oq7ZowcN3xpRCRw+VkFJEh6VoDhZ/6W4qg8Azh/q2rnm5OTwoAAOXr6LJzsPiq63WCREWa+MWXgzN6040tDPRuj/sgNDRRdDkBmzY0ZFZZyLpjvg+vvhyt9OR1ry53yixoeNTV+x+G6KBle7AekgoqoeWnMp0M9VPRDaiInrcRezagbopBXjiNdKwJR1bcktp9wDLrSvRm1aeYH72phSd4NWOECsRhXXLGf7GSLUJRyBdI7+7dsjRriVrQfmfyAfNoAV8ASX7vrmltByjTIn1CFsol7qzDHQquMr8WB3Mo2llDaGqA1GkXgr8/aokE1MFcSmmFR7uR1dLPOlt+f6ZTXYRwALSPy1SMxb2pcRQbB1rg7oQRpzZhHecy8JVsUMmVFZ+9VzhS68k7GHv2MODpPvXy9F1ul+5Kqm361qEKmcdF1cXWbW/NVJMm1SXlUCZNtfcczbpx66nbKCZf4VRMHqnSJxWfMZgH1d6SlTptI3Z/jFosAtg+hqCkRBcekmoua2/zR6RDqfePyRZMZbH4PNtgRxO7sj54L+mZGa64jRcXy92u7fwnOJFnWoH7lSsz0OiUEBJ24RquaG5YUn6M25+CXkokv3EXxW5WYlCBq0lyIyhqK9FNsCflHRmddaTNehQTX3XGHHeiqZZlII01tNanl8q/SFNayulcUZIYT00OQ3hhE3+ih0/Ybbmw1+IJoXzTOfEBaGFeS7AOL4Fo0M7u2YPSdm9fnEKXCPKpZbxp/XLuyOGGXSod5aC79zZoiF2diJoR0FW6ClvnDkiKSpm/wBrZi0cxMycG0q7rMwdzDRgcP5E8SJjMnWSGdBW25YdrotnynLNqBs6yaoJsM5bTk3armIkSQtVfj7c6kLvY9cX0lDWC0C5uKM45rpfuIlja4M+21RK8vdjChgb8xAG6GP1Y92ZIQNifh9vVdIHbISbnzgA3nA0ZR0hNH0tlZqtn/bIqWuKedeXIOELnan36UemUdnHSXMvKfkypIS8z19qZSZ2mZRjMVMtwIBHVpNG6y8FY3Ybe5z0TIWglzfIUN3HPrhdTmk5QlXY30uOcJqw/SsNJ+M0dfdxgMPSCWaqbwxGtS+3YMqrEvVlWG553PmczWBRpJ2eY23qcobD6TDd+2CB4aY3kZN21QGz8bjlDPl/IwsX5lr4i6SrSMTv19NNtF1tK5LkxjB6It3boN9T7Sk5smUyfu2zkP/J4pFLvvaDVH1YqT6umGV6Ih5j8SYb1LYkG5K29YRSz/ur37IV+TDwaPSnpS6jLQ1PpRdCTESzhzxKsieiLn9xJ53bzkpVKSCrummZ1N063mz7H2GlRn1ZjiVWe4fHZShsubUV5dg5vPTiGUkroQJ8oFeFrAHF2II2t0lUTyL9z+mU8tWLWBqln2PxQ2Mh8w98Zi4tvKz9h+SNDVEHNWI5+tZn7F0GBTzQPtgOEFcbvzlHb5R0zB/VuRW+YzD3YUlWDFqIOEA5fg7soNibcvD1Vb6w/6nehdmxEwJuULTOsuoWfJJcOrW2F8Cie3EllYrqqrZmifG8974gDdI6/3tIulO/vVj+41L9nYxvNwHMb140D85ANi0O+Ri+X702creO2imlQ0+ubdWduX84r7UjRPPOphKxrScbZet+5fcbKMoiG8oqRcPQyd3hnoUJ4bJNsFQmft1YkqIUcGratN1R5K+CF5GzXGNfxiSI/4hcNisflRByJBAoISaN6e8+n3TTu2bs8ZKx+KzMXGw0LAc2ob4yxKRU5S9HgV7cBVzROEa8Xkz5GrXd/x5D9WJjcojOtFpOw1qL0nJJZhG8QJy3PazqHk2J2sZ6336iBtzil7EUskaQbBD07wj4mXLWbtu8d4qpPL+pjVEB13SfJxyyrLQ18VUZlshFtZbxoMC+r9QQDzp9ZjSdTjazhm7CVfZkuJC0DdU8x6KVZ5tdt+y0mBNUUJnb0eM+fiXpKlC+SYDaWAzSZgZaPSmyUHWcIdl+Ztij7aAkf3r21BxFjsamMD7Uq4+jDkSr+ZGsqhFzn1iOqkRripZHq6Dqbz1WtGTX4VVqZXo/D+lh90UQoW8hMO4rJYYQjkdA+ar7OTrL+oF2cZRPQF1su3NnUEsFYIo6zXDxRRSb7JLsHt/GYINUr+4zg4Ym6pzGHpDj0G2wYGMW7FlTTw2tCeNV15WZfNsNhBAgcJs8oko77OpPPaBFcAjWPiaDERfh49/e6e9nxravJbrvohODuuK4era8SOaWVJaG6a5srLy/JHbs9I/YSPLmTq5TqMRNiNLP3uRcpM1gzLA5F1TGFxDG01yrTLf3lNJlGXVZnPVC/rkylJFyAwJ09I7rHCK0GgyU63iq20P6gcWSveqg90t6NqH4heKNhN6Fl5T4/p9in5kfmFRqrFY42b9Iaeti55y365m4i1ETJ5bq+PjNR759h3ZLncMxv4mbVmx4ZNL5NGJS0MrOSQKq8Ilyx6fjKvsOKrtjzbdXuJIk60W3KpKYcpvf3KBhgxvEy72AvxSeFxG5S+C5ZAwd6KpVaDUqJ/HCRBnLv+17vf1i0NsQU30ovT5jaR4DBz3K4D/fqQdgneK7QwCa5hLZgiQMtqMO7jKfEY06o1Xap2OseMoLj7GTry7xaIshrZFjH4y1F915UteCgkyoPjYqcwJzw+Z4Gqe7b7YWL36YuoNrx4aFSFZ2EIrbMwO541br/vk/1VsKnz4Eoe+UoHn1uxFS4npOkT/AS/MrmfXaHNUdHJD9P7UlObPj7bJrJzsPnXhR2u+uuvC1Iq3h3DwJn2//eamQ2Dx+kvj/LUTx0mesqq/9n3TAx15zaMQe1FhiHz4GNckaUpCkOW87vn56otLD32IXhlcwoCT474Rfe6GALlu/oX2vsHMvJ73mi6l/lRVwZxZIpwyfApnnDe7VXFP/0rxvTQfs8G1xnVduCxthDFsnC0xYJ2pQs3FIZ51TrIO0Mi0jQwhulfXOlqLr2WI2ZrL3Sg1lLfJWZNyt251ARz1+11XoZ3qAYUjQbhrCdzqXx4zcVvyktNCQ1kOj4EOZ85iMISSD7iUm+UAbCorq94k6vG9sJ8mefuUCppEDyjJt9SNKHBoxSy2RFz8IXa3d39uFqLIK+NLVuRlkQP4xKJGaPxU+hOE6W/hI1hn6GX4HFaurB2nWgLV3LetAJHHxIVGFCn33HMEfkhX9AK0IBGynVLCoNUAwatY++aL6btM43cBufMdg0kiDpbT7C3GKabjB7JhQ6uq3iMwSeWlKnTy0mcs81J/iidEMm+Vqm7Sym4HY+D+Z61bHmIqEIesn1Yret16p3zjPYZbwcPqz7jC2RgbaQfmywHjR+eynHySaZ/fTjlNIKI4N3jVaU5jKJoR7uoB+DWlKrVLVhA677TGwK+mkiI+/FpGMj6jnCGkFuPLOnv28t854ARjE9952OYWKvgtl8RnVL4bbNQuGJelgPFmdt5FnbdyU2ZZA8CEGBVZOmhDH7QI5Ivml3WC9LwbDijkPKhX520ujBTgrf0UMXSP753YLoVic2lKHeW4tunsjSOUgq9YJp0msLzDk55RoXIcNWn/tInBxhGxPuGpYHZO3iaIW0VZIVHQn0GdYoIotQPlmyct9vrq73dmeJUYpem76/JjlClB1H4U0/ZGpXVeJuaumYGjImbRB5X955uahjTW6W5cbJZ8LTnal9mL4h9PF7iqp+wQ70sGJTnHw61MK86rYV89w2UnGpNYeERoeIHizOUOKcub4gdCP5CZLotjXL7RFqKQGzVfYV0Se6J+9RPHNrD9jnP/u2eEElu5od3Fa3jLo/UlKIcz88Tpnoi0O1DqESHUekolE/S3PD0JvETWHqAzWH4JjUyWQbEwePiRfck6rDmQZm5s0Y6cFL8Is8O0aNrz+TNmkiq0cLllV0t2XKYay5FpfoON/Tm1IZujfm2JJJWFRNL/fMd3NdQSm0jDy/8xXFsRFesMXE3P5kluf9WFgFntBocVNpnZb8bq4nLTbGQnmqmJgRbfmYbtowWpLWmysfcZsw0w0djwYqj4YouOzsDB2tKdeee/VYdRuO5T0pwJOgLh6vnlM2iMWweWjY9wqVP67iNHHDz3YY3bJxVWX3eX3VSITByJI2dpS+hHA2wxgrR9DOEfUFPOLAIyaXqXBP9hxRKgI89kmpzMQy1buhRzJlGizdrb1CaNbPVYz4M1itCrE1cUQergcsvrzjdwpxqz5sAdvKQc+2QJTmwZ3ZTs4D21MFmPpsz2RcjsyPxuPoPSm7ipQHKmt8Dw+C8nmx6B3RXGzYj+/UEh1vt0kZfbhvQm5XUjzh/DnUhUhFyXO9qUXeC9pH5uTF4NO9OPrHQukXVHq1chdE6Y0VyaLIsL5jU31+jDsEA4XDbKwa643spW8UjMK29lubRWpZZ7pToLQI+yJwZCeXAKVpWYSEICivYNd9bmJ5PDcxnByaF5TBrrIwXo0FiERuffNlVnBeCE6jqlijbtWD8Mrq+aHotInwNJiI9JWjkJ45a4FK00dF7rv1cocf4jPgGmgYa9rS1HQVJpwqfAVU9NixkFD3mDVV31Z6l9VzPeDPKLUiLKbDjNDQKjZ/i3UWh3J38FZeQRIPqzdUrPtCiPamrzpCEf+b5ycj6SZyAe/vcb3Jf6MU3ZtCgkLMTlAaIadlbY/dw01Y2sG7ftGZ9MEadM/b8NNaVUK4aewL2dOtZ4ExyiRL1MSYOmYjK2mLTNwSJ3MnxZq4h5/KP5UBPiZY87kXRlb7PgqDptH61nKGZQ8tTmuXCOY62Onl75IuPT8dMxSB3skHxU0UCWr1mVbojL96SLOuv6ZNTNRlHnsnQqklibRsa+9j5QOn6CmGLU3o6roWj/DXIvMzWVZMrZM6Bbdj/boda43b5ALZyO1Ua0n9DOd5Hr5QDA0uTcZJ5zHZ1tJzmzrrk9lcQRkyYpPYHBsuFVFJnEzqCbqJwgm9dqbPjGhWkvmUjva1G+g0utvTDmaC1YnNK8tgG+UhFopZo9GNZE2WgOA9NWYOsbAhy3WJsqm/nj66XhEWcsOKxZtPvoD7mHpnec1ZOtuxJrwaqY+Mgrx3rqBtI7ZgJ5wv4QkPYw37ydwO/Rq2FDUus2dl0yr8qGXnE8dgbKnnSHblKCjKSZUIpLMNvEeMe3qrJ+3qwfP0TQnE94xm6Q8WvH3vvy2r4hWBgUtPfN+XDl/k0sDbJbAnP1y5ahOKNFWxI/YQXSlsxyphc6lCJRopAxsWQTzzpcz7oNc9oslv25G88lgrF1SQTC/IbDOHPDvd9h4rGatM7AumzKNMuZFNlI6k3E92mHil3DtGPf9UI7pARJb/VtTiu9WWB5Kg+x7Eq0S8b6VcGfdfTWd5D2zkuU9RK2okozzS/cD0EfEUY6d88o3+NEGt4QpyTGQeHLsMedWeWQzJ8LtyKunSB03QowNvvB6vPwI1gGBXKKsLZpEXbLOIQc72xwzqBYzZGUpVC9HKtYQ828P39PO0MuriiHj3s7G12MV8QGEdlYfivDuTSTWcMDuiLytdYuhWrIvYe7I7qlRaSZUIMTHRX9tNq4DqhXYeQxMJhftOsQoQieoCwh/ciAneTZKjfMbBoHgJwxKk8zZMYThrPv5JVhKdUWFuU+Gkd8uh4h14Mh+eDAnXjhKdhi30x2xnb99whYyye1mxo3I856qu3LD+aFDqitS1E1IzTZvc1+UQLjq7T2MKD8CSQ0vARkjF7KO3QYi7NZp11XmZ3+gJNlwLpwyMGHuR77Rb+EGRfXTdqbKyQW2cRsH8YBi3nOZjNUMlStz0DUTdPr10agyLwjusnbmLE0TzZdzPCik5OlhqNS0+FdlsxGZeEKnMHmTD8mijSQgBseFPBMVL4vzkD+Mf7W8KqOpvvEiQfmvPOK45XFIRdYcrUl4rWG/08XMN+LbQ41QsVFoBcoyIcE3dlH2olGfo25pet1aOQgbFpu7xS7O9kZuMNW/Szh8PtNS7O19480SkQLysdy5FnGVm/QKimtJDgAVt7nH6jKdoZku6npoyeQ5y18OwM80S3IZ6fO4xo6d1snTeyq57U+jTYRloABskIMfoG8OGKsGqfxPtWRGHqwyvszCDparPga46EoyN9sL4ODcB6fvk13fEnzyiy2Mc5OdhgCYTQAtn8z00ELFjE4UYnBsfba3Nr4I0Zw8KNGPXJgKlu1lwrYgs0yk+iZGHRJbNpouN/2R2WC8lKECOovA485Cqbc4f2YWgbMqMakgp9ZFWs13vuFpDssIAxeG0Sdypmh5dDA00Tf2rsKGXAeOyGZwCwijkAky8fU9T+4rdAU3ecBCNAutzTjZOLwNJ+9u5m45zFisD2Rp12Y7ZSm2kA9Op06RSgvADO16R6qw81C4zSOO3DmsGcSvouw7P2DkjnWsz5w8fsOCbO96sV9zKQGk7i1EZk5EJ2+YfPFSJGeox2MSpocwggyNrYdRpB6RZANjulbvBcxktzhnEDq7IcdSWeVRDUHXDHDSjLBF8E9hI7+l1I7LPVIO8WpkFsOAat6uEMARIYNgOCF/zERMLwIZTPmQ1h8YDeb++iEm6uMMEjwb5WITnRuxjfU5/dx8u1sPY129BVTF+/pBYZchPwiCCtAVKizba78c0SjiZoPhbS50kitJoDBpVDAllhSv1Tgu+DtnEyZDcrjWzt8r2JbtB16x4qogoxL9b83jHMwgLJiUTC9K2o4wxQDUSmueCoB6BZ6oXYgHUVqvbOf2CeGVasIau5j2pLYvTsz3NumeDjbH1CxNFCrIs8bomhh0K7h+jMsJ4LyrEG60CktwMqYgG4xBViUROrSK8F8eXN7EqdoUD9V3aD/ka6kURIRCL/UXeszZgCb0SG8A7g6WDBnyQD3nKMvtK2WTJkw/odh9loFGQI+HBx5CH4Ic10wIfNtSwA8R90GByqcTgSAj7+WTh6huh0AEeBDKxMn+1e+QoUDiHWE2i9cLLZTuw/k9XWWdpU+aPaBuQDwgzkjX4jl8dakvY8KS5hKVDoHoFvS/TtfEXNkagFRnQ+QiB51ovhWi7a+cMwbNPh2JnvzsCfe6mgIyQXBUALYW2FeGHB5odG3VVwldTEJaxwHzz2oap0DtYE+vdzUGX8j3fY2t/XoYHGQV75UHn9C0Q50urbOXIXM/2aFkRnTEuUOj8yXaWiI0RhCP3XYKLZc9Q6HYLNHlXNiMphVEF8EpeHeTK73MUrC7asPsvNvR7VEbmxCkuRTBAZOAuOU5uWXhV6zMfihFcdNq6TuFsNAbhHSY69UfeYCHdBHZ0Dgnkz0N4RWdLtCS+hKztaNBlQuKMwlXNvMDmxsVkUoZamT6dXaGdnFsqq/JIMUANae14YymcV2NAj39nwkUerpuPsY2S6k2F69TuKg9quuU504bDanqRkkBcm+eXRFLDtAOGNa7PUnvxEo+SvDanKGEql2GpztxIdkA7lfNfpBjgyV+in0pThO9IIIpArIim3HxaSqq21o4Q8ZIsU877XYCDV4EV87p6W2fBg07EATETxo4i4vegrhpGSU3SwqajwsqhfeOu2JbQMiQb3rcteyPQFuMCx9ycLs49hVoeZUV5p1KkiGo+ydMNkXARbda0AiQ7+7xQbmh+t1TRM0/jiDLHTgbHM1cWzdcSlMjSpp9X9axrpAduOG4G4V28YoKXn/rShqkODUlqS+SOvYMrniXcKMM8N8+9P/+8xNewXHQKMv3lx3w+qE9cNebQR3cP3HGFgTQjNxnIZlAEaqVRr1FVRbBvUL6xcgFo4n1tWY44/4zD3PbLTfzQ0dsGWAqtqG6J1XujOqf1uptrtb2aJq9l3mZ9buUxD5Vjelo2qLrbucXc0vRIHYdBIndbNEdWqyDFelJ5ze1plxCOLZuI8dIWEXEkljbvhpKlVD/qsy9vI2dcEn2HH486WhhMypc9dGk6MmR3w16698A9Nu1caH2nN8T7vV3Wjok4iyaeLc/B5Odklwg4tg5GF/5gHtLbRDIR9WLrj3ZQuBAhKzNsGnbQxVzld4+qBdUFvcTEm009HPpjkN4YwqPePXoLDDuXYuFJKIcrTBoSuyfte2l8SQHlB9qdbqUd82/AaE2aNQivjyMz2gAAdUSbr9WB4yC3+JLzRqH3A8MkkpmowhDaezwPe25JNFXd9hthY1HirdTC8cC5Q8JKWZshFErzAs2Hb2efVsdeqWf0AdCn1CnerfuFCrmNJcrxxvELLqBXagwGB/ShqAiLHCXisY/20hHZZg7tLM9COQlMxPOyT8Z5QTmbpm93gp2xDrYWdMcx3Los2xaInJd8HQ3X2tI2oZ6gVp72ET5q4B8mr25+HKoaigr01bSmFdMquHiUO8pQThCU6WVHGa67eFTQuFOzbCAhu+hVyBXBHWW/3eB/J7/aaJUzuDWSUKU/pL6zLZYRFbKY4ZdWlbYaYdjKbsyUekx3VOvYJckk3phI9Zm8WKpD+SkRc6GaEy8tUfoXS+z0xEWsnT7Cd6SRLzZI7Wa2KQdknRimOgKsNgomeTN85kLDJvfyYE/dNRM9YosNh0i9YC7USKgFRaLKlwsll2MXjZ+fwTwgJJA+KXyRyofgbrXWEd9e9q85JUcD4ysm37B7F9qnkhxBtXf3g+4FE1qvTMnf6hKCtXFFTf7MHcQ/GAmPQaRP6nQYOR73RRqKS5zCNUDA3ziYU+BJXxuqHQX3FqMCdnPoYup5fNkh9ESLRB5e8u7wFMKO+pJBzdD5i/Yu7+ZACQ8xbJLMjxZlWQuRjQR2w1hFAGsFPQXkhQCX0YTHY9yCC/fqHbqDPWHqlUZiy1EZR8OqRf1ndbwWVgwM/jCHj2GcpkU+qq+uivQvrMOMq/he0KzLrtDBo8FIxD/5zIqMj7HFiC94ehTpyElvipdx3BpVsQaVftso8h1z094HSbm0iuctrkjsziKpR2FsmjGY+813WIzXbdL2p9bfJ2e+e5dv3tU/CM8+bW4FO94BCmduxc0dZ9gOs5K9+4E/WeINj4sadshzx/xyw0cwm1UOJZXlGVhNTTqmra6CSP3yz9ZmPuV4YR6QrFzMcC4/gpacwgorXSxNc0vBYabPtdz7KFH+eXjOA3HIpZBzIPBZ0pdzpi8tr9Kj5z1bt71tmVszag6aLfYWax+OYEukxOV7mVjCYtpLmnj63byojALFsoT7ABAEzEfwLMj7zt11Ie/umsbd3m8sFBk3hr2n6Y88f88JL858X3tybS95okWHvK10XzjXKgVuy1/MWGILWWaARBhy5GLKoDAi70NUiCD2K2WG3sfc/nrdH9C32QmbQ/TWbjiWzu0tk5qcDs2fzgB/m2QB5xd6YwQAEMJ3mROK9QOTzFhHz+waPijZT1AgPStLQxMjZhcdC/OvWKzWRsQmMmSgv1oLfdGBVlg19ZbjWG5xSji7wxM29BuhZx5b+1PQG32IWZ0ccp/4wxtCidW6AnQfD+bmIbtxNI6+ek3l80pMhsa1gCs6usT3/iHhtsltBZcbRSe3+RacU9K72lpfVzL8XYt2YxojUwAArC91hX+0r8fE0t7A1lLH/BomM9ElOJCehf41SnzzF8i//vvWbrYPFwyavIXm2zdYhGdfiqviTXLDbdzXEURHlckv8LwtMIeN9SbXjejTA12ucKL4qDgOWSu+D7rTVivo6vEZyCYd6qlRQlXS2CAlCbpo1L3X54PMNHNlKSEpPUdlL8ap2TR576Apz8mWM/cxVeFtDO7OMGAPYVi0yFKFhxlDKumXDpgbJ+qJKJfGbpu73OQbE9hEfJTo2UenFn8uSV437nPzsSR7OEEGGn/QHicfvBWRNYngc9Oqd61IMEfBU2+0lG1vdjNU9Q4jTZkObJzcbdCtImuSqj6pvcFr347cnljld0MIC0+rcYWUqWIlIaPeVjP2Pv6d1SPPhE+ZSllhLgXtPbZdaBZFqDrxFOclwdPrNUikMVn+7s2l+vRj/KeuSGwOFjgHx7twrXF+1Bw7e/cc1U389F8xYMr5K/ivkLUo7W9rfe1MldkS2aIQAHD70g0KpJc2j5Wlnb3dNRqd7tfUf3982/T04tK996VllcR7+xiY6RYgv+7ca8BF7sYGAAD10ov35i+C2ttamZsb2F4jHcbfI/9g70RoiWXTLWQRox0GVRnlcEnxg/sQgb1qrPn0BQTPqXzTQrCeXdQWJ6UKw836O8FtB+7MMKMdJ/rYBTcDZ3KsSG/6c7CHNLAE0oVAWnN+Wy7F5H69z3rvg97ocYTfuKD2eYaR1G+3puivr7G0Zq/wEoK6beWpUyDLHMOxxYvY4cgUIdTHSs67rCBgOo7nDQlqdbpN1EgXMSlVj8voTdbpzVtJ3ThV/TJ6XQ8u0lxFdDVpylrx47WZ7QlzOwm/fGI82Ctmx82jypZc6KyVky6YMNO43dZHk5mqExmBybhJ+HfjFMBu5XwEAEAC4tp3Fn0dq2u0CtUvkP/atmlmYGD9lf11885f/xzml3dDkssCmFsZmehdQzXNL6H/W90WVvoG5v9t3f+C/rFu8l+H0L/OhUL/O9w/Vk/16ygGlvYm9i7XyID5d9l/nMWl44G1jp6Zgf5/ezz4f+q/P340HgADuXTqj78ObDuwpsOYvxwNyC4LaWdg62iiZ/DfzuTf2Cs2wj+D4P4giIWOiSXYPKmXpfDdLeTWrSo+0fd0+JqMtW4NDTBy4hqY8neVVgCM2fWcVw3nHvxnX6JBAR0S9Ihy+oVBXKjTA3vqq1P3WVQEC3nSIroVWY8fBW2LqL43HmD7ZNjfD2VPSkqydRzmINrrePH2MNcQ3xUe0Bs67d1p5H3ZxdqsQU+AKnOW1co77Q6/6aPytU2WZSnbAwEA6L7ybNVCx9LE0MDO/hqzVdJLcP+ewV+jhRl+Tf3h4wFbsDwiJAuyyIVdIDlcv6fk/U/YkDdWJMdiMh4VgbCd6gydu6WCTMihjQt0Xnhjx4jR+SIYT6OsnSi2STU4rZ2sJa2p0vK/tcDBPZal3n7TGflWxg5eddorVn6SC/rm/ZsUx7B/F1srFyXUEAAAr+tXR9/A2tzK5Ro1p/s1FWTmYGdvZWHianANPvNV+CBdHbvrdGK+Kwf5959aGFjag7e6fXjtfWgWZJ8TnpaaBgSNBJSAyFl616gyFKS2AF2oiQqxT0blDGN0NLdTqLOYZXnU4w3kNjwPPO8X6Y4Gw61PxHTi5Nr2P/e2hQymN4IeLcRyty1JsIWMTlbzoL4l6HXzQ1X3l0aNzHCjRMyPr9TTQjZ0M2lBYYSDEEj5O0OTyImDxLNokKeh8fQ93s3O5oHZRRcU6ZFjy5AKS/sb+I5PuhKWM3OjqeY0+Y23ovm+nhmpDKHmLAEAwAbisioJXr1Kf/+qY29iZQleKMbOkhvvbqHB9J9nbUKySPrVQPLW2vAtdm1pfLaj8F2iEz/KiOXgG0jKons/7XfHEz1oKSFFdYPEpELPU+ezGr2DxCebAh5jemJLN9AmpaJqcYEj+6K/kWW+dOMAKs4pHUX913tRC3xH61/dw+rSa+Du1bP79+0dPC/9HhbEplvIvp80svthIJeUX+9DPolZf+cCrdiGUdp+JCVUYck/CCdbW4ee/hCXz3I31wPbkyL0ocBdBRUZbN31t8KcJW5DzWymMwTGnJ1HDkFERtIqiDNGuob7xa91ZQ73VAulTM3b5/0Wom6wRb8OR8o5uUDx+NqSr5/0F7kCAJBzaadivVKuVo4GtuY6LnbX6L3c1woE0jdwNDC3sr5GT5b4o4D/vo9b6FiDtylPyL86NewJT0v2rhMjsa1UiIioFTomZG8YxgYFJQkJOvuoC4/ei0euEXwKTD5zHzyyMODDymsyD5t7DFhQzKVRaBN9tSMTSjsMMjCUmIvKeqamls85Rq16JQ9tgFsZpIMmvYBfvwFy/MclnUl2r7yJDGupPvMNaK82Jg3+e0xSYaBQ+eNBGleO8hF+VdkHKPJoPPkfepneT8OPONn85wwCTek2egYAAMeX1kjyz2r0szuffk/JXxc+dP+0lg0/mqRK39mzdQou7xyqIFXo4wMqGKdc6i2UdcrdDj3jA8QAvIodTc3lRy1PB44nF9WC6RIy3kNW4jFE4shEdsnNEHbBF6pwnx0/yR0tmFZ87xJM17BtIewbcCwLcWf8Qmy5NaqgjebvrAVKl7gcAAAouzRrmT/L+rI7WbeMqY8AmtiWR1IaSDugul8FXg2mFDRZn9V//jKfyPo+P/Lc+UEy25kwRwHVszO2IrWUjw+68gg3tFoftrWxNRmkaXRhNB0UNJfjpKHkG8kWiwtrk7xoU0Nm8+mjlJqT2hZ83zzEvzpazckuw79I+GHY2/E9Q/ohU5C+apQPHs4rW5L7IruIf1fjNLP99K+ZV/4fTAas9MyutS5C/2sqSORfH2DnDG2Rtg+U2jtkpelGZLvp2rulyllHyj7OKmQxf1RQJgN4zryFiTzciYR5zs5yLO/G5mvFCVV6hVcEGaE96zkOgIFRD2VmRhTNbTnKFO3IXUR88JJ7rzFvd1dKwQ5p1451R5JhFtNOsVt61w7z9g5angBP4Us5ft/PwVOnWDBriGx0eSeh2mP0tLTQfpywvnLThqrh73ja51eREMmKOSD+c+bKMmwhFQAANcirPg58X4H//2C2M/5aAAXl97Kd3UOykoy9H2cVlOE72hmVaXvFezrk2xmVxQvEZZiZJGTkxSVlukCSSuIdsr33mRTE6Xu6JQbmIKEEvg50EWUKW8IAAAhcedJta2Bn5WCrd50JGvElOJAJC6flNa4j6l8x/yePtV8jWDvomv/GWs4/qZS/poKM7S2us9zC9JvoP64M9W8EsjZ3MDK5TsOCfhv+x3nQ/kaoP7jsGa+AB+nZXWfR/M4VQ/xxyZivEtDEQsfoOs9aHFcO8sd5MVwlpOl1mortahH+JyujX/l//8V/aQD/B/eP1f9oOcvB3sT8emuhZD+nXVkp0nds1H+y/4WK+aFCCEgsqP9o/Pb1EiQAwtfvZTz56/+/+Q6L76Hfvt2BAAxq8xPod++p+B747VFyPDCgGATw61dEfI/79hQ0PhiOAQb4jdPo/+H9+Oz0//+gAWuC9bDAL05S/5yEA0ZCgAN+fZIaPM1vTxWTgqWp/FPYP93A76nfngnGAafCA786n/w97Nu9E+Cw9R/Dvj1UfFnxsMCKh0kJ/GrzBbiub/cxkIHp0vwJ6oerq5cpxANTSEoF/M6WiJ/jiMBwlpfgvtsSAZ74t/77TbDEG3+B/H5LxGViScHEatMAV3DzwfV+a7LTgel982vqD9z8y1TfBFPNQAtc0bgHV/6tA80Iptz398iXddVfXR/tdMDvGtvgqr8dkajAVBPSA1c0ti+TSwIm1/0y9vee9s8F04AJHvgl9E8kszEAv29n/67kgF9CryaZHEzy6q/p+r93ZdCDqRZhBK7jZF8mnApMeN6vA/zDxP65eGYw8bBMwHVN7N+/A1pfFuQf/jW49G+NZfA7YOuvqT/wry9TTQammosZuIpZ/fOKg8sO/w3sZcX+f/633i4uGH/vB/zvferfH7h7QMDvuMO/eyUQ3QKu4A6Dp/ytw8oAlrLtr6lXnr+A6+ZmAa7g2/6cSgdGDf819Ye+7c/5zGD8zavwv/dtv5s4feNO8oEVX4kV+G/5tt8H/dY0FAQL6nYb+C/aoN/H/dbAuwsWV40N+K8YlJe1IStYG4reAf7MJvx5IG6wQIXXCvQDmxC8lt/aYRJgtSRlB/4HNuH38b81piTB4gtzAP8LC+57Ad96QTJgArg4gf+RG/b7NzYxLuAKHtR3yxbfuDHgU6KkX1N/5EH9Y6HlGy/l20F07UkKN3ANi+f3hz2hu8Dv+DM/xxGD4SIuwX3vz/x8HkENVuP5XzH/ZMYmxgNcwZr5OZUSjJr0a+r31szPq8EEVo3D30RfrSjUYPJ1eIGruzI/TwAElkDdb8OvlgItWAp0fMB1DJmf4xnB8P5XwH9nyPy8TnfA6rRyxRBXqxb4/EmdH7i+F/PzhDjAF56uHORqKTGAP7cLANe0YX6eDxtYPjFXi/AnT/SwgsCVHJjffaLX/B3u1YTjgglv/kGAf5ovP5cLvmaLIQT8vvnyrcgfOS1/i7wQtPwn9hvfBQb2r+/dA+4BxvgA8Fror9/+LwAA//9JEAV4MlwAAA=="); err != nil {
+ if err := gres.Add("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"); err != nil {
panic("add binary content to resource manager failed: " + err.Error())
}
}
diff --git a/server/internal/library/hggen/internal/service/install.go b/server/internal/library/hggen/internal/service/install.go
index cb7257c..ebda00e 100644
--- a/server/internal/library/hggen/internal/service/install.go
+++ b/server/internal/library/hggen/internal/service/install.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package service
import (
@@ -29,6 +35,7 @@ type serviceInstallAvailablePath struct {
filePath string
writable bool
installed bool
+ IsSelf bool
}
func (s serviceInstall) Run(ctx context.Context) (err error) {
@@ -104,6 +111,8 @@ func (s serviceInstall) Run(ctx context.Context) (err error) {
)
if input != "" {
inputID = gconv.Int(input)
+ } else {
+ break
}
// Check if out of range.
if inputID >= len(paths) || inputID < 0 {
@@ -131,17 +140,17 @@ func (s serviceInstall) Run(ctx context.Context) (err error) {
}
// IsInstalled checks and returns whether the binary is installed.
-func (s serviceInstall) IsInstalled() bool {
+func (s serviceInstall) IsInstalled() (*serviceInstallAvailablePath, bool) {
paths := s.getAvailablePaths()
for _, aPath := range paths {
if aPath.installed {
- return true
+ return &aPath, true
}
}
- return false
+ return nil, false
}
-// getGoPathBinFilePath retrieves ad returns the GOPATH/bin path for binary.
+// getGoPathBin retrieves ad returns the GOPATH/bin path for binary.
func (s serviceInstall) getGoPathBin() string {
if goPath := genv.Get(`GOPATH`).String(); goPath != "" {
return gfile.Join(goPath, "bin")
@@ -214,6 +223,7 @@ func (s serviceInstall) checkAndAppendToAvailablePath(folderPaths []serviceInsta
filePath = gfile.Join(dirPath, binaryFileName)
writable = gfile.IsWritable(dirPath)
installed = gfile.Exists(filePath)
+ self = gfile.SelfPath() == filePath
)
if !writable && !installed {
return folderPaths
@@ -225,5 +235,6 @@ func (s serviceInstall) checkAndAppendToAvailablePath(folderPaths []serviceInsta
writable: writable,
filePath: filePath,
installed: installed,
+ IsSelf: self,
})
}
diff --git a/server/internal/library/hggen/internal/utility/allyes/allyes.go b/server/internal/library/hggen/internal/utility/allyes/allyes.go
index 146eda4..f8f7d1e 100644
--- a/server/internal/library/hggen/internal/utility/allyes/allyes.go
+++ b/server/internal/library/hggen/internal/utility/allyes/allyes.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package allyes
import (
diff --git a/server/internal/library/hggen/internal/utility/mlog/mlog.go b/server/internal/library/hggen/internal/utility/mlog/mlog.go
index 4bf00c5..d7af655 100644
--- a/server/internal/library/hggen/internal/utility/mlog/mlog.go
+++ b/server/internal/library/hggen/internal/utility/mlog/mlog.go
@@ -1,3 +1,9 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package mlog
import (
diff --git a/server/internal/library/hggen/internal/utility/utils/utils.go b/server/internal/library/hggen/internal/utility/utils/utils.go
index aee71b8..fc7fa74 100644
--- a/server/internal/library/hggen/internal/utility/utils/utils.go
+++ b/server/internal/library/hggen/internal/utility/utils/utils.go
@@ -1,10 +1,20 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
package utils
import (
- "github.com/gogf/gf/v2/os/gfile"
- "github.com/gogf/gf/v2/text/gstr"
+ "context"
+ "fmt"
"golang.org/x/tools/imports"
+ "github.com/gogf/gf/v2/os/gfile"
+ "github.com/gogf/gf/v2/os/gproc"
+ "github.com/gogf/gf/v2/text/gregex"
+ "github.com/gogf/gf/v2/text/gstr"
"hotgo/internal/library/hggen/internal/consts"
"hotgo/internal/library/hggen/internal/utility/mlog"
)
@@ -36,6 +46,13 @@ func GoFmt(path string) {
}
}
+// GoModTidy executes `go mod tidy` at specified directory `dirPath`.
+func GoModTidy(ctx context.Context, dirPath string) error {
+ command := fmt.Sprintf(`cd %s && go mod tidy`, dirPath)
+ err := gproc.ShellRun(ctx, command)
+ return err
+}
+
// IsFileDoNotEdit checks and returns whether file contains `do not edit` key.
func IsFileDoNotEdit(filePath string) bool {
if !gfile.Exists(filePath) {
@@ -43,3 +60,78 @@ func IsFileDoNotEdit(filePath string) bool {
}
return gstr.Contains(gfile.GetContents(filePath), consts.DoNotEditKey)
}
+
+// ReplaceGeneratedContentGFV2 replaces generated go content from goframe v1 to v2.
+func ReplaceGeneratedContentGFV2(folderPath string) (err error) {
+ return gfile.ReplaceDirFunc(func(path, content string) string {
+ if gstr.Contains(content, `"github.com/gogf/gf`) && !gstr.Contains(content, `"github.com/gogf/gf/v2`) {
+ content = gstr.Replace(content, `"github.com/gogf/gf"`, `"github.com/gogf/gf/v2"`)
+ content = gstr.Replace(content, `"github.com/gogf/gf/`, `"github.com/gogf/gf/v2/`)
+ content = gstr.Replace(content, `"github.com/gogf/gf/v2/contrib/`, `"github.com/gogf/gf/contrib/`)
+ return content
+ }
+ return content
+ }, folderPath, "*.go", true)
+}
+
+// GetImportPath calculates and returns the golang import path for given `filePath`.
+// Note that it needs a `go.mod` in current working directory or parent directories to detect the path.
+func GetImportPath(filePath string) string {
+ // If `filePath` does not exist, create it firstly to find the import path.
+ var realPath = gfile.RealPath(filePath)
+ if realPath == "" {
+ _ = gfile.Mkdir(filePath)
+ realPath = gfile.RealPath(filePath)
+ }
+
+ var (
+ newDir = gfile.Dir(realPath)
+ oldDir string
+ suffix string
+ goModName = "go.mod"
+ goModPath string
+ importPath string
+ )
+
+ if gfile.IsDir(filePath) {
+ suffix = gfile.Basename(filePath)
+ }
+ for {
+ goModPath = gfile.Join(newDir, goModName)
+ if gfile.Exists(goModPath) {
+ match, _ := gregex.MatchString(`^module\s+(.+)\s*`, gfile.GetContents(goModPath))
+ importPath = gstr.Trim(match[1]) + "/" + suffix
+ importPath = gstr.Replace(importPath, `\`, `/`)
+ importPath = gstr.TrimRight(importPath, `/`)
+ return importPath
+ }
+ oldDir = newDir
+ newDir = gfile.Dir(oldDir)
+ if newDir == oldDir {
+ return ""
+ }
+ suffix = gfile.Basename(oldDir) + "/" + suffix
+ }
+}
+
+// GetModPath retrieves and returns the file path of go.mod for current project.
+func GetModPath() string {
+ var (
+ oldDir = gfile.Pwd()
+ newDir = gfile.Dir(oldDir)
+ goModName = "go.mod"
+ goModPath string
+ )
+ for {
+ goModPath = gfile.Join(newDir, goModName)
+ if gfile.Exists(goModPath) {
+ return goModPath
+ }
+ oldDir = newDir
+ newDir = gfile.Dir(oldDir)
+ if newDir == oldDir {
+ break
+ }
+ }
+ return ""
+}
diff --git a/server/internal/library/hggen/internal/utility/utils/utils_http_download.go b/server/internal/library/hggen/internal/utility/utils/utils_http_download.go
new file mode 100644
index 0000000..d68e61c
--- /dev/null
+++ b/server/internal/library/hggen/internal/utility/utils/utils_http_download.go
@@ -0,0 +1,105 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package utils
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ "strconv"
+ "time"
+
+ "github.com/gogf/gf/v2/errors/gerror"
+
+ "hotgo/internal/library/hggen/internal/utility/mlog"
+)
+
+// HTTPDownloadFileWithPercent downloads target url file to local path with percent process printing.
+func HTTPDownloadFileWithPercent(url string, localSaveFilePath string) error {
+ start := time.Now()
+ out, err := os.Create(localSaveFilePath)
+ if err != nil {
+ return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath)
+ }
+ defer out.Close()
+
+ headResp, err := http.Head(url)
+ if err != nil {
+ return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath)
+ }
+ defer headResp.Body.Close()
+
+ size, err := strconv.Atoi(headResp.Header.Get("Content-Length"))
+ if err != nil {
+ return gerror.Wrap(err, "retrieve Content-Length failed")
+ }
+ doneCh := make(chan int64)
+
+ go doPrintDownloadPercent(doneCh, localSaveFilePath, int64(size))
+
+ resp, err := http.Get(url)
+ if err != nil {
+ return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath)
+ }
+ defer resp.Body.Close()
+
+ wroteBytesCount, err := io.Copy(out, resp.Body)
+ if err != nil {
+ return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath)
+ }
+
+ doneCh <- wroteBytesCount
+ elapsed := time.Since(start)
+ if elapsed > time.Minute {
+ mlog.Printf(`download completed in %.0fm`, float64(elapsed)/float64(time.Minute))
+ } else {
+ mlog.Printf(`download completed in %.0fs`, elapsed.Seconds())
+ }
+
+ return nil
+}
+
+func doPrintDownloadPercent(doneCh chan int64, localSaveFilePath string, total int64) {
+ var (
+ stop = false
+ lastPercentFmt string
+ )
+ for {
+ select {
+ case <-doneCh:
+ stop = true
+
+ default:
+ file, err := os.Open(localSaveFilePath)
+ if err != nil {
+ mlog.Fatal(err)
+ }
+ fi, err := file.Stat()
+ if err != nil {
+ mlog.Fatal(err)
+ }
+ size := fi.Size()
+ if size == 0 {
+ size = 1
+ }
+ var (
+ percent = float64(size) / float64(total) * 100
+ percentFmt = fmt.Sprintf(`%.0f`, percent) + "%"
+ )
+ if lastPercentFmt != percentFmt {
+ lastPercentFmt = percentFmt
+ mlog.Print(percentFmt)
+ }
+ }
+
+ if stop {
+ break
+ }
+ time.Sleep(time.Second)
+ }
+}
diff --git a/server/internal/library/hggen/internal/utility/utils/utils_test.go b/server/internal/library/hggen/internal/utility/utils/utils_test.go
new file mode 100644
index 0000000..6136870
--- /dev/null
+++ b/server/internal/library/hggen/internal/utility/utils/utils_test.go
@@ -0,0 +1,22 @@
+// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+package utils_test
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/gogf/gf/v2/test/gtest"
+ "hotgo/internal/library/hggen/internal/utility/utils"
+)
+
+func Test_GetModPath(t *testing.T) {
+ gtest.C(t, func(t *gtest.T) {
+ goModPath := utils.GetModPath()
+ fmt.Println(goModPath)
+ })
+}
diff --git a/server/internal/library/hggen/views/column.go b/server/internal/library/hggen/views/column.go
index b78e938..2ee8e98 100644
--- a/server/internal/library/hggen/views/column.go
+++ b/server/internal/library/hggen/views/column.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package views
import (
@@ -20,7 +19,7 @@ import (
)
// DoTableColumns 获取指定表生成字段列表
-func DoTableColumns(ctx context.Context, in sysin.GenCodesColumnListInp, config gendao.CGenDaoInput) (fields []*sysin.GenCodesColumnListModel, err error) {
+func DoTableColumns(ctx context.Context, in *sysin.GenCodesColumnListInp, config gendao.CGenDaoInput) (fields []*sysin.GenCodesColumnListModel, err error) {
var (
sql = "select ORDINAL_POSITION as `id`, COLUMN_NAME as `name`, COLUMN_COMMENT as `dc`, DATA_TYPE as `dataType`, COLUMN_TYPE as `sqlType`, CHARACTER_MAXIMUM_LENGTH as `length`, IS_NULLABLE as `isAllowNull`, COLUMN_DEFAULT as `defaultValue`, COLUMN_KEY as `index`, EXTRA as `extra` from information_schema.COLUMNS where TABLE_SCHEMA = '%s' and TABLE_NAME = '%s' ORDER BY `id` ASC"
conf = g.DB(in.Name).GetConfig()
@@ -42,7 +41,6 @@ func DoTableColumns(ctx context.Context, in sysin.GenCodesColumnListInp, config
CustomAttributes(ctx, field, config)
}
}
-
return
}
@@ -65,10 +63,7 @@ func CustomAttributes(ctx context.Context, field *sysin.GenCodesColumnListModel,
// GenGotype 生成字段的go类型
func GenGotype(ctx context.Context, field *sysin.GenCodesColumnListModel, in gendao.CGenDaoInput) (goName, typeName, tsName, tsType string) {
- var (
- err error
- )
-
+ var err error
tsName = getJsonTagFromCase(field.Name, in.JsonCase)
goName = gstr.CaseCamel(field.Name)
@@ -100,7 +95,6 @@ func GenGotype(ctx context.Context, field *sysin.GenCodesColumnListModel, in gen
}
tsType = ShiftMap[typeName]
-
return
}
diff --git a/server/internal/library/hggen/views/column_default.go b/server/internal/library/hggen/views/column_default.go
index 58b5b03..c155ed6 100644
--- a/server/internal/library/hggen/views/column_default.go
+++ b/server/internal/library/hggen/views/column_default.go
@@ -317,5 +317,10 @@ func setDefaultValue(field *sysin.GenCodesColumnListModel) {
value = consts.ConvType(field.DefaultValue, field.GoType)
}
+ // 时间类型不做默认值处理
+ if field.GoType == GoTypeGTime {
+ value = ""
+ }
+
field.DefaultValue = value
}
diff --git a/server/internal/library/hggen/views/curd.go b/server/internal/library/hggen/views/curd.go
index cd654f2..70d00bb 100644
--- a/server/internal/library/hggen/views/curd.go
+++ b/server/internal/library/hggen/views/curd.go
@@ -7,7 +7,6 @@ package views
import (
"context"
- "fmt"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
@@ -67,14 +66,14 @@ type CurdOptions struct {
HeadOps []string `json:"headOps"`
Join []*CurdOptionsJoin `json:"join"`
Menu *CurdOptionsMenu `json:"menu"`
- Step *CurdStep // 转换后的流程控制条件
- dictMap g.Map // 字典选项 -> 字段映射关系
TemplateGroup string `json:"templateGroup"`
ApiPrefix string `json:"apiPrefix"`
+ Step *CurdStep // 转换后的流程控制条件
+ dictMap g.Map // 字典选项 -> 字段映射关系
}
type CurdPreviewInput struct {
- In sysin.GenCodesPreviewInp // 提交参数
+ In *sysin.GenCodesPreviewInp // 提交参数
DaoConfig gendao.CGenDaoInput // 生成dao配置
Config *model.GenerateConfig // 生成配置
view *gview.View // 视图模板
@@ -102,7 +101,7 @@ func (l *gCurd) initInput(ctx context.Context, in *CurdPreviewInput) (err error)
}
if len(in.masterFields) == 0 {
- if in.masterFields, err = DoTableColumns(ctx, sysin.GenCodesColumnListInp{Name: in.In.DbName, Table: in.In.TableName}, in.DaoConfig); err != nil {
+ if in.masterFields, err = DoTableColumns(ctx, &sysin.GenCodesColumnListInp{Name: in.In.DbName, Table: in.In.TableName}, in.DaoConfig); err != nil {
return
}
}
@@ -236,7 +235,7 @@ func (l *gCurd) DoBuild(ctx context.Context, in *CurdBuildInput) (err error) {
for name, f := range in.BeforeEvent {
if gstr.InArray(in.PreviewIn.options.AutoOps, name) {
if err = f(ctx); err != nil {
- return fmt.Errorf("in doBuild operation beforeEvent to '%s' failed::%v", name, err)
+ return gerror.Newf("in doBuild operation beforeEvent to '%s' failed:%v", name, err)
}
}
}
@@ -254,7 +253,7 @@ func (l *gCurd) DoBuild(ctx context.Context, in *CurdBuildInput) (err error) {
}
if err = gfile.PutContents(vi.Path, strings.TrimSpace(vi.Content)); err != nil {
- return fmt.Errorf("writing content to '%s' failed: %v", vi.Path, err)
+ return gerror.Newf("writing content to '%s' failed: %v", vi.Path, err)
}
if gstr.Str(vi.Path, `.`) == ".sql" && needExecSql {
@@ -266,7 +265,6 @@ func (l *gCurd) DoBuild(ctx context.Context, in *CurdBuildInput) (err error) {
if gstr.Str(vi.Path, `.`) == ".go" {
utils.GoFmt(vi.Path)
}
-
}
// 后置操作
@@ -274,7 +272,7 @@ func (l *gCurd) DoBuild(ctx context.Context, in *CurdBuildInput) (err error) {
for name, f := range in.AfterEvent {
if gstr.InArray(in.PreviewIn.options.AutoOps, name) {
if err = f(ctx); err != nil {
- return fmt.Errorf("in doBuild operation afterEvent to '%s' failed::%v", name, err)
+ return gerror.Newf("in doBuild operation afterEvent to '%s' failed:%v", name, err)
}
}
}
@@ -515,12 +513,12 @@ func (l *gCurd) generateWebModelContent(ctx context.Context, in *CurdPreviewInpu
tplData, err := l.webModelTplData(ctx, in)
if err != nil {
- return err
+ return
}
genFile.Content, err = in.view.Parse(ctx, name+".template", tplData)
if err != nil {
- return err
+ return
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].WebViewsPath, gstr.LcFirst(in.In.VarName), "model.ts")
@@ -564,7 +562,6 @@ func (l *gCurd) generateWebIndexContent(ctx context.Context, in *CurdPreviewInpu
genFile.Meth = consts.GenCodesBuildMethCover
}
in.content.Views[name] = genFile
-
return
}
diff --git a/server/internal/library/hggen/views/curd_generate_input.go b/server/internal/library/hggen/views/curd_generate_input.go
index b00ec04..d75b022 100644
--- a/server/internal/library/hggen/views/curd_generate_input.go
+++ b/server/internal/library/hggen/views/curd_generate_input.go
@@ -164,7 +164,6 @@ func (l *gCurd) generateStructFieldDefinition(field *sysin.GenCodesColumnListMod
default:
panic("inputType is invalid")
}
-
return result
}
diff --git a/server/internal/library/hggen/views/curd_generate_web_edit.go b/server/internal/library/hggen/views/curd_generate_web_edit.go
index 98327ab..be25616 100644
--- a/server/internal/library/hggen/views/curd_generate_web_edit.go
+++ b/server/internal/library/hggen/views/curd_generate_web_edit.go
@@ -48,7 +48,7 @@ func (l *gCurd) generateWebEditFormItem(ctx context.Context, in *CurdPreviewInpu
component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.Dc, field.TsName)
case FormModeInputEditor:
- component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName)
+ component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName, field.TsName)
case FormModeInputDynamic:
component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName)
diff --git a/server/internal/library/hggen/views/curd_generate_web_index.go b/server/internal/library/hggen/views/curd_generate_web_index.go
index 068678d..aed7024 100644
--- a/server/internal/library/hggen/views/curd_generate_web_index.go
+++ b/server/internal/library/hggen/views/curd_generate_web_index.go
@@ -83,6 +83,5 @@ func (l *gCurd) webIndexTplData(ctx context.Context, in *CurdPreviewInput) (g.Ma
}
}
data["isSearchForm"] = isSearchForm
-
return data, nil
}
diff --git a/server/internal/library/hggen/views/utils.go b/server/internal/library/hggen/views/utils.go
index ef0b8cc..d105dac 100644
--- a/server/internal/library/hggen/views/utils.go
+++ b/server/internal/library/hggen/views/utils.go
@@ -25,7 +25,6 @@ func (l *gCurd) parseServFunName(templateGroup, varName string) string {
if gstr.HasPrefix(varName, templateGroup) && varName != templateGroup {
return varName
}
-
return templateGroup + varName
}
@@ -94,7 +93,6 @@ func ImportSql(ctx context.Context, path string) error {
return err
}
}
-
return nil
}
@@ -144,7 +142,6 @@ func checkCurdPath(temp *model.GenerateAppCrudTemplate, addonName string) (err e
if !gfile.Exists(temp.WebViewsPath) {
return gerror.Newf(tip, "WebViewsPath", temp.WebViewsPath)
}
-
return
}
diff --git a/server/internal/library/hgorm/dao.go b/server/internal/library/hgorm/dao.go
index 300f3c9..1eefffd 100644
--- a/server/internal/library/hgorm/dao.go
+++ b/server/internal/library/hgorm/dao.go
@@ -29,6 +29,10 @@ type Join struct {
fields map[string]*gdb.TableField // 表字段列表
}
+func LeftJoin(m *gdb.Model, masterTable, masterField, joinTable, alias, onField string) *gdb.Model {
+ return m.LeftJoin(GenJoinOnRelation(masterTable, masterField, joinTable, alias, onField)...)
+}
+
// GenJoinOnRelation 生成关联表关联条件
func GenJoinOnRelation(masterTable, masterField, joinTable, alias, onField string) []string {
relation := fmt.Sprintf("`%s`.`%s` = `%s`.`%s`", alias, onField, masterTable, masterField)
diff --git a/server/internal/library/network/tcp/client.go b/server/internal/library/network/tcp/client.go
index c56b799..d457648 100644
--- a/server/internal/library/network/tcp/client.go
+++ b/server/internal/library/network/tcp/client.go
@@ -7,19 +7,33 @@ package tcp
import (
"context"
+ "github.com/gogf/gf/v2/container/gtype"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/gtcp"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/grpool"
- "github.com/gogf/gf/v2/os/gtime"
"hotgo/utility/simple"
- "reflect"
"sync"
"time"
)
+// Client tcp客户端
+type Client struct {
+ ctx context.Context // 上下文
+ conn *Conn // 连接对象
+ config *ClientConfig // 配置
+ msgParser *MsgParser // 消息处理器
+ logger *glog.Logger // 日志处理器
+ isLogin *gtype.Bool // 是否已登录
+ taskGo *grpool.Pool // 任务协程池
+ closeFlag *gtype.Bool // 关闭标签,关闭以后可以重连
+ stopFlag *gtype.Bool // 停止标签,停止以后不能重连
+ wg sync.WaitGroup // 流程控制
+ mutex sync.Mutex // 状态锁
+}
+
// ClientConfig 客户端配置
type ClientConfig struct {
Addr string // 连接地址
@@ -33,86 +47,56 @@ type ClientConfig struct {
CloseEvent CallbackEvent // 连接关闭事件
}
-// Client 客户端
-type Client struct {
- Ctx context.Context // 上下文
- Logger *glog.Logger // 日志处理器
- IsLogin bool // 是否已登录
- addr string // 连接地址
- auth *AuthMeta // 认证元数据
- rpc *Rpc // rpc协议支持
- timeout time.Duration // 连接超时时间
- connectInterval time.Duration // 重连时间间隔
- maxConnectCount uint // 最大重连次数,0不限次数
- connectCount uint // 已重连次数
- autoReconnect bool // 是否开启自动重连
- loginEvent CallbackEvent // 登录成功事件
- closeEvent CallbackEvent // 连接关闭事件
- sync.Mutex // 状态锁
- heartbeat int64 // 心跳
- msgGo *grpool.Pool // 消息处理协程池
- routers map[string]RouterHandler // 已注册的路由
- conn *gtcp.Conn // 连接对象
- wg sync.WaitGroup // 状态控制
- closeFlag bool // 关闭标签,关闭以后可以重连
- stopFlag bool // 停止标签,停止以后不能重连
-}
+// CallbackEvent 回调事件
+type CallbackEvent func()
// NewClient 初始化一个tcp客户端
-func NewClient(config *ClientConfig) (client *Client, err error) {
+func NewClient(config *ClientConfig) (client *Client) {
client = new(Client)
+ client.ctx = gctx.New()
+ client.logger = g.Log("tcpClient")
+
+ baseErr := gerror.New("NewClient fail")
if config == nil {
- err = gerror.New("config is nil")
+ client.logger.Fatal(client.ctx, gerror.Wrap(baseErr, "config is nil"))
return
}
if config.Addr == "" {
- err = gerror.New("client address is not set")
+ client.logger.Fatal(client.ctx, gerror.Wrap(baseErr, "client address is not set"))
return
}
- if config.Auth == nil {
- err = gerror.New("client auth cannot be empty")
- return
- }
-
- if config.Auth.Group == "" || config.Auth.Name == "" {
- err = gerror.New("Auth.Group or Auth.Group is nil")
- return
- }
-
- client.Ctx = gctx.New()
- client.autoReconnect = true
- client.addr = config.Addr
- client.auth = config.Auth
- client.loginEvent = config.LoginEvent
- client.closeEvent = config.CloseEvent
- client.Logger = g.Log("tcpClient")
-
+ client.config = config
if config.ConnectInterval <= 0 {
- client.connectInterval = 5 * time.Second
+ client.config.ConnectInterval = 5 * time.Second
} else {
- client.connectInterval = config.ConnectInterval
+ client.config.ConnectInterval = config.ConnectInterval
}
if config.Timeout <= 0 {
- client.timeout = 10 * time.Second
+ client.config.Timeout = 10 * time.Second
} else {
- client.timeout = config.Timeout
+ client.config.Timeout = config.Timeout
}
- client.msgGo = grpool.New(5)
- client.rpc = NewRpc(client.Ctx, client.msgGo, client.Logger)
+ client.isLogin = gtype.NewBool(false)
+ client.closeFlag = gtype.NewBool(false)
+ client.stopFlag = gtype.NewBool(false)
+
+ client.taskGo = grpool.New(5)
+ client.msgParser = NewMsgParser(client.handleRoutineTask)
+ client.registerDefaultRouter()
return
}
// Start 启动tcp连接
func (client *Client) Start() (err error) {
- client.Lock()
- defer client.Unlock()
+ client.mutex.Lock()
+ defer client.mutex.Unlock()
- if client.stopFlag {
+ if client.stopFlag.Val() {
err = gerror.New("client is stop")
return
}
@@ -121,64 +105,66 @@ func (client *Client) Start() (err error) {
return gerror.New("client is running")
}
- client.IsLogin = false
- client.connectCount = 0
- client.closeFlag = false
- client.stopFlag = false
+ client.isLogin.Set(false)
+ client.config.ConnectCount = 0
+ client.closeFlag.Set(false)
+ client.stopFlag.Set(false)
client.wg.Add(1)
- simple.SafeGo(client.Ctx, func(ctx context.Context) {
+ simple.SafeGo(client.ctx, func(ctx context.Context) {
client.connect()
})
return
}
+// registerDefaultRouter 注册默认路由
+func (client *Client) registerDefaultRouter() {
+ var routers = []interface{}{
+ client.onResponseServerLogin, // 服务登录
+ client.onResponseServerHeartbeat, // 心跳
+ }
+ client.RegisterRouter(routers...)
+}
+
// RegisterRouter 注册路由
-func (client *Client) RegisterRouter(routers map[string]RouterHandler) (err error) {
- if client.conn != nil {
- return gerror.New("client is running")
+func (client *Client) RegisterRouter(routers ...interface{}) {
+ err := client.msgParser.RegisterRouter(routers...)
+ if err != nil {
+ client.logger.Fatal(client.ctx, err)
}
+}
- client.Lock()
- defer client.Unlock()
-
- if client.routers == nil {
- client.routers = make(map[string]RouterHandler)
- // 默认路由
- client.routers = map[string]RouterHandler{
- "ResponseServerHeartbeat": client.onResponseServerHeartbeat,
- "ResponseServerLogin": client.onResponseServerLogin,
- }
+// RegisterRPCRouter 注册RPC路由
+func (client *Client) RegisterRPCRouter(routers ...interface{}) {
+ err := client.msgParser.RegisterRPCRouter(routers...)
+ if err != nil {
+ client.logger.Fatal(client.ctx, err)
}
+}
- for i, router := range routers {
- _, ok := client.routers[i]
- if ok {
- return gerror.Newf("client route duplicate registration:%v", i)
- }
- client.routers[i] = router
- }
- return
+// RegisterInterceptor 注册拦截器
+func (client *Client) RegisterInterceptor(interceptors ...Interceptor) {
+ client.msgParser.RegisterInterceptor(interceptors...)
}
// dial
func (client *Client) dial() *gtcp.Conn {
for {
- conn, err := gtcp.NewConn(client.addr, client.timeout)
- if err == nil || client.closeFlag {
+ conn, err := gtcp.NewConn(client.config.Addr, client.config.Timeout)
+ if err == nil || client.closeFlag.Val() {
return conn
}
- if client.maxConnectCount > 0 {
- if client.connectCount < client.maxConnectCount {
- client.connectCount += 1
+ if client.config.MaxConnectCount > 0 {
+ if client.config.ConnectCount < client.config.MaxConnectCount {
+ client.config.ConnectCount += 1
} else {
return nil
}
}
- client.Logger.Debugf(client.Ctx, "connect to %v error: %v", client.addr, err)
- time.Sleep(client.connectInterval)
+ client.logger.Debugf(client.ctx, "connect to %v error: %v", client.config.Addr, err)
+ time.Sleep(client.config.ConnectInterval)
continue
}
}
@@ -190,26 +176,24 @@ func (client *Client) connect() {
reconnect:
conn := client.dial()
if conn == nil {
- if !client.stopFlag {
- client.Logger.Debugf(client.Ctx, "client dial failed")
+ if !client.stopFlag.Val() {
+ client.logger.Debugf(client.ctx, "client dial failed")
}
return
}
- client.Lock()
- if client.closeFlag {
- client.Unlock()
- _ = conn.Close()
- client.Logger.Debugf(client.Ctx, "client connect but closeFlag is true")
+ client.mutex.Lock()
+ if client.closeFlag.Val() {
+ client.mutex.Unlock()
+ conn.Close()
+ client.logger.Debugf(client.ctx, "client connect but closeFlag is true")
return
}
- client.conn = conn
- client.connectCount = 0
- client.heartbeat = gtime.Timestamp()
-
+ client.conn = NewConn(conn, client.logger, client.msgParser)
+ client.config.ConnectCount = 0
client.read()
- client.Unlock()
+ client.mutex.Unlock()
client.serverLogin()
client.startCron()
@@ -217,102 +201,38 @@ reconnect:
// read
func (client *Client) read() {
- simple.SafeGo(client.Ctx, func(ctx context.Context) {
+ go func() {
defer func() {
client.Close()
- client.Logger.Debugf(client.Ctx, "client are about to be reconnected..")
- time.Sleep(client.connectInterval)
- _ = client.Start()
+ client.logger.Debugf(client.ctx, "client are about to be reconnected..")
+ time.Sleep(client.config.ConnectInterval)
+ client.Start()
}()
- for {
- if client.conn == nil {
- client.Logger.Debugf(client.Ctx, "client client.conn is nil, server closed")
- break
- }
-
- msg, err := RecvPkg(client.conn)
- if err != nil {
- client.Logger.Debugf(client.Ctx, "client RecvPkg err:%+v, server closed", err)
- break
- }
-
- if client.routers == nil {
- client.Logger.Debugf(client.Ctx, "client RecvPkg routers is nil")
- break
- }
-
- if msg == nil {
- client.Logger.Debugf(client.Ctx, "client RecvPkg msg is nil")
- break
- }
-
- f, ok := client.routers[msg.Router]
- if !ok {
- client.Logger.Debugf(client.Ctx, "client RecvPkg invalid message: %+v", msg)
- continue
- }
-
- switch msg.Router {
- case "ResponseServerLogin", "ResponseServerHeartbeat": // 服务登录、心跳无需验证签名
- client.doHandleRouterMsg(initCtx(gctx.New(), &Context{}), f, msg.Data)
- default: // 通用路由消息处理
- in, err := VerifySign(msg.Data, client.auth.AppId, client.auth.SecretKey)
- if err != nil {
- client.Logger.Warningf(client.Ctx, "client read VerifySign err:%+v message: %+v", err, msg)
- continue
- }
-
- ctx := initCtx(gctx.New(), &Context{
- Conn: client.conn,
- Auth: client.auth,
- TraceID: in.TraceID,
- })
-
- // 响应rpc消息
- if client.rpc.HandleMsg(ctx, msg.Data) {
- return
- }
-
- client.doHandleRouterMsg(ctx, f, msg.Data)
- }
+ if err := client.conn.Run(); err != nil {
+ client.logger.Debug(client.ctx, err)
}
- })
+ }()
}
// Close 关闭同服务器的链接
func (client *Client) Close() {
- client.Lock()
- defer client.Unlock()
+ client.mutex.Lock()
+ defer client.mutex.Unlock()
- client.IsLogin = false
- client.closeFlag = true
+ client.isLogin.Set(false)
+ client.closeFlag.Set(true)
if client.conn != nil {
client.conn.Close()
client.conn = nil
}
- if client.closeEvent != nil {
- client.closeEvent()
+ if client.config.CloseEvent != nil {
+ client.config.CloseEvent()
}
client.wg.Wait()
}
-// Stop 停止服务
-func (client *Client) Stop() {
- if client.stopFlag {
- return
- }
- client.stopFlag = true
- client.stopCron()
- client.Close()
-}
-
-// IsStop 是否已停止
-func (client *Client) IsStop() bool {
- return client.stopFlag
-}
-
// Destroy 销毁当前连接
func (client *Client) Destroy() {
client.stopCron()
@@ -322,80 +242,62 @@ func (client *Client) Destroy() {
}
}
-// Write
-func (client *Client) Write(data interface{}) error {
- client.Lock()
- defer client.Unlock()
-
- if client.conn == nil {
- return gerror.New("client conn is nil")
+// Stop 停止服务
+func (client *Client) Stop() {
+ if client.stopFlag.Val() {
+ return
}
+ client.stopFlag.Set(true)
+ client.stopCron()
+ client.Close()
+}
- if client.closeFlag {
- return gerror.New("client conn is closed")
- }
+// IsStop 是否已停止
+func (client *Client) IsStop() bool {
+ return client.stopFlag.Val()
+}
- if data == nil {
- return gerror.New("client Write message is nil")
- }
+// IsLogin 是否已登录成功
+func (client *Client) IsLogin() bool {
+ return client.isLogin.Val()
+}
- msgType := reflect.TypeOf(data)
- if msgType == nil || msgType.Kind() != reflect.Ptr {
- return gerror.Newf("client json message pointer required: %+v", data)
+func (client *Client) handleRoutineTask(ctx context.Context, task func()) {
+ ctx, cancel := context.WithCancel(ctx)
+ err := client.taskGo.AddWithRecover(ctx,
+ func(ctx context.Context) {
+ task()
+ cancel()
+ },
+ func(ctx context.Context, err error) {
+ client.logger.Warningf(ctx, "routineTask exec err:%+v", err)
+ cancel()
+ },
+ )
+ if err != nil {
+ client.logger.Warningf(ctx, "routineTask add err:%+v", err)
}
- msg := &Message{Router: msgType.Elem().Name(), Data: data}
- return SendPkg(client.conn, msg)
+}
+
+// Conn 获取当前连接
+func (client *Client) Conn() *Conn {
+ return client.conn
}
// Send 发送消息
func (client *Client) Send(ctx context.Context, data interface{}) error {
- MsgPkg(data, client.auth, gctx.CtxId(ctx))
- return client.Write(data)
-}
-
-// Reply 回复消息
-func (client *Client) Reply(ctx context.Context, data interface{}) (err error) {
- user := GetCtx(ctx)
- if user == nil {
- err = gerror.New("获取回复用户信息失败")
- return
+ if client.conn == nil {
+ return gerror.New("conn is nil")
}
- MsgPkg(data, client.auth, user.TraceID)
- return client.Write(data)
+ return client.conn.Send(ctx, data)
}
-// RpcRequest 发送消息并等待响应结果
-func (client *Client) RpcRequest(ctx context.Context, data interface{}) (res interface{}, err error) {
- var (
- traceID = MsgPkg(data, client.auth, gctx.CtxId(ctx))
- key = client.rpc.GetCallId(client.conn, traceID)
- )
-
- if traceID == "" {
- err = gerror.New("traceID is required")
- return
- }
- return client.rpc.Request(key, func() {
- _ = client.Write(data)
- })
+// Request 发送消息并等待响应结果
+func (client *Client) Request(ctx context.Context, data interface{}) (interface{}, error) {
+ return client.conn.Request(ctx, data)
}
-// doHandleRouterMsg 处理路由消息
-func (client *Client) doHandleRouterMsg(ctx context.Context, fun RouterHandler, args ...interface{}) {
- ctx, cancel := context.WithCancel(ctx)
- err := client.msgGo.AddWithRecover(ctx,
- func(ctx context.Context) {
- fun(ctx, args...)
- cancel()
- },
- func(ctx context.Context, err error) {
- client.Logger.Warningf(ctx, "doHandleRouterMsg msgGo exec err:%+v", err)
- cancel()
- },
- )
-
- if err != nil {
- client.Logger.Warningf(ctx, "doHandleRouterMsg msgGo Add err:%+v", err)
- return
- }
+// RequestScan 发送消息并等待响应结果,将结果保存在response中
+func (client *Client) RequestScan(ctx context.Context, data, response interface{}) error {
+ return client.conn.RequestScan(ctx, data, response)
}
diff --git a/server/internal/library/network/tcp/client_cron.go b/server/internal/library/network/tcp/client_cron.go
index a315511..cf54e77 100644
--- a/server/internal/library/network/tcp/client_cron.go
+++ b/server/internal/library/network/tcp/client_cron.go
@@ -10,12 +10,11 @@ import (
"fmt"
"github.com/gogf/gf/v2/os/gcron"
"github.com/gogf/gf/v2/os/gtime"
- "hotgo/internal/consts"
)
// getCronKey 生成客户端定时任务名称
func (client *Client) getCronKey(s string) string {
- return fmt.Sprintf("tcp.client_%s_%s:%s", s, client.auth.Group, client.auth.Name)
+ return fmt.Sprintf("tcp.client_%s:%s", s, client.conn.LocalAddr().String())
}
// stopCron 停止定时任务
@@ -28,19 +27,22 @@ func (client *Client) stopCron() {
// startCron 启动定时任务
func (client *Client) startCron() {
// 心跳超时检查
- if gcron.Search(client.getCronKey(consts.TCPCronHeartbeatVerify)) == nil {
- _, _ = gcron.AddSingleton(client.Ctx, "@every 600s", func(ctx context.Context) {
- if client.heartbeat < gtime.Timestamp()-consts.TCPHeartbeatTimeout {
- client.Logger.Debugf(client.Ctx, "client heartbeat timeout, about to reconnect..")
+ if gcron.Search(client.getCronKey(CronHeartbeatVerify)) == nil {
+ _, _ = gcron.AddSingleton(client.ctx, "@every 600s", func(ctx context.Context) {
+ if client == nil || client.conn == nil {
+ return
+ }
+ if client.conn.Heartbeat < gtime.Timestamp()-HeartbeatTimeout {
+ client.logger.Debugf(client.ctx, "client heartbeat timeout, about to reconnect..")
client.Destroy()
}
- }, client.getCronKey(consts.TCPCronHeartbeatVerify))
+ }, client.getCronKey(CronHeartbeatVerify))
}
// 心跳
- if gcron.Search(client.getCronKey(consts.TCPCronHeartbeat)) == nil {
- _, _ = gcron.AddSingleton(client.Ctx, "@every 120s", func(ctx context.Context) {
+ if gcron.Search(client.getCronKey(CronHeartbeat)) == nil {
+ _, _ = gcron.AddSingleton(client.ctx, "@every 300s", func(ctx context.Context) {
client.serverHeartbeat()
- }, client.getCronKey(consts.TCPCronHeartbeat))
+ }, client.getCronKey(CronHeartbeat))
}
}
diff --git a/server/internal/library/network/tcp/client_handle.go b/server/internal/library/network/tcp/client_handle.go
index a084347..20e3cb8 100644
--- a/server/internal/library/network/tcp/client_handle.go
+++ b/server/internal/library/network/tcp/client_handle.go
@@ -7,70 +7,73 @@ package tcp
import (
"context"
+ "fmt"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtime"
- "github.com/gogf/gf/v2/util/gconv"
- "hotgo/internal/consts"
- "hotgo/internal/model/input/msgin"
+ "hotgo/utility/encrypt"
)
// serverLogin 心跳
func (client *Client) serverHeartbeat() {
+ if !client.isLogin.Val() {
+ return
+ }
+
ctx := gctx.New()
- if err := client.Send(ctx, &msgin.ServerHeartbeat{}); err != nil {
- client.Logger.Debugf(ctx, "client WriteMsg ServerHeartbeat err:%+v", err)
+ if err := client.conn.Send(ctx, &ServerHeartbeatReq{}); err != nil {
+ client.logger.Warningf(ctx, "client ServerHeartbeat Send err:%+v", err)
return
}
}
// serverLogin 服务登陆
func (client *Client) serverLogin() {
- data := &msgin.ServerLogin{
- Group: client.auth.Group,
- Name: client.auth.Name,
+ auth := client.config.Auth
+
+ // 无需登录
+ if auth == nil {
+ return
}
+ data := &ServerLoginReq{
+ Name: auth.Name,
+ Extra: auth.Extra,
+ Group: auth.Group,
+ AppId: auth.AppId,
+ Timestamp: gtime.Timestamp(),
+ }
+
+ // 签名
+ data.Sign = encrypt.Md5ToString(fmt.Sprintf("%v%v%v", data.AppId, data.Timestamp, auth.SecretKey))
+
ctx := gctx.New()
- if err := client.Send(ctx, data); err != nil {
- client.Logger.Debugf(ctx, "client WriteMsg ServerLogin err:%+v", err)
+ if err := client.conn.Send(ctx, data); err != nil {
+ client.logger.Warningf(ctx, "client ServerLogin Send err:%+v", err)
return
}
}
// onResponseServerLogin 接收服务登陆响应结果
-func (client *Client) onResponseServerLogin(ctx context.Context, args ...interface{}) {
- var in *msgin.ResponseServerLogin
- if err := gconv.Scan(args[0], &in); err != nil {
- client.Logger.Infof(ctx, "onResponseServerLogin message Scan failed:%+v, args:%+v", err, args[0])
- return
- }
-
- if in.Code != consts.TCPMsgCodeSuccess {
- client.IsLogin = false
- client.Logger.Warningf(ctx, "onResponseServerLogin quit err:%v", in.Message)
+func (client *Client) onResponseServerLogin(ctx context.Context, req *ServerLoginRes) {
+ if err := req.GetError(); err != nil {
+ client.isLogin.Set(false)
+ client.logger.Warningf(ctx, "onResponseServerLogin destroy, err:%v", err)
client.Destroy()
return
}
- client.IsLogin = true
+ client.isLogin.Set(true)
- if client.loginEvent != nil {
- client.loginEvent()
+ if client.config.LoginEvent != nil {
+ client.config.LoginEvent()
}
}
// onResponseServerHeartbeat 接收心跳响应结果
-func (client *Client) onResponseServerHeartbeat(ctx context.Context, args ...interface{}) {
- var in *msgin.ResponseServerHeartbeat
- if err := gconv.Scan(args[0], &in); err != nil {
- client.Logger.Infof(ctx, "onResponseServerHeartbeat message Scan failed:%+v, args:%+v", err, args)
+func (client *Client) onResponseServerHeartbeat(ctx context.Context, req *ServerHeartbeatRes) {
+ if err := req.GetError(); err != nil {
+ client.logger.Warningf(ctx, "onResponseServerHeartbeat err:%v", err)
return
}
-
- if in.Code != consts.TCPMsgCodeSuccess {
- client.Logger.Warningf(ctx, "onResponseServerHeartbeat err:%v", in.Message)
- return
- }
-
- client.heartbeat = gtime.Timestamp()
+ client.conn.Heartbeat = gtime.Timestamp()
}
diff --git a/server/internal/library/network/tcp/conn.go b/server/internal/library/network/tcp/conn.go
new file mode 100644
index 0000000..d0ba9f7
--- /dev/null
+++ b/server/internal/library/network/tcp/conn.go
@@ -0,0 +1,177 @@
+// Package tcp
+// @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 tcp
+
+import (
+ "context"
+ "github.com/gogf/gf/v2/container/gtype"
+ "github.com/gogf/gf/v2/container/gvar"
+ "github.com/gogf/gf/v2/errors/gcode"
+ "github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/net/gtcp"
+ "github.com/gogf/gf/v2/os/gctx"
+ "github.com/gogf/gf/v2/os/glog"
+ "github.com/gogf/gf/v2/os/gtime"
+ "github.com/gogf/gf/v2/util/grand"
+ "net"
+ "sync/atomic"
+)
+
+// AuthMeta 认证元数据
+type AuthMeta struct {
+ Name string `json:"name"` // 客户端名称,当同一个应用ID有多个客户端时请使用不同的名称区分。比如cron1,cron2
+ Extra g.Map `json:"extra"` // 自定义数据,可以传递一些额外的自定义数据
+ Group string `json:"group"` // 客户端分组
+ AppId string `json:"appId"` // 应用ID
+ SecretKey string `json:"secretKey"` // 应用秘钥
+ EndAt *gtime.Time `json:"endAt"` // 授权过期时间
+ Routes []string `json:"routes"` // 授权路由
+}
+
+// Conn tcp连接
+type Conn struct {
+ CID int64 // 连接ID
+ Conn *gtcp.Conn // 连接对象
+ Auth *AuthMeta // 认证元数据
+ Heartbeat int64 // 心跳
+ FirstTime int64 // 首次连接时间
+
+ writeChan chan []byte // 发数据
+ closeFlag *gtype.Bool // 关闭标签
+ logger *glog.Logger // 日志处理器
+ msgParser *MsgParser // 消息处理器
+}
+
+var idCounter int64
+
+func NewConn(conn *gtcp.Conn, logger *glog.Logger, msgParser *MsgParser) *Conn {
+ tcpConn := new(Conn)
+ tcpConn.CID = atomic.AddInt64(&idCounter, 1)
+ tcpConn.Conn = conn
+ tcpConn.Heartbeat = gtime.Timestamp()
+ tcpConn.FirstTime = gtime.Timestamp()
+
+ tcpConn.writeChan = make(chan []byte, 1000)
+ tcpConn.closeFlag = gtype.NewBool(false)
+ tcpConn.logger = logger
+ tcpConn.msgParser = msgParser
+
+ go func() {
+ for b := range tcpConn.writeChan {
+ if b == nil {
+ break
+ }
+ if err := conn.SendPkg(b); err != nil {
+ break
+ }
+ }
+ }()
+ return tcpConn
+}
+
+func (c *Conn) Run() error {
+ for {
+ data, err := c.Conn.RecvPkg()
+ if err != nil {
+ return gerror.NewCodef(gcode.CodeInvalidRequest, "read packet err:%+v conn closed", err)
+ }
+
+ if c.closeFlag.Val() {
+ return nil
+ }
+
+ msg, err := c.msgParser.Encoding(data)
+ if err != nil {
+ return gerror.NewCodef(gcode.CodeInternalError, "message encoding err:%+v conn closed", err)
+ }
+
+ ctx, err := c.bindContext(msg)
+ if err != nil {
+ return gerror.NewCodef(gcode.CodeInternalError, "bindContext err:%+v message: %+v", err, msg)
+ }
+
+ if err = c.msgParser.handleInterceptor(ctx, msg); err != nil {
+ c.logger.Warning(ctx, gerror.Wrap(err, "interceptor authentication failed"))
+ continue
+ }
+
+ if err = c.msgParser.handleRouterMsg(ctx, msg); err != nil {
+ return err
+ }
+ }
+}
+
+// RemoteAddr returns the remote network address, if known.
+func (c *Conn) RemoteAddr() net.Addr {
+ return c.Conn.RemoteAddr()
+}
+
+// LocalAddr returns the local network address, if known.
+func (c *Conn) LocalAddr() net.Addr {
+ return c.Conn.LocalAddr()
+}
+
+// Write
+func (c *Conn) Write(b []byte) {
+ if !c.closeFlag.Val() {
+ c.writeChan <- b
+ }
+}
+
+// Send 发送消息
+func (c *Conn) Send(ctx context.Context, data interface{}) error {
+ if c.closeFlag.Val() {
+ return gerror.New("conn is closed")
+ }
+ b, err := c.msgParser.Decoding(ctx, data, "")
+ if err != nil {
+ return err
+ }
+ c.Write(b)
+ return nil
+}
+
+func (c *Conn) Close() {
+ if c.closeFlag.Val() {
+ return
+ }
+ c.closeFlag.Set(true)
+ close(c.writeChan)
+ c.Conn.Close()
+}
+
+// Request 发送消息并等待响应结果
+func (c *Conn) Request(ctx context.Context, data interface{}) (interface{}, error) {
+ if c.closeFlag.Val() {
+ return nil, gerror.New("conn is closed")
+ }
+ msgId := grand.S(16)
+ b, err := c.msgParser.Decoding(ctx, data, msgId)
+ if err != nil {
+ return nil, err
+ }
+ return c.msgParser.rpc.Request(ctx, msgId, func() {
+ c.Write(b)
+ })
+}
+
+// RequestScan 发送消息并等待响应结果,将结果保存在response中
+func (c *Conn) RequestScan(ctx context.Context, data, response interface{}) error {
+ body, err := c.Request(ctx, data)
+ if err != nil {
+ return err
+ }
+ return gvar.New(body).Scan(response)
+}
+
+// bindContext 将用户身份绑定到上下文
+func (c *Conn) bindContext(msg *Message) (ctx context.Context, err error) {
+ ctx = initCtx(gctx.New(), &Context{
+ Conn: c,
+ })
+ return SetCtxTraceID(ctx, msg.TraceId)
+}
diff --git a/server/internal/library/network/tcp/consts.go b/server/internal/library/network/tcp/consts.go
new file mode 100644
index 0000000..01c3276
--- /dev/null
+++ b/server/internal/library/network/tcp/consts.go
@@ -0,0 +1,32 @@
+// Package tcp
+// @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 tcp
+
+// 定时任务
+const (
+ CronHeartbeatVerify = "tcpHeartbeatVerify"
+ CronHeartbeat = "tcpHeartbeat"
+ CronAuthVerify = "tcpAuthVerify"
+)
+
+const (
+ HeartbeatTimeout = 300 // tcp心跳超时,默认300s
+ RPCTimeout = 10 // rpc通讯超时时间, 默认10s
+)
+
+const (
+ ParseRouterErrInvalidParams = "register router[%v] method must have two params"
+ ParseRouterRPCErrInvalidParams = "register RPC router [%v] method must have two response params"
+ ParseRouterErrInvalidFirstParam = "the first params of the processing method that registers the router[%v] must be of type context.Context"
+ ParseRouterErrInvalidSecondParam = "the second params of the processing method that registers the router[%v] must be of type pointer to a struct"
+)
+
+type CtxKey string
+
+// ContextKey 上下文
+const (
+ ContextKey CtxKey = "tcpContext" // tcp上下文变量名称
+)
diff --git a/server/internal/library/network/tcp/context.go b/server/internal/library/network/tcp/context.go
index 3f2dfbe..4c11215 100644
--- a/server/internal/library/network/tcp/context.go
+++ b/server/internal/library/network/tcp/context.go
@@ -8,23 +8,21 @@ package tcp
import (
"context"
"github.com/gogf/gf/v2/net/gtrace"
- "hotgo/internal/consts"
)
+// Context tcp上下文
+type Context struct {
+ Conn *Conn
+}
+
// initCtx 初始化上下文对象指针到上下文对象中,以便后续的请求流程中可以修改
-func initCtx(ctx context.Context, model *Context) (newCtx context.Context) {
- if model.TraceID != "" {
- newCtx, _ = gtrace.WithTraceID(ctx, model.TraceID)
- } else {
- newCtx = ctx
- }
- newCtx = context.WithValue(newCtx, consts.ContextTCPKey, model)
- return
+func initCtx(ctx context.Context, model *Context) context.Context {
+ return context.WithValue(ctx, ContextKey, model)
}
// GetCtx 获得上下文变量,如果没有设置,那么返回nil
func GetCtx(ctx context.Context) *Context {
- value := ctx.Value(consts.ContextTCPKey)
+ value := ctx.Value(ContextKey)
if value == nil {
return nil
}
@@ -33,3 +31,20 @@ func GetCtx(ctx context.Context) *Context {
}
return nil
}
+
+// ConnFromCtx retrieves and returns the Conn object from context.
+func ConnFromCtx(ctx context.Context) *Conn {
+ user := GetCtx(ctx)
+ if user == nil {
+ return nil
+ }
+ return user.Conn
+}
+
+// SetCtxTraceID 将自定义跟踪ID注入上下文以进行传播
+func SetCtxTraceID(ctx context.Context, traceID string) (context.Context, error) {
+ if len(traceID) > 0 {
+ return gtrace.WithTraceID(ctx, traceID)
+ }
+ return ctx, nil
+}
diff --git a/server/internal/library/network/tcp/model.go b/server/internal/library/network/tcp/model.go
deleted file mode 100644
index 1e3ca59..0000000
--- a/server/internal/library/network/tcp/model.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Package tcp
-// @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 tcp
-
-import (
- "github.com/gogf/gf/v2/net/gtcp"
- "github.com/gogf/gf/v2/os/gtime"
-)
-
-// AuthMeta 认证元数据
-type AuthMeta struct {
- Group string `json:"group"`
- Name string `json:"name"`
- AppId string `json:"appId"`
- SecretKey string `json:"secretKey"`
- EndAt *gtime.Time `json:"-"`
-}
-
-// Context tcp上下文
-type Context struct {
- Conn *gtcp.Conn `json:"conn"`
- Auth *AuthMeta `json:"auth"` // 认证元数据
- TraceID string `json:"traceID"` // 链路ID
-}
-
-// CallbackEvent 回调事件
-type CallbackEvent func()
diff --git a/server/internal/library/network/tcp/msg.go b/server/internal/library/network/tcp/msg.go
new file mode 100644
index 0000000..5a108ea
--- /dev/null
+++ b/server/internal/library/network/tcp/msg.go
@@ -0,0 +1,84 @@
+// Package tcp
+// @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 tcp
+
+import (
+ "github.com/gogf/gf/v2/errors/gcode"
+ "github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/frame/g"
+)
+
+type ServerRes struct {
+ Code int `json:"code" example:"2000" description:"状态码"`
+ Message string `json:"message,omitempty" example:"操作成功" description:"提示消息"`
+}
+
+// SetCode 设置状态码
+func (i *ServerRes) SetCode(code ...int) {
+ if len(code) > 0 {
+ i.Code = code[0]
+ return
+ }
+
+ // 默认值,转为成功的状态码
+ if i.Code == 0 {
+ i.Code = gcode.CodeOK.Code()
+ }
+}
+
+// SetMessage 设置提示消息
+func (i *ServerRes) SetMessage(msg ...string) {
+ message := "操作成功"
+ if len(msg) > 0 {
+ message = msg[0]
+ return
+ }
+ i.Message = message
+}
+
+// SetError 设置响应中的错误
+func (i *ServerRes) SetError(err error) {
+ if err != nil {
+ i.Code = gerror.Code(err).Code()
+ i.Message = err.Error()
+ }
+ return
+}
+
+// GetError 获取响应中的错误
+func (i *ServerRes) GetError() (err error) {
+ if i.Code != gcode.CodeOK.Code() {
+ if i.Message == "" {
+ i.Message = "操作失败"
+ }
+ err = gerror.NewCode(gcode.New(i.Code, i.Message, ""))
+ }
+ return
+}
+
+// ServerLoginReq 服务登录
+type ServerLoginReq struct {
+ Name string `json:"name" description:"客户端名称"` // 客户端名称,当同一个应用ID有多个客户端时请使用不同的名称区分。比如cron1,cron2
+ Extra g.Map `json:"extra" description:"自定义数据"` // 自定义数据,可以传递一些额外的自定义数据
+ Group string `json:"group" description:"分组"`
+ AppId string `json:"appID" description:"应用ID"`
+ Timestamp int64 `json:"timestamp" description:"服务器时间戳"`
+ Sign string `json:"sign" description:"签名"`
+}
+
+// ServerLoginRes 响应服务登录
+type ServerLoginRes struct {
+ ServerRes
+}
+
+// ServerHeartbeatReq 心跳
+type ServerHeartbeatReq struct {
+}
+
+// ServerHeartbeatRes 响应心跳
+type ServerHeartbeatRes struct {
+ ServerRes
+}
diff --git a/server/internal/library/network/tcp/msg_parser.go b/server/internal/library/network/tcp/msg_parser.go
new file mode 100644
index 0000000..fc930ca
--- /dev/null
+++ b/server/internal/library/network/tcp/msg_parser.go
@@ -0,0 +1,222 @@
+// Package tcp
+// @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 tcp
+
+import (
+ "context"
+ "encoding/json"
+ "github.com/gogf/gf/v2/encoding/gjson"
+ "github.com/gogf/gf/v2/errors/gcode"
+ "github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/os/gctx"
+ "github.com/gogf/gf/v2/util/gconv"
+ "github.com/gogf/gf/v2/util/gutil"
+ "reflect"
+ "sync"
+)
+
+// MsgParser 消息处理器
+type MsgParser struct {
+ mutex sync.Mutex // 路由锁
+ task RoutineTask // 投递协程任务
+ rpc *RPC // rpc
+ routers map[string]*RouteHandler // 已注册的路由
+ interceptors []Interceptor // 拦截器
+}
+
+// RoutineTask 投递协程任务
+type RoutineTask func(ctx context.Context, task func())
+
+// Interceptor 拦截器
+type Interceptor func(ctx context.Context, msg *Message) (err error)
+
+// Message 标准消息
+type Message struct {
+ Router string `json:"router"` // 路由
+ TraceId string `json:"traceId"` // 链路ID
+ Data interface{} `json:"data"` // 数据
+ MsgId string `json:"msgId,omitempty"` // 消息ID,rpc用
+ Error string `json:"error,omitempty"` // 消息错误,rpc用
+}
+
+// NewMsgParser 初始化消息处理器
+func NewMsgParser(task RoutineTask) *MsgParser {
+ m := new(MsgParser)
+ m.task = task
+ m.routers = make(map[string]*RouteHandler)
+ m.rpc = NewRPC(task)
+ return m
+}
+
+// RegisterRouter 注册路由
+func (m *MsgParser) RegisterRouter(routers ...interface{}) (err error) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+
+ for _, router := range routers {
+ info, err := ParseRouteHandler(router, false)
+ if err != nil {
+ return err
+ }
+ if _, ok := m.routers[info.Id]; ok {
+ return gerror.Newf("server router duplicate registration:%v", info.Id)
+ }
+ m.routers[info.Id] = info
+ }
+ return
+}
+
+// RegisterRPCRouter 注册rpc路由
+func (m *MsgParser) RegisterRPCRouter(routers ...interface{}) (err error) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+
+ for _, router := range routers {
+ info, err := ParseRouteHandler(router, true)
+ if err != nil {
+ return err
+ }
+ if _, ok := m.routers[info.Id]; ok {
+ return gerror.Newf("server rpc router duplicate registration:%v", info.Id)
+ }
+ m.routers[info.Id] = info
+ }
+ return
+}
+
+// RegisterInterceptor 注册拦截器
+func (m *MsgParser) RegisterInterceptor(interceptors ...Interceptor) {
+ m.interceptors = append(interceptors, interceptors...)
+ return
+}
+
+// Encoding 消息编码
+func (m *MsgParser) Encoding(data []byte) (*Message, error) {
+ var msg Message
+ if err := gconv.Scan(data, &msg); err != nil {
+ return nil, gerror.Newf("invalid package struct: %s", err.Error())
+ }
+ if msg.Router == "" {
+ return nil, gerror.Newf("message is not router: %+v", msg)
+ }
+ return &msg, nil
+}
+
+// Decoding 消息解码
+func (m *MsgParser) Decoding(ctx context.Context, data interface{}, msgId string) ([]byte, error) {
+ message, err := m.doDecoding(ctx, data, msgId)
+ if err != nil {
+ return nil, err
+ }
+ return json.Marshal(message)
+}
+
+// Decoding 消息解码
+func (m *MsgParser) doDecoding(ctx context.Context, data interface{}, msgId string) (*Message, error) {
+ msgType := reflect.TypeOf(data)
+ if msgType == nil || msgType.Kind() != reflect.Ptr {
+ return nil, gerror.Newf("json message pointer required: %+v", data)
+ }
+
+ message := &Message{Router: msgType.Elem().Name(), TraceId: gctx.CtxId(ctx), MsgId: msgId, Data: data}
+ return message, nil
+}
+
+// handleRouterMsg 处理路由消息
+func (m *MsgParser) handleRouterMsg(ctx context.Context, msg *Message) error {
+ // rpc消息
+ if m.rpc.Response(ctx, msg) {
+ return nil
+ }
+
+ handler, ok := m.routers[msg.Router]
+ if !ok {
+ return gerror.NewCodef(gcode.CodeInternalError, "invalid message: %+v, or the router is not registered.", msg)
+ }
+ return m.doHandleRouterMsg(ctx, handler, msg)
+}
+
+// doHandleRouterMsg 处理路由消息
+func (m *MsgParser) doHandleRouterMsg(ctx context.Context, handler *RouteHandler, msg *Message) (err error) {
+ var input = gutil.Copy(handler.Input.Interface())
+ if err = gjson.New(msg.Data).Scan(input); err != nil {
+ return gerror.NewCodef(
+ gcode.CodeInvalidParameter,
+ "router scan failed:%v to parse message:%v",
+ err, handler.Id)
+ }
+
+ args := []reflect.Value{reflect.ValueOf(ctx), reflect.ValueOf(input)}
+
+ m.task(ctx, func() {
+ results := handler.Func.Call(args)
+ if handler.IsRPC {
+ switch len(results) {
+ case 2:
+ var responseErr error
+ if !results[1].IsNil() {
+ if err, ok := results[1].Interface().(error); ok {
+ responseErr = err
+ }
+ }
+
+ responseMsg, deErr := m.doDecoding(ctx, results[0].Interface(), msg.MsgId)
+ if deErr != nil && responseErr == nil {
+ responseErr = deErr
+ return
+ }
+
+ if responseErr != nil {
+ responseMsg.Error = responseErr.Error()
+ }
+
+ b, err := json.Marshal(responseMsg)
+ if err != nil {
+ return
+ }
+
+ user := GetCtx(ctx)
+ user.Conn.Write(b)
+ }
+ return
+ }
+ })
+ return
+}
+
+// handleInterceptor 处理拦截器
+func (m *MsgParser) handleInterceptor(ctx context.Context, msg *Message) (interceptErr error) {
+ for _, f := range m.interceptors {
+ if interceptErr = f(ctx, msg); interceptErr != nil {
+ break
+ }
+ }
+
+ if interceptErr == nil {
+ return
+ }
+
+ handler, ok := m.routers[msg.Router]
+ if !ok {
+ return
+ }
+
+ if handler.IsRPC {
+ var output = gutil.Copy(handler.Output.Interface())
+ response, doerr := m.doDecoding(ctx, output, msg.MsgId)
+ if doerr != nil {
+ return doerr
+ }
+
+ response.Error = interceptErr.Error()
+ b, err := json.Marshal(response)
+ if err != nil {
+ return err
+ }
+ ConnFromCtx(ctx).Write(b)
+ }
+ return
+}
diff --git a/server/internal/library/network/tcp/response.go b/server/internal/library/network/tcp/response.go
deleted file mode 100644
index f1584d2..0000000
--- a/server/internal/library/network/tcp/response.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Package tcp
-// @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 tcp
-
-type Response interface {
- PkgResponse()
- GetError() (err error)
-}
-
-// PkgResponse 打包响应消息
-func PkgResponse(data interface{}) {
- if c, ok := data.(Response); ok {
- c.PkgResponse()
- return
- }
-}
-
-// GetResponseError 解析响应消息中的错误
-func GetResponseError(data interface{}) (err error) {
- if c, ok := data.(Response); ok {
- return c.GetError()
- }
- return
-}
diff --git a/server/internal/library/network/tcp/router.go b/server/internal/library/network/tcp/router.go
index a5ce3c8..c25b97d 100644
--- a/server/internal/library/network/tcp/router.go
+++ b/server/internal/library/network/tcp/router.go
@@ -7,56 +7,88 @@ package tcp
import (
"context"
- "encoding/json"
+ "github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/net/gtcp"
- "github.com/gogf/gf/v2/util/gconv"
+ "github.com/gogf/gf/v2/text/gstr"
+ "reflect"
+ "runtime"
)
-// RouterHandler 路由消息处理器
-type RouterHandler func(ctx context.Context, args ...interface{})
-
-// Message 路由消息
-type Message struct {
- Router string `json:"router"`
- Data interface{} `json:"data"`
+// RouteHandler 路由处理器
+type RouteHandler struct {
+ Id string // 路由ID
+ IsRPC bool // 是否支持rpc协议
+ Func reflect.Value // 路由处理方法
+ Input reflect.Value // 输入参数
+ Output reflect.Value // 输出参数
}
-// SendPkg 打包发送的数据包
-func SendPkg(conn *gtcp.Conn, message *Message) error {
- b, err := json.Marshal(message)
- if err != nil {
- return err
+// ParseRouteHandler 解析路由
+func ParseRouteHandler(router interface{}, isRPC bool) (info *RouteHandler, err error) {
+ funcName := runtime.FuncForPC(reflect.ValueOf(router).Pointer()).Name()
+ funcType := reflect.ValueOf(router).Type()
+
+ if funcType.NumIn() != 2 {
+ err = gerror.Newf(ParseRouterErrInvalidParams, funcName)
+ return
}
- return conn.SendPkg(b)
-}
-// RecvPkg 解包
-func RecvPkg(conn *gtcp.Conn) (*Message, error) {
- if data, err := conn.RecvPkg(); err != nil {
- return nil, err
- } else {
- var msg = new(Message)
- if err = gconv.Scan(data, &msg); err != nil {
- return nil, gerror.Newf("invalid package structure: %s", err.Error())
- }
- if msg.Router == "" {
- return nil, gerror.Newf("message is not routed: %+v", msg)
- }
- return msg, err
+ if funcType.In(0) != reflect.TypeOf((*context.Context)(nil)).Elem() {
+ err = gerror.Newf(ParseRouterErrInvalidFirstParam, funcName)
+ return
}
-}
-// MsgPkg 打包消息
-func MsgPkg(data interface{}, auth *AuthMeta, traceID string) string {
- // 打包签名
- msg := PkgSign(data, auth.AppId, auth.SecretKey, traceID)
-
- // 打包响应消息
- PkgResponse(data)
-
- if msg == nil {
- return ""
+ inputType := funcType.In(1)
+ if !(inputType.Kind() == reflect.Ptr && inputType.Elem().Kind() == reflect.Struct) {
+ err = gerror.Newf(ParseRouterErrInvalidSecondParam, funcName)
+ return
}
- return msg.TraceID
+
+ // The request struct should be named as `xxxReq`.
+ if !gstr.HasSuffix(inputType.String(), `Req`) && !gstr.HasSuffix(inputType.String(), `Res`) {
+ err = gerror.NewCodef(
+ gcode.CodeInvalidParameter,
+ `invalid struct naming of the request: defined as "%s", but should be named with the "Req" or "Res" suffix, such as "XxxReq" or "XxxRes"`,
+ inputType.String(),
+ )
+ return
+ }
+
+ info = &RouteHandler{
+ Id: gstr.SubStrFromREx(inputType.String(), `.`),
+ IsRPC: isRPC,
+ Func: reflect.ValueOf(router),
+ Input: reflect.New(inputType.Elem()),
+ }
+
+ if !isRPC {
+ return
+ }
+
+ if funcType.NumOut() != 2 {
+ err = gerror.Newf(ParseRouterRPCErrInvalidParams, funcName)
+ return
+ }
+ outputType := funcType.Out(0)
+ // The response struct should be named as `xxxRes`.
+ if !gstr.HasSuffix(outputType.String(), `Res`) {
+ err = gerror.NewCodef(
+ gcode.CodeInvalidParameter,
+ `invalid struct naming for response: defined as "%s", but it should be named with "Res" suffix like "XxxRes"`,
+ outputType.String(),
+ )
+ return
+ }
+
+ if !funcType.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) {
+ err = gerror.NewCodef(
+ gcode.CodeInvalidParameter,
+ `invalid handler: defined as "%s", but the last output parameter should be type of "error"`,
+ reflect.TypeOf(funcType).String(),
+ )
+ return
+ }
+
+ info.Output = reflect.New(outputType.Elem())
+ return
}
diff --git a/server/internal/library/network/tcp/rpc.go b/server/internal/library/network/tcp/rpc.go
index 4c6c3f5..2ebd5bf 100644
--- a/server/internal/library/network/tcp/rpc.go
+++ b/server/internal/library/network/tcp/rpc.go
@@ -7,118 +7,95 @@ package tcp
import (
"context"
- "fmt"
+ "github.com/gogf/gf/v2/container/gtype"
"github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/net/gtcp"
- "github.com/gogf/gf/v2/os/glog"
- "github.com/gogf/gf/v2/os/grpool"
- "hotgo/internal/consts"
- "hotgo/utility/simple"
"sync"
"time"
)
-type Rpc struct {
- ctx context.Context
+// RPC .
+type RPC struct {
mutex sync.Mutex
- callbacks map[string]RpcRespFunc
- msgGo *grpool.Pool // 消息处理协程池
- logger *glog.Logger // 日志处理器
+ callbacks map[string]RPCResponseFunc
+ task RoutineTask
}
-// RpcResp 响应结构
-type RpcResp struct {
+// RPCResponse 响应结构
+type RPCResponse struct {
res interface{}
err error
}
-type RpcRespFunc func(resp interface{}, err error)
+type RPCResponseFunc func(resp interface{}, err error)
-// NewRpc 初始化一个rpc协议
-func NewRpc(ctx context.Context, msgGo *grpool.Pool, logger *glog.Logger) *Rpc {
- return &Rpc{
- ctx: ctx,
- callbacks: make(map[string]RpcRespFunc),
- msgGo: msgGo,
- logger: logger,
+// NewRPC 初始化RPC
+func NewRPC(task RoutineTask) *RPC {
+ return &RPC{
+ task: task,
+ callbacks: make(map[string]RPCResponseFunc),
}
}
-// GetCallId 获取回调id
-func (r *Rpc) GetCallId(client *gtcp.Conn, traceID string) string {
- return fmt.Sprintf("%v.%v", client.LocalAddr().String(), traceID)
-}
-
-// HandleMsg 处理rpc消息
-func (r *Rpc) HandleMsg(ctx context.Context, data interface{}) bool {
- user := GetCtx(ctx)
- callId := r.GetCallId(user.Conn, user.TraceID)
-
- if call, ok := r.callbacks[callId]; ok {
- r.mutex.Lock()
- delete(r.callbacks, callId)
- r.mutex.Unlock()
-
- ctx, cancel := context.WithCancel(ctx)
-
- err := r.msgGo.AddWithRecover(ctx, func(ctx context.Context) {
- call(data, nil)
- cancel()
- }, func(ctx context.Context, err error) {
- r.logger.Warningf(ctx, "rpc HandleMsg msgGo exec err:%+v", err)
- cancel()
- })
-
- if err != nil {
- r.logger.Warningf(ctx, "rpc HandleMsg msgGo Add err:%+v", err)
- }
- return true
- }
- return false
-}
-
-// Request 发起rpc请求
-func (r *Rpc) Request(callId string, send func()) (res interface{}, err error) {
- var (
- waitCh = make(chan struct{})
- resCh = make(chan RpcResp, 1)
- isClose = false
- )
+// Request 发起RPC请求
+func (r *RPC) Request(ctx context.Context, msgId string, send func()) (res interface{}, err error) {
+ resCh := make(chan RPCResponse, 1)
+ isClose := gtype.NewBool(false)
defer func() {
- isClose = true
+ isClose.Set(true)
close(resCh)
-
- // 移除消息
- if _, ok := r.callbacks[callId]; ok {
- r.mutex.Lock()
- delete(r.callbacks, callId)
- r.mutex.Unlock()
- }
+ r.popCallback(msgId)
}()
- simple.SafeGo(r.ctx, func(ctx context.Context) {
- close(waitCh)
-
- // 加入回调
- r.mutex.Lock()
- r.callbacks[callId] = func(res interface{}, err error) {
- if !isClose {
- resCh <- RpcResp{res: res, err: err}
- }
+ r.mutex.Lock()
+ r.callbacks[msgId] = func(res interface{}, err error) {
+ if !isClose.Val() {
+ resCh <- RPCResponse{res: res, err: err}
}
- r.mutex.Unlock()
+ }
+ r.mutex.Unlock()
- // 发送消息
- send()
- })
+ r.task(ctx, send)
- <-waitCh
select {
- case <-time.After(time.Second * consts.TCPRpcTimeout):
- err = gerror.New("rpc response timeout")
+ case <-time.After(time.Second * RPCTimeout):
+ err = gerror.New("RPC response timeout")
return
case got := <-resCh:
return got.res, got.err
}
}
+
+// Response RPC消息响应
+func (r *RPC) Response(ctx context.Context, msg *Message) bool {
+ if len(msg.MsgId) == 0 {
+ return false
+ }
+
+ f, ok := r.popCallback(msg.MsgId)
+ if !ok {
+ return false
+ }
+
+ var msgError error
+ if len(msg.Error) > 0 {
+ msgError = gerror.New(msg.Error)
+ }
+
+ r.task(ctx, func() {
+ f(msg.Data, msgError)
+ })
+ return true
+}
+
+// popCallback 弹出回调
+func (r *RPC) popCallback(msgId string) (RPCResponseFunc, bool) {
+ r.mutex.Lock()
+ defer r.mutex.Unlock()
+
+ call, ok := r.callbacks[msgId]
+ if ok {
+ delete(r.callbacks, msgId)
+ }
+ return call, ok
+}
diff --git a/server/internal/library/network/tcp/server.go b/server/internal/library/network/tcp/server.go
index 649c514..05dff22 100644
--- a/server/internal/library/network/tcp/server.go
+++ b/server/internal/library/network/tcp/server.go
@@ -7,24 +7,30 @@ package tcp
import (
"context"
+ "github.com/gogf/gf/v2/container/gtype"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/gtcp"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/grpool"
- "hotgo/internal/consts"
"hotgo/utility/simple"
- "reflect"
"sync"
- "time"
)
-// ClientConn 连接到tcp服务器的客户端对象
-type ClientConn struct {
- Conn *gtcp.Conn // 连接对象
- Auth *AuthMeta // 认证元数据
- heartbeat int64 // 心跳
+// Server tcp服务器
+type Server struct {
+ ctx context.Context // 上下文
+ name string // 服务器名称
+ addr string // 服务器地址
+ ln *gtcp.Server // tcp服务器
+ logger *glog.Logger // 日志处理器
+ wgLn sync.WaitGroup // 流程控制,让tcp服务器按可控流程启动退出
+ closeFlag *gtype.Bool // 服务关闭标签
+ clients map[string]*Conn // 已登录的认证客户端
+ mutexConns sync.Mutex // 连接锁,主要用于客户端上下线
+ taskGo *grpool.Pool // 任务协程池
+ msgParser *MsgParser // 消息处理器
}
// ServerConfig tcp服务器配置
@@ -33,182 +39,121 @@ type ServerConfig struct {
Addr string // 监听地址
}
-// Server tcp服务器对象结构
-type Server struct {
- Ctx context.Context // 上下文
- Logger *glog.Logger // 日志处理器
- addr string // 连接地址
- name string // 服务器名称
- rpc *Rpc // rpc协议
- ln *gtcp.Server // tcp服务器
- wgLn sync.WaitGroup // 状态控制,主要用于tcp服务器能够按流程启动退出
- mutex sync.Mutex // 服务器状态锁
- closeFlag bool // 服务关闭标签
- clients map[string]*ClientConn // 已登录的认证客户端
- mutexConns sync.Mutex // 连接锁,主要用于客户端上下线
- msgGo *grpool.Pool // 消息处理协程池
- cronRouters map[string]RouterHandler // 定时任务路由
- queueRouters map[string]RouterHandler // 队列路由
- authRouters map[string]RouterHandler // 任务路由
-}
-
// NewServer 初始一个tcp服务器对象
-func NewServer(config *ServerConfig) (server *Server, err error) {
+func NewServer(config *ServerConfig) (server *Server) {
+ server = new(Server)
+ server.ctx = gctx.New()
+ server.logger = g.Log("tcpServer")
+
+ baseErr := gerror.New("TCPServer start fail")
if config == nil {
- err = gerror.New("config is nil")
+ server.logger.Fatal(server.ctx, gerror.Wrap(baseErr, "config is nil"))
return
}
if config.Addr == "" {
- err = gerror.New("server address is not set")
+ server.logger.Fatal(server.ctx, gerror.Wrap(baseErr, "server address is not set"))
return
}
- server = new(Server)
- server.Ctx = gctx.New()
-
if config.Name == "" {
- config.Name = simple.AppName(server.Ctx)
+ config.Name = simple.AppName(server.ctx)
}
server.addr = config.Addr
server.name = config.Name
server.ln = gtcp.NewServer(server.addr, server.accept, config.Name)
- server.clients = make(map[string]*ClientConn)
- server.closeFlag = false
- server.Logger = g.Log("tcpServer")
- server.msgGo = grpool.New(20)
- server.rpc = NewRpc(server.Ctx, server.msgGo, server.Logger)
+ server.closeFlag = gtype.NewBool(false)
+ server.clients = make(map[string]*Conn)
+ server.taskGo = grpool.New(20)
+ server.msgParser = NewMsgParser(server.handleRoutineTask)
+
server.startCron()
return
}
// accept
func (server *Server) accept(conn *gtcp.Conn) {
- defer func() {
- server.mutexConns.Lock()
- _ = conn.Close()
- // 从登录列表中移除
- delete(server.clients, conn.RemoteAddr().String())
- server.mutexConns.Unlock()
+ tcpConn := NewConn(conn, server.logger, server.msgParser)
+ server.AddClient(tcpConn)
+ go func() {
+ if err := tcpConn.Run(); err != nil {
+ server.logger.Info(server.ctx, err)
+ }
+
+ // cleanup
+ tcpConn.Close()
+ server.RemoveClient(tcpConn)
}()
+}
- for {
- msg, err := RecvPkg(conn)
- if err != nil {
- server.Logger.Debugf(server.Ctx, "RecvPkg err:%+v, client closed.", err)
- break
- }
-
- client := server.getLoginConn(conn)
-
- switch msg.Router {
- case "ServerLogin": // 服务登录
- // 初始化上下文
- ctx := initCtx(gctx.New(), &Context{
- Conn: conn,
- })
- server.doHandleRouterMsg(ctx, server.onServerLogin, msg.Data)
- case "ServerHeartbeat": // 心跳
- if client == nil {
- server.Logger.Infof(server.Ctx, "conn not connected, ignore the heartbeat, msg:%+v", msg)
- continue
- }
- // 初始化上下文
- ctx := initCtx(gctx.New(), &Context{})
- server.doHandleRouterMsg(ctx, server.onServerHeartbeat, msg.Data, client)
- default: // 通用路由消息处理
- if client == nil {
- server.Logger.Warningf(server.Ctx, "conn is not logged in but sends a routing message. actively conn disconnect, msg:%+v", msg)
- time.Sleep(time.Second)
- conn.Close()
- return
- }
- server.handleRouterMsg(msg, client)
- }
+// RemoveClient 移除客户端
+func (server *Server) RemoveClient(conn *Conn) {
+ label := server.ClientLabel(conn.Conn)
+ if _, ok := server.clients[label]; ok {
+ server.mutexConns.Lock()
+ delete(server.clients, label)
+ server.mutexConns.Unlock()
}
}
-// handleRouterMsg 处理路由消息
-func (server *Server) handleRouterMsg(msg *Message, client *ClientConn) {
- // 验证签名
- in, err := VerifySign(msg.Data, client.Auth.AppId, client.Auth.SecretKey)
- if err != nil {
- server.Logger.Warningf(server.Ctx, "handleRouterMsg VerifySign err:%+v message: %+v", err, msg)
- return
- }
-
- // 初始化上下文
- ctx := initCtx(gctx.New(), &Context{
- Conn: client.Conn,
- Auth: client.Auth,
- TraceID: in.TraceID,
- })
-
- // 响应rpc消息
- if server.rpc.HandleMsg(ctx, msg.Data) {
- return
- }
-
- handle := func(routers map[string]RouterHandler, group string) {
- if routers == nil {
- server.Logger.Debugf(server.Ctx, "handleRouterMsg route is not initialized %v message: %+v", group, msg)
- return
- }
- f, ok := routers[msg.Router]
- if !ok {
- server.Logger.Debugf(server.Ctx, "handleRouterMsg invalid %v message: %+v", group, msg)
- return
- }
-
- server.doHandleRouterMsg(ctx, f, msg.Data)
- }
-
- switch client.Auth.Group {
- case consts.TCPClientGroupCron:
- handle(server.cronRouters, client.Auth.Group)
- case consts.TCPClientGroupQueue:
- handle(server.queueRouters, client.Auth.Group)
- case consts.TCPClientGroupAuth:
- handle(server.authRouters, client.Auth.Group)
- default:
- server.Logger.Warningf(server.Ctx, "group is not registered: %+v", client.Auth.Group)
- }
+// AddClient 添加客户端
+func (server *Server) AddClient(conn *Conn) {
+ server.mutexConns.Lock()
+ server.clients[server.ClientLabel(conn.Conn)] = conn
+ server.mutexConns.Unlock()
}
-// doHandleRouterMsg 处理路由消息
-func (server *Server) doHandleRouterMsg(ctx context.Context, fun RouterHandler, args ...interface{}) {
- ctx, cancel := context.WithCancel(ctx)
- err := server.msgGo.AddWithRecover(ctx,
- func(ctx context.Context) {
- fun(ctx, args...)
- cancel()
- },
- func(ctx context.Context, err error) {
- server.Logger.Warningf(ctx, "doHandleRouterMsg msgGo exec err:%+v", err)
- cancel()
- },
- )
-
- if err != nil {
- server.Logger.Warningf(ctx, "doHandleRouterMsg msgGo Add err:%+v", err)
+// AuthClient 认证客户端
+func (server *Server) AuthClient(conn *Conn, auth *AuthMeta) {
+ label := server.ClientLabel(conn.Conn)
+ client, ok := server.clients[label]
+ if !ok {
+ server.logger.Debugf(server.ctx, "authClient client does not exist:%v", label)
return
}
+ client.Auth = auth
}
-// getLoginConn 获取指定已登录的连接
-func (server *Server) getLoginConn(conn *gtcp.Conn) *ClientConn {
- client, ok := server.clients[conn.RemoteAddr().String()]
+// ClientLabel 客户端标识
+func (server *Server) ClientLabel(conn *gtcp.Conn) string {
+ return conn.RemoteAddr().String()
+}
+
+// GetClient 获取指定连接
+func (server *Server) GetClient(conn *gtcp.Conn) *Conn {
+ client, ok := server.clients[server.ClientLabel(conn)]
if !ok {
return nil
}
return client
}
-// getLoginConn 获取指定appid的所有连接
-func (server *Server) getAppIdClients(appid string) (list []*ClientConn) {
+// GetClients 获取所有连接
+func (server *Server) GetClients() map[string]*Conn {
+ return server.clients
+}
+
+// GetClientById 通过连接ID获取连接
+func (server *Server) GetClientById(id int64) *Conn {
+ server.mutexConns.Lock()
+ defer server.mutexConns.Unlock()
+
for _, v := range server.clients {
- if v.Auth.AppId == appid {
+ if v.CID == id {
+ return v
+ }
+ }
+ return nil
+}
+
+// GetAppIdClients 获取指定appid的所有连接
+func (server *Server) GetAppIdClients(appid string) (list []*Conn) {
+ server.mutexConns.Lock()
+ defer server.mutexConns.Unlock()
+
+ for _, v := range server.clients {
+ if v.Auth != nil && v.Auth.AppId == appid {
list = append(list, v)
}
}
@@ -216,70 +161,63 @@ func (server *Server) getAppIdClients(appid string) (list []*ClientConn) {
}
// GetGroupClients 获取指定分组的所有连接
-func (server *Server) GetGroupClients(group string) (list []*ClientConn) {
+func (server *Server) GetGroupClients(group string) (list []*Conn) {
+ server.mutexConns.Lock()
+ defer server.mutexConns.Unlock()
+
for _, v := range server.clients {
- if v.Auth.Group == group {
+ if v.Auth != nil && v.Auth.Group == group {
list = append(list, v)
}
}
return
}
-// RegisterAuthRouter 注册授权路由
-func (server *Server) RegisterAuthRouter(routers map[string]RouterHandler) {
- server.mutex.Lock()
- defer server.mutex.Unlock()
-
- if server.authRouters == nil {
- server.authRouters = make(map[string]RouterHandler)
- }
-
- for i, router := range routers {
- _, ok := server.authRouters[i]
- if ok {
- server.Logger.Debugf(server.Ctx, "server authRouters duplicate registration:%v", i)
- continue
- }
- server.authRouters[i] = router
- }
+// GetAppIdOnline 获取指定appid的在线数量
+func (server *Server) GetAppIdOnline(appid string) int {
+ return len(server.GetAppIdClients(appid))
}
-// RegisterCronRouter 注册任务路由
-func (server *Server) RegisterCronRouter(routers map[string]RouterHandler) {
- server.mutex.Lock()
- defer server.mutex.Unlock()
-
- if server.cronRouters == nil {
- server.cronRouters = make(map[string]RouterHandler)
- }
-
- for i, router := range routers {
- _, ok := server.cronRouters[i]
- if ok {
- server.Logger.Debugf(server.Ctx, "server cronRouters duplicate registration:%v", i)
- continue
- }
- server.cronRouters[i] = router
- }
+// GetAllOnline 获取所有在线数量
+func (server *Server) GetAllOnline() int {
+ return len(server.clients)
}
-// RegisterQueueRouter 注册队列路由
-func (server *Server) RegisterQueueRouter(routers map[string]RouterHandler) {
- server.mutex.Lock()
- defer server.mutex.Unlock()
+// GetAuthOnline 获取所有已登录认证在线数量
+func (server *Server) GetAuthOnline() int {
+ server.mutexConns.Lock()
+ defer server.mutexConns.Unlock()
- if server.queueRouters == nil {
- server.queueRouters = make(map[string]RouterHandler)
- }
-
- for i, router := range routers {
- _, ok := server.queueRouters[i]
- if ok {
- server.Logger.Debugf(server.Ctx, "server queueRouters duplicate registration:%v", i)
- continue
+ online := 0
+ for _, v := range server.clients {
+ if v.Auth != nil {
+ online++
}
- server.queueRouters[i] = router
}
+ return online
+}
+
+// RegisterRouter 注册路由
+func (server *Server) RegisterRouter(routers ...interface{}) {
+ err := server.msgParser.RegisterRouter(routers...)
+ if err != nil {
+ server.logger.Fatal(server.ctx, err)
+ }
+ return
+}
+
+// RegisterRPCRouter 注册RPC路由
+func (server *Server) RegisterRPCRouter(routers ...interface{}) {
+ err := server.msgParser.RegisterRPCRouter(routers...)
+ if err != nil {
+ server.logger.Fatal(server.ctx, err)
+ }
+ return
+}
+
+// RegisterInterceptor 注册拦截器
+func (server *Server) RegisterInterceptor(interceptors ...Interceptor) {
+ server.msgParser.RegisterInterceptor(interceptors...)
}
// Listen 监听服务
@@ -291,77 +229,68 @@ func (server *Server) Listen() (err error) {
// Close 关闭服务
func (server *Server) Close() {
- if server.closeFlag {
+ if server.closeFlag.Val() {
return
}
- server.closeFlag = true
+ server.closeFlag.Set(true)
server.stopCron()
server.mutexConns.Lock()
for _, client := range server.clients {
- _ = client.Conn.Close()
+ client.Conn.Close()
}
server.clients = nil
server.mutexConns.Unlock()
if server.ln != nil {
- _ = server.ln.Close()
+ server.ln.Close()
}
server.wgLn.Wait()
}
// IsClose 服务是否关闭
func (server *Server) IsClose() bool {
- return server.closeFlag
+ return server.closeFlag.Val()
}
-// Write 向指定客户端发送消息
-func (server *Server) Write(conn *gtcp.Conn, data interface{}) (err error) {
- if server.closeFlag {
- return gerror.New("service is down")
- }
-
- msgType := reflect.TypeOf(data)
- if msgType == nil || msgType.Kind() != reflect.Ptr {
- return gerror.Newf("json message pointer required: %+v", data)
- }
-
- msg := &Message{Router: msgType.Elem().Name(), Data: data}
-
- return SendPkg(conn, msg)
-}
-
-// Send 发送消息
-func (server *Server) Send(ctx context.Context, client *ClientConn, data interface{}) (err error) {
- MsgPkg(data, client.Auth, gctx.CtxId(ctx))
- return server.Write(client.Conn, data)
-}
-
-// Reply 回复消息
-func (server *Server) Reply(ctx context.Context, data interface{}) (err error) {
- user := GetCtx(ctx)
- if user == nil {
- err = gerror.New("获取回复用户信息失败")
- return
- }
- MsgPkg(data, user.Auth, user.TraceID)
- return server.Write(user.Conn, data)
-}
-
-// RpcRequest 向指定客户端发送消息并等待响应结果
-func (server *Server) RpcRequest(ctx context.Context, client *ClientConn, data interface{}) (res interface{}, err error) {
- var (
- traceID = MsgPkg(data, client.Auth, gctx.CtxId(ctx))
- key = server.rpc.GetCallId(client.Conn, traceID)
+// handleRoutineTask 处理协程任务
+func (server *Server) handleRoutineTask(ctx context.Context, task func()) {
+ ctx, cancel := context.WithCancel(ctx)
+ err := server.taskGo.AddWithRecover(ctx,
+ func(ctx context.Context) {
+ task()
+ cancel()
+ },
+ func(ctx context.Context, err error) {
+ server.logger.Warningf(ctx, "routineTask exec err:%+v", err)
+ cancel()
+ },
)
- if traceID == "" {
- err = gerror.New("traceID is required")
+ if err != nil {
+ server.logger.Warningf(ctx, "routineTask add err:%+v", err)
+ }
+}
+
+// GetRoutes 获取所有路由
+func (server *Server) GetRoutes() (routes []RouteHandler) {
+ if server.msgParser.routers == nil {
return
}
- return server.rpc.Request(key, func() {
- _ = server.Write(client.Conn, data)
- })
+ for _, v := range server.msgParser.routers {
+ routes = append(routes, *v)
+ }
+ return
+}
+
+// Request 向指定客户端发送消息并等待响应结果
+func (server *Server) Request(ctx context.Context, client *Conn, data interface{}) (interface{}, error) {
+ return client.Request(ctx, data)
+}
+
+// RequestScan 向指定客户端发送消息并等待响应结果,将结果保存在response中
+func (server *Server) RequestScan(ctx context.Context, client *Conn, data, response interface{}) error {
+ return client.RequestScan(ctx, data, response)
}
diff --git a/server/internal/library/network/tcp/server_cron.go b/server/internal/library/network/tcp/server_cron.go
index 46ce808..25ccbfa 100644
--- a/server/internal/library/network/tcp/server_cron.go
+++ b/server/internal/library/network/tcp/server_cron.go
@@ -10,7 +10,6 @@ import (
"fmt"
"github.com/gogf/gf/v2/os/gcron"
"github.com/gogf/gf/v2/os/gtime"
- "hotgo/internal/consts"
)
// getCronKey 生成服务端定时任务名称
@@ -28,32 +27,35 @@ func (server *Server) stopCron() {
// startCron 启动定时任务
func (server *Server) startCron() {
// 心跳超时检查
- if gcron.Search(server.getCronKey(consts.TCPCronHeartbeatVerify)) == nil {
- _, _ = gcron.AddSingleton(server.Ctx, "@every 300s", func(ctx context.Context) {
- if server.clients == nil {
+ if gcron.Search(server.getCronKey(CronHeartbeatVerify)) == nil {
+ gcron.AddSingleton(server.ctx, "@every 300s", func(ctx context.Context) {
+ if server == nil || server.clients == nil {
return
}
for _, client := range server.clients {
- if client.heartbeat < gtime.Timestamp()-consts.TCPHeartbeatTimeout {
- _ = client.Conn.Close()
- server.Logger.Debugf(server.Ctx, "client heartbeat timeout, close conn. auth:%+v", client.Auth)
+ if client.Heartbeat < gtime.Timestamp()-HeartbeatTimeout {
+ client.Conn.Close()
+ server.logger.Debugf(server.ctx, "client heartbeat timeout, close conn. auth:%+v", client.Auth)
}
}
- }, server.getCronKey(consts.TCPCronHeartbeatVerify))
+ }, server.getCronKey(CronHeartbeatVerify))
}
// 认证检查
- if gcron.Search(server.getCronKey(consts.TCPCronAuthVerify)) == nil {
- _, _ = gcron.AddSingleton(server.Ctx, "@every 300s", func(ctx context.Context) {
- if server.clients == nil {
+ if gcron.Search(server.getCronKey(CronAuthVerify)) == nil {
+ gcron.AddSingleton(server.ctx, "@every 300s", func(ctx context.Context) {
+ if server == nil || server.clients == nil {
return
}
for _, client := range server.clients {
+ if client.Auth == nil {
+ continue
+ }
if client.Auth.EndAt.Before(gtime.Now()) {
- _ = client.Conn.Close()
- server.Logger.Debugf(server.Ctx, "client auth expired, close conn. auth:%+v", client.Auth)
+ client.Conn.Close()
+ server.logger.Debugf(server.ctx, "client auth expired, close conn. auth:%+v", client.Auth)
}
}
- }, server.getCronKey(consts.TCPCronAuthVerify))
+ }, server.getCronKey(CronAuthVerify))
}
}
diff --git a/server/internal/library/network/tcp/server_handle.go b/server/internal/library/network/tcp/server_handle.go
deleted file mode 100644
index b86d7df..0000000
--- a/server/internal/library/network/tcp/server_handle.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Package tcp
-// @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 tcp
-
-import (
- "context"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/os/gtime"
- "github.com/gogf/gf/v2/text/gstr"
- "github.com/gogf/gf/v2/util/gconv"
- "hotgo/internal/consts"
- "hotgo/internal/model/entity"
- "hotgo/internal/model/input/msgin"
- "hotgo/utility/convert"
-)
-
-// onServerLogin 处理客户端登录
-func (server *Server) onServerLogin(ctx context.Context, args ...interface{}) {
- var (
- in = new(msgin.ServerLogin)
- user = GetCtx(ctx)
- res = new(msgin.ResponseServerLogin)
- models *entity.SysServeLicense
- )
-
- if err := gconv.Scan(args[0], &in); err != nil {
- server.Logger.Warningf(ctx, "onServerLogin message Scan failed:%+v, args:%+v", err, args)
- return
- }
-
- err := g.Model("sys_serve_license").Ctx(ctx).
- Where("appid = ?", in.AppId).
- Scan(&models)
-
- if err != nil {
- res.Code = 1
- res.Message = err.Error()
- _ = server.Write(user.Conn, res)
- return
- }
-
- if models == nil {
- res.Code = 2
- res.Message = "授权信息不存在"
- _ = server.Write(user.Conn, res)
- return
- }
-
- // 验证签名
- if _, err = VerifySign(in, models.Appid, models.SecretKey); err != nil {
- res.Code = 3
- res.Message = "签名错误,请联系管理员"
- _ = server.Write(user.Conn, res)
- return
- }
-
- if models.Status != consts.StatusEnabled {
- res.Code = 4
- res.Message = "授权已禁用,请联系管理员"
- _ = server.Write(user.Conn, res)
- return
- }
-
- if models.Group != in.Group {
- res.Code = 5
- res.Message = "你登录的授权分组未得到授权,请联系管理员"
- _ = server.Write(user.Conn, res)
- return
- }
-
- if models.EndAt.Before(gtime.Now()) {
- res.Code = 6
- res.Message = "授权已过期,请联系管理员"
- _ = server.Write(user.Conn, res)
- return
- }
-
- allowedIps := convert.IpFilterStrategy(models.AllowedIps)
- if _, ok := allowedIps["*"]; !ok {
- ip := gstr.StrTillEx(user.Conn.RemoteAddr().String(), ":")
- if _, ok2 := allowedIps[ip]; !ok2 {
- res.Code = 7
- res.Message = "IP(" + ip + ")未授权,请联系管理员"
- _ = server.Write(user.Conn, res)
- return
- }
- }
-
- // 检查是否存在多地登录,如果连接超出上限,直接将所有已连接断开
- clients := server.getAppIdClients(models.Appid)
- online := len(clients) + 1
- if online > models.OnlineLimit {
- res2 := new(msgin.ResponseServerLogin)
- res2.Code = 8
- res2.Message = "授权登录端超出上限已进行记录。请立即终止操作。如有疑问请联系管理员"
- for _, client := range clients {
- _ = server.Write(client.Conn, res2)
- _ = client.Conn.Close()
- }
-
- // 当前连接也踢掉
- _ = server.Write(user.Conn, res2)
- _ = user.Conn.Close()
- return
- }
-
- server.mutexConns.Lock()
- server.clients[user.Conn.RemoteAddr().String()] = &ClientConn{
- Conn: user.Conn,
- Auth: &AuthMeta{
- Group: in.Group,
- Name: in.Name,
- AppId: in.AppId,
- SecretKey: models.SecretKey,
- EndAt: models.EndAt,
- },
- heartbeat: gtime.Timestamp(),
- }
- server.mutexConns.Unlock()
-
- _, err = g.Model("sys_serve_license").Ctx(ctx).
- Where("id = ?", models.Id).Data(g.Map{
- "online": online,
- "login_times": models.LoginTimes + 1,
- "last_login_at": gtime.Now(),
- "last_active_at": gtime.Now(),
- "remote_addr": user.Conn.RemoteAddr().String(),
- }).Update()
- if err != nil {
- server.Logger.Warningf(ctx, "onServerLogin Update err:%+v", err)
- }
-
- res.AppId = in.AppId
- res.Code = consts.TCPMsgCodeSuccess
- _ = server.Write(user.Conn, res)
-}
-
-// onServerHeartbeat 处理客户端心跳
-func (server *Server) onServerHeartbeat(ctx context.Context, args ...interface{}) {
- var (
- in *msgin.ServerHeartbeat
- res = new(msgin.ResponseServerHeartbeat)
- )
-
- if err := gconv.Scan(args[0], &in); err != nil {
- server.Logger.Warningf(ctx, "onServerHeartbeat message Scan failed:%+v, args:%+v", err, args)
- return
- }
-
- client := args[1].(*ClientConn)
- client.heartbeat = gtime.Timestamp()
-
- _, err := g.Model("sys_serve_license").Ctx(ctx).
- Where("appid = ?", client.Auth.AppId).Data(g.Map{
- "last_active_at": gtime.Now(),
- }).Update()
- if err != nil {
- server.Logger.Warningf(ctx, "onServerHeartbeat Update err:%+v", err)
- }
-
- res.Code = consts.TCPMsgCodeSuccess
- _ = server.Write(client.Conn, res)
-}
diff --git a/server/internal/library/network/tcp/sign.go b/server/internal/library/network/tcp/sign.go
deleted file mode 100644
index db4bae6..0000000
--- a/server/internal/library/network/tcp/sign.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Package tcp
-// @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 tcp
-
-import (
- "github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/util/gconv"
- "hotgo/internal/model/input/msgin"
-)
-
-type Sign interface {
- SetSign(appId, secretKey string) *msgin.RpcMsg
- SetTraceID(traceID string)
-}
-
-// PkgSign 打包签名
-func PkgSign(data interface{}, appId, secretKey, traceID string) *msgin.RpcMsg {
- if c, ok := data.(Sign); ok {
- c.SetTraceID(traceID)
- return c.SetSign(appId, secretKey)
- }
- return nil
-}
-
-// VerifySign 验证签名
-func VerifySign(data interface{}, appId, secretKey string) (in *msgin.RpcMsg, err error) {
- // 无密钥,无需签名
- if secretKey == "" {
- return
- }
-
- if err = gconv.Scan(data, &in); err != nil {
- return
- }
-
- if appId != in.AppId {
- err = gerror.New("appId invalid")
- return
- }
-
- if in.Sign != in.GetSign(secretKey) {
- err = gerror.New("sign invalid")
- return
- }
- return
-}
diff --git a/server/internal/library/network/tcp/tcp_example_test.go b/server/internal/library/network/tcp/tcp_example_test.go
new file mode 100644
index 0000000..5484f3d
--- /dev/null
+++ b/server/internal/library/network/tcp/tcp_example_test.go
@@ -0,0 +1,128 @@
+package tcp_test
+
+import (
+ "context"
+ "fmt"
+ "github.com/gogf/gf/v2/os/gctx"
+ "github.com/gogf/gf/v2/test/gtest"
+ "hotgo/internal/library/network/tcp"
+ "testing"
+ "time"
+)
+
+var T *testing.T // 声明一个全局的 *testing.T 变量
+
+type TestMsgReq struct {
+ Name string `json:"name"`
+}
+
+type TestMsgRes struct {
+ tcp.ServerRes
+}
+
+type TestRPCMsgReq struct {
+ Name string `json:"name"`
+}
+
+type TestRPCMsgRes struct {
+ tcp.ServerRes
+}
+
+func onTestMsg(ctx context.Context, req *TestMsgReq) {
+ fmt.Printf("服务器收到消息 ==> onTestMsg:%+v\n", req)
+ conn := tcp.ConnFromCtx(ctx)
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNE(conn, nil)
+ })
+
+ res := new(TestMsgRes)
+ res.Message = fmt.Sprintf("你的名字:%v", req.Name)
+ conn.Send(ctx, res)
+}
+
+func onResponseTestMsg(ctx context.Context, req *TestMsgRes) {
+ fmt.Printf("客户端收到响应消息 ==> TestMsgRes:%+v\n", req)
+ err := req.GetError()
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+}
+
+func onTestRPCMsg(ctx context.Context, req *TestRPCMsgReq) (res *TestRPCMsgRes, err error) {
+ fmt.Printf("服务器收到消息 ==> onTestRPCMsg:%+v\n", req)
+ res = new(TestRPCMsgRes)
+ res.Message = fmt.Sprintf("你的名字:%v", req.Name)
+ return
+}
+
+func startTCPServer() {
+ serv := tcp.NewServer(&tcp.ServerConfig{
+ Name: "hotgo",
+ Addr: ":8002",
+ })
+
+ // 注册路由
+ serv.RegisterRouter(
+ onTestMsg,
+ )
+
+ // 注册RPC路由
+ serv.RegisterRPCRouter(
+ onTestRPCMsg,
+ )
+
+ // 服务监听
+ err := serv.Listen()
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+}
+
+// 一个基本的消息收发
+func TestSendMsg(t *testing.T) {
+ T = t
+ go startTCPServer()
+
+ ctx := gctx.New()
+ client := tcp.NewClient(&tcp.ClientConfig{
+ Addr: "127.0.0.1:8002",
+ })
+
+ // 注册路由
+ client.RegisterRouter(
+ onResponseTestMsg,
+ )
+
+ go func() {
+ err := client.Start()
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+ }()
+
+ // 确保服务都启动完成
+ time.Sleep(time.Second * 1)
+
+ // 拿到客户端的连接
+ conn := client.Conn()
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNE(conn, nil)
+ })
+
+ // 向服务器发送tcp消息,不会阻塞程序执行
+ err := conn.Send(ctx, &TestMsgReq{Name: "Tom"})
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+
+ // 向服务器发送rpc消息,会等待服务器响应结果,直到拿到结果或响应超时才会继续
+ var res TestRPCMsgRes
+ if err = conn.RequestScan(ctx, &TestRPCMsgReq{Name: "Tony"}, &res); err != nil {
+ gtest.C(T, func(t *gtest.T) {
+ t.AssertNil(err)
+ })
+ }
+
+ fmt.Printf("客户端收到RPC消息响应 ==> TestRPCMsgRes:%+v\n", res)
+ time.Sleep(time.Second * 1)
+}
diff --git a/server/internal/library/payment/notifycall.go b/server/internal/library/payment/notifycall.go
index fdc34bb..975ce87 100644
--- a/server/internal/library/payment/notifycall.go
+++ b/server/internal/library/payment/notifycall.go
@@ -12,7 +12,7 @@ import (
// 异步回调
-type NotifyCallFunc func(ctx context.Context, pay payin.NotifyCallFuncInp) (err error)
+type NotifyCallFunc func(ctx context.Context, pay *payin.NotifyCallFuncInp) (err error)
var (
notifyCall = make(map[string]NotifyCallFunc)
@@ -37,7 +37,7 @@ func RegisterNotifyCallMap(calls map[string]NotifyCallFunc) {
}
// NotifyCall 执行订单分组的异步回调
-func NotifyCall(ctx context.Context, in payin.NotifyCallFuncInp) {
+func NotifyCall(ctx context.Context, in *payin.NotifyCallFuncInp) {
f, ok := notifyCall[in.Pay.OrderGroup]
if ok {
ctx = contexts.Detach(ctx)
diff --git a/server/internal/library/sms/aliyun/handle.go b/server/internal/library/sms/aliyun/handle.go
deleted file mode 100644
index 4ffa4d6..0000000
--- a/server/internal/library/sms/aliyun/handle.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package aliyun
-
-import (
- "context"
- "fmt"
- openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
- dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v3/client"
- util "github.com/alibabacloud-go/tea-utils/v2/service"
- "github.com/alibabacloud-go/tea/tea"
- "github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model"
- "hotgo/internal/model/input/sysin"
- "hotgo/internal/service"
-)
-
-var (
- Handle = aliYun{}
-)
-
-type aliYun struct{}
-
-// SendCode 发送验证码
-func (d *aliYun) SendCode(ctx context.Context, in sysin.SendCodeInp, config *model.SmsConfig) (err error) {
- if config == nil {
- config, err = service.SysConfig().GetSms(ctx)
- if err != nil {
- return err
- }
- }
-
- client, err := CreateClient(tea.String(config.AliYunAccessKeyID), tea.String(config.AliYunAccessKeySecret))
- if err != nil {
- return err
- }
-
- sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
- PhoneNumbers: tea.String(in.Mobile),
- SignName: tea.String(config.AliYunSign),
- TemplateCode: tea.String(in.Template),
- TemplateParam: tea.String(fmt.Sprintf("{\"code\":\"%v\"}", in.Code)),
- }
-
- tryErr := func() (_e error) {
- defer func() {
- if r := tea.Recover(recover()); r != nil {
- _e = r
- }
- }()
-
- // 复制代码运行请自行打印 API 的返回值
- response, err := client.SendSmsWithOptions(sendSmsRequest, &util.RuntimeOptions{})
- if err != nil {
- return err
- }
-
- g.Log().Debugf(ctx, "aliyun.sendCode response:%+v", response.GoString())
-
- return nil
- }()
- return tryErr
-}
-
-// CreateClient 使用AK&SK初始化账号Client
-func CreateClient(accessKeyId *string, accessKeySecret *string) (_result *dysmsapi20170525.Client, _err error) {
- config := &openapi.Config{
- // 必填,您的 AccessKey ID
- AccessKeyId: accessKeyId,
- // 必填,您的 AccessKey Secret
- AccessKeySecret: accessKeySecret,
- }
- // 访问的域名
- config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
- _result, _err = dysmsapi20170525.NewClient(config)
- return _result, _err
-}
-
-func TestSend(accessKeyId string, accessKeySecret string) (_err error) {
- // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378661.html
- client, _err := CreateClient(tea.String(accessKeyId), tea.String(accessKeySecret))
- if _err != nil {
- return _err
- }
-
- sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
- PhoneNumbers: tea.String("15303830571"),
- SignName: tea.String("布帆云"),
- TemplateCode: tea.String("SMS_198921686"),
- TemplateParam: tea.String("{\"code\":\"1234\"}"),
- }
- runtime := &util.RuntimeOptions{}
- tryErr := func() (_e error) {
- defer func() {
- if r := tea.Recover(recover()); r != nil {
- _e = r
- }
- }()
- // 复制代码运行请自行打印 API 的返回值
- _, _err = client.SendSmsWithOptions(sendSmsRequest, runtime)
- if _err != nil {
- return _err
- }
-
- return nil
- }()
-
- if tryErr != nil {
- var err = &tea.SDKError{}
- if _t, ok := tryErr.(*tea.SDKError); ok {
- err = _t
- } else {
- err.Message = tea.String(tryErr.Error())
- }
- // 如有需要,请打印 error
- _, _err = util.AssertAsString(err.Message)
- if _err != nil {
- return _err
- }
- }
- return _err
-}
diff --git a/server/internal/library/sms/config.go b/server/internal/library/sms/config.go
new file mode 100644
index 0000000..bd5a958
--- /dev/null
+++ b/server/internal/library/sms/config.go
@@ -0,0 +1,22 @@
+package sms
+
+import (
+ "context"
+ "github.com/gogf/gf/v2/database/gdb"
+ "github.com/gogf/gf/v2/frame/g"
+ "hotgo/internal/model"
+)
+
+var config *model.SmsConfig
+
+func SetConfig(c *model.SmsConfig) {
+ config = c
+}
+
+func GetConfig() *model.SmsConfig {
+ return config
+}
+
+func GetModel(ctx context.Context) *gdb.Model {
+ return g.Model("sys_sms_log").Ctx(ctx)
+}
diff --git a/server/internal/library/sms/sms.go b/server/internal/library/sms/sms.go
index e6274c8..985c532 100644
--- a/server/internal/library/sms/sms.go
+++ b/server/internal/library/sms/sms.go
@@ -4,15 +4,12 @@ import (
"context"
"fmt"
"hotgo/internal/consts"
- "hotgo/internal/library/sms/aliyun"
- "hotgo/internal/library/sms/tencent"
- "hotgo/internal/model"
"hotgo/internal/model/input/sysin"
)
// Drive 短信驱动
type Drive interface {
- SendCode(ctx context.Context, in sysin.SendCodeInp, config *model.SmsConfig) (err error)
+ SendCode(ctx context.Context, in *sysin.SendCodeInp) (err error)
}
func New(name ...string) Drive {
@@ -27,9 +24,9 @@ func New(name ...string) Drive {
switch instanceName {
case consts.SmsDriveAliYun:
- drive = &aliyun.Handle
+ drive = &AliYunDrive{}
case consts.SmsDriveTencent:
- drive = &tencent.Handle
+ drive = &TencentDrive{}
default:
panic(fmt.Sprintf("暂不支持短信驱动:%v", instanceName))
}
diff --git a/server/internal/library/sms/sms_aliyun.go b/server/internal/library/sms/sms_aliyun.go
new file mode 100644
index 0000000..566932b
--- /dev/null
+++ b/server/internal/library/sms/sms_aliyun.go
@@ -0,0 +1,60 @@
+package sms
+
+import (
+ "context"
+ "fmt"
+ openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
+ dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v3/client"
+ util "github.com/alibabacloud-go/tea-utils/v2/service"
+ "github.com/alibabacloud-go/tea/tea"
+ "github.com/gogf/gf/v2/frame/g"
+ "hotgo/internal/model/input/sysin"
+)
+
+type AliYunDrive struct{}
+
+// SendCode 发送验证码
+func (d *AliYunDrive) SendCode(ctx context.Context, in *sysin.SendCodeInp) (err error) {
+ client, err := d.CreateClient(tea.String(config.AliYunAccessKeyID), tea.String(config.AliYunAccessKeySecret))
+ if err != nil {
+ return err
+ }
+
+ sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
+ PhoneNumbers: tea.String(in.Mobile),
+ SignName: tea.String(config.AliYunSign),
+ TemplateCode: tea.String(in.Template),
+ TemplateParam: tea.String(fmt.Sprintf("{\"code\":\"%v\"}", in.Code)),
+ }
+
+ return func() (_e error) {
+ defer func() {
+ if r := tea.Recover(recover()); r != nil {
+ _e = r
+ }
+ }()
+
+ // 复制代码运行请自行打印 API 的返回值
+ response, err := client.SendSmsWithOptions(sendSmsRequest, &util.RuntimeOptions{})
+ if err != nil {
+ return err
+ }
+
+ g.Log().Debugf(ctx, "aliyun.sendCode response:%+v", response.GoString())
+
+ return nil
+ }()
+}
+
+// CreateClient 使用AK&SK初始化账号Client
+func (d *AliYunDrive) CreateClient(accessKeyId *string, accessKeySecret *string) (result *dysmsapi20170525.Client, err error) {
+ conf := &openapi.Config{
+ // 必填,您的 AccessKey ID
+ AccessKeyId: accessKeyId,
+ // 必填,您的 AccessKey Secret
+ AccessKeySecret: accessKeySecret,
+ }
+ // 访问的域名
+ conf.Endpoint = tea.String("dysmsapi.aliyuncs.com")
+ return dysmsapi20170525.NewClient(conf)
+}
diff --git a/server/internal/library/sms/tencent/handle.go b/server/internal/library/sms/sms_tencent.go
similarity index 97%
rename from server/internal/library/sms/tencent/handle.go
rename to server/internal/library/sms/sms_tencent.go
index a44b5f7..608b23c 100644
--- a/server/internal/library/sms/tencent/handle.go
+++ b/server/internal/library/sms/sms_tencent.go
@@ -1,11 +1,10 @@
-package tencent
+package sms
import (
"context"
"encoding/json"
"fmt"
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model"
"hotgo/internal/model/input/sysin"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
@@ -14,14 +13,10 @@ import (
sms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms/v20210111" // 引入sms
)
-var (
- Handle = tencent{}
-)
-
-type tencent struct{}
+type TencentDrive struct{}
// SendCode 发送验证码
-func (d *tencent) SendCode(ctx context.Context, in sysin.SendCodeInp, config *model.SmsConfig) (err error) {
+func (d *TencentDrive) SendCode(ctx context.Context, in *sysin.SendCodeInp) (err error) {
/* 必要步骤:
* 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。
* 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。
diff --git a/server/internal/library/storager/mime.go b/server/internal/library/storager/mime.go
index 59b8687..b25aacd 100644
--- a/server/internal/library/storager/mime.go
+++ b/server/internal/library/storager/mime.go
@@ -18,13 +18,16 @@ import (
// 文件归属分类
const (
- KindImg = "images" // 图片
- KindDoc = "document" // 文档
- KindAudio = "audio" // 音频
- KindVideo = "video" // 视频
- KindOther = "other" // 其他
+ KindImg = "image" // 图片
+ KindDoc = "doc" // 文档
+ KindAudio = "audio" // 音频
+ KindVideo = "video" // 视频
+ KindZip = "zip" // 压缩包
+ KindOther = "other" // 其他
)
+var KindSlice = []string{KindImg, KindDoc, KindAudio, KindVideo, KindZip, KindOther}
+
var (
// 图片类型
imgType = g.MapStrStr{
@@ -45,12 +48,33 @@ var (
// 文档类型
docType = g.MapStrStr{
- "doc": "application/msword",
- "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
- "xls": "application/vnd.ms-excel",
- "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
- "ppt": "application/vnd.ms-powerpoint",
- "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
+ "doc": "application/msword",
+ "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "dot": "application/msword",
+ "xls": "application/vnd.ms-excel",
+ "xlt": "application/vnd.ms-excel",
+ "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ "xltx": "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
+ "ppt": "application/vnd.ms-powerpoint",
+ "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
+ "pdf": "application/pdf",
+ "txt": "text/plain",
+ "csv": "text/csv",
+ "html": "text/html",
+ "xml": "text/xml",
+ "pptm": "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
+ "pot": "application/vnd.ms-powerpoint",
+ "wpd": "application/wordperfect",
+ "md": "text/markdown",
+ "json": "application/json",
+ "yaml": "application/x-yaml",
+ "markdown": "text/markdown",
+ "asciidoc": "text/asciidoc",
+ "xsl": "application/xml",
+ "wps": "application/vnd.ms-works",
+ "sxi": "application/vnd.sun.xml.impress",
+ "sti": "application/vnd.sun.xml.impress.template",
+ "odp": "application/vnd.oasis.opendocument.presentation-template",
}
// 音频类型
@@ -79,6 +103,23 @@ var (
"flv": "video/x-flv",
"3gp": "video/3gpp",
}
+
+ // 压缩包
+ zipType = g.MapStrStr{
+ "zip": "application/zip",
+ "rar": "application/x-rar-compressed",
+ "tar": "application/x-tar",
+ "gz": "application/gzip",
+ "7z": "application/octet-stream",
+ "tar.gz": "application/octet-stream",
+ }
+
+ // 其他
+ otherType = g.MapStrStr{
+ "dwf": "model/vnd.dwf",
+ "ics": "text/calendar",
+ "vcard": "text/vcard",
+ }
)
// IsImgType 判断是否为图片
@@ -105,16 +146,17 @@ func IsVideoType(ext string) bool {
return ok
}
-// GetImgType 获取图片类型
-func GetImgType(ext string) (string, error) {
- if mime, ok := imgType[ext]; ok {
- return mime, nil
- }
- return "", gerror.New("Invalid image type")
+// IsZipType 判断是否为压缩包
+func IsZipType(ext string) bool {
+ _, ok := zipType[ext]
+ return ok
}
-// GetFileType 获取文件类型
-func GetFileType(ext string) (string, error) {
+// GetFileMimeType 获取文件扩展类型
+// 如果文件类型没有加入系统映射类型,默认认为不是合法的文件类型。建议将常用的上传文件类型加入映射关系。
+// 当然你也可以不做限制,可以上传任意文件。但需要谨慎处理和设置相应的安全措施。
+// 获取任意扩展名的扩展类型:mime.TypeByExtension(".xls")
+func GetFileMimeType(ext string) (string, error) {
if mime, ok := imgType[ext]; ok {
return mime, nil
}
@@ -127,10 +169,16 @@ func GetFileType(ext string) (string, error) {
if mime, ok := videoType[ext]; ok {
return mime, nil
}
+ if mime, ok := zipType[ext]; ok {
+ return mime, nil
+ }
+ if mime, ok := otherType[ext]; ok {
+ return mime, nil
+ }
return "", gerror.Newf("Invalid file type:%v", ext)
}
-// GetFileKind 获取文件所属分类
+// GetFileKind 获取文件上传类型
func GetFileKind(ext string) string {
if _, ok := imgType[ext]; ok {
return KindImg
@@ -144,12 +192,15 @@ func GetFileKind(ext string) string {
if _, ok := videoType[ext]; ok {
return KindVideo
}
+ if _, ok := zipType[ext]; ok {
+ return KindZip
+ }
return KindOther
}
// Ext 获取文件后缀
func Ext(baseName string) string {
- return gstr.StrEx(path.Ext(baseName), ".")
+ return gstr.ToLower(gstr.StrEx(path.Ext(baseName), "."))
}
// UploadFileByte 获取上传文件的byte
diff --git a/server/internal/library/storager/model.go b/server/internal/library/storager/model.go
index a557314..8331d75 100644
--- a/server/internal/library/storager/model.go
+++ b/server/internal/library/storager/model.go
@@ -4,9 +4,9 @@ package storager
type FileMeta struct {
Filename string // 文件名称
Size int64 // 文件大小
- Kind string // 文件所属分类
- MetaType string // 文件类型
+ Kind string // 文件上传类型
+ MimeType string // 文件扩展类型
NaiveType string // NaiveUI类型
- Ext string // 文件后缀名
+ Ext string // 文件扩展名
Md5 string // 文件hash
}
diff --git a/server/internal/library/storager/upload.go b/server/internal/library/storager/upload.go
index ac8537e..7affbfb 100644
--- a/server/internal/library/storager/upload.go
+++ b/server/internal/library/storager/upload.go
@@ -52,7 +52,7 @@ func New(name ...string) UploadDrive {
}
// DoUpload 上传入口
-func DoUpload(ctx context.Context, file *ghttp.UploadFile, typ int) (result *entity.SysAttachment, err error) {
+func DoUpload(ctx context.Context, typ string, file *ghttp.UploadFile) (result *entity.SysAttachment, err error) {
if file == nil {
err = gerror.New("文件必须!")
return
@@ -63,17 +63,12 @@ func DoUpload(ctx context.Context, file *ghttp.UploadFile, typ int) (result *ent
return
}
- if _, err = GetFileType(meta.Ext); err != nil {
+ if _, err = GetFileMimeType(meta.Ext); err != nil {
return
}
switch typ {
- case consts.UploadTypeFile:
- if config.FileSize > 0 && meta.Size > config.FileSize*1024*1024 {
- err = gerror.Newf("文件大小不能超过%vMB", config.FileSize)
- return
- }
- case consts.UploadTypeImage:
+ case KindImg:
if !IsImgType(meta.Ext) {
err = gerror.New("上传的文件不是图片")
return
@@ -82,24 +77,34 @@ func DoUpload(ctx context.Context, file *ghttp.UploadFile, typ int) (result *ent
err = gerror.Newf("图片大小不能超过%vMB", config.ImageSize)
return
}
- case consts.UploadTypeDoc:
+ case KindDoc:
if !IsDocType(meta.Ext) {
err = gerror.New("上传的文件不是文档")
return
}
- case consts.UploadTypeAudio:
+ case KindAudio:
if !IsAudioType(meta.Ext) {
err = gerror.New("上传的文件不是音频")
return
}
- case consts.UploadTypeVideo:
+ case KindVideo:
if !IsVideoType(meta.Ext) {
err = gerror.New("上传的文件不是视频")
return
}
+ case KindZip:
+ if !IsZipType(meta.Ext) {
+ err = gerror.New("上传的文件不是压缩文件")
+ return
+ }
+ case KindOther:
+ fallthrough
default:
- err = gerror.Newf("无效的上传类型:%v", typ)
- return
+ // 默认为通用的文件上传
+ if config.FileSize > 0 && meta.Size > config.FileSize*1024*1024 {
+ err = gerror.Newf("文件大小不能超过%vMB", config.FileSize)
+ return
+ }
}
result, err = hasFile(ctx, meta.Md5)
@@ -149,7 +154,7 @@ func GetFileMeta(file *ghttp.UploadFile) (meta *FileMeta, err error) {
meta.Size = file.Size
meta.Ext = Ext(file.Filename)
meta.Kind = GetFileKind(meta.Ext)
- meta.MetaType, err = GetFileType(meta.Ext)
+ meta.MimeType, err = GetFileMimeType(meta.Ext)
if err != nil {
return
}
@@ -185,7 +190,7 @@ func write(ctx context.Context, meta *FileMeta, fullPath string) (models *entity
FileUrl: fullPath,
Name: meta.Filename,
Kind: meta.Kind,
- MetaType: meta.MetaType,
+ MimeType: meta.MimeType,
NaiveType: meta.NaiveType,
Ext: meta.Ext,
Md5: meta.Md5,
diff --git a/server/internal/library/storager/upload_cos.go b/server/internal/library/storager/upload_cos.go
index d008dd8..2a25e73 100644
--- a/server/internal/library/storager/upload_cos.go
+++ b/server/internal/library/storager/upload_cos.go
@@ -36,7 +36,7 @@ func (d *CosDrive) Upload(ctx context.Context, file *ghttp.UploadFile) (fullPath
},
})
- fullPath = GenFullPath(config.UCloudPath, gfile.Ext(file.Filename))
+ fullPath = GenFullPath(config.CosPath, gfile.Ext(file.Filename))
_, err = client.Object.Put(ctx, fullPath, f2, nil)
return
}
diff --git a/server/internal/library/storager/upload_oss.go b/server/internal/library/storager/upload_oss.go
index 441d395..8011fe7 100644
--- a/server/internal/library/storager/upload_oss.go
+++ b/server/internal/library/storager/upload_oss.go
@@ -36,7 +36,7 @@ func (d *OssDrive) Upload(ctx context.Context, file *ghttp.UploadFile) (fullPath
return
}
- fullPath = GenFullPath(config.UCloudPath, gfile.Ext(file.Filename))
+ fullPath = GenFullPath(config.OssPath, gfile.Ext(file.Filename))
err = bucket.PutObject(fullPath, f2)
return
}
diff --git a/server/internal/library/storager/upload_qiniu.go b/server/internal/library/storager/upload_qiniu.go
index c4ade73..5eedde6 100644
--- a/server/internal/library/storager/upload_qiniu.go
+++ b/server/internal/library/storager/upload_qiniu.go
@@ -46,7 +46,7 @@ func (d *QiNiuDrive) Upload(ctx context.Context, file *ghttp.UploadFile) (fullPa
return
}
- fullPath = GenFullPath(config.UCloudPath, gfile.Ext(file.Filename))
+ fullPath = GenFullPath(config.QiNiuPath, gfile.Ext(file.Filename))
err = storage.NewFormUploader(&cfg).Put(ctx, &storage.PutRet{}, token, fullPath, f2, file.Size, &storage.PutExtra{})
return
}
diff --git a/server/internal/logic/admin/cash.go b/server/internal/logic/admin/cash.go
index 050ba4f..647819f 100644
--- a/server/internal/logic/admin/cash.go
+++ b/server/internal/logic/admin/cash.go
@@ -36,7 +36,7 @@ func init() {
}
// View 获取指定提现信息
-func (s *sAdminCash) View(ctx context.Context, in adminin.CashViewInp) (res *adminin.CashViewModel, err error) {
+func (s *sAdminCash) View(ctx context.Context, in *adminin.CashViewInp) (res *adminin.CashViewModel, err error) {
if !service.AdminMember().VerifySuperId(ctx, contexts.GetUserId(ctx)) {
err = gerror.New("没有访问权限")
return
@@ -68,7 +68,7 @@ func (s *sAdminCash) View(ctx context.Context, in adminin.CashViewInp) (res *adm
}
// List 获取列表
-func (s *sAdminCash) List(ctx context.Context, in adminin.CashListInp) (list []*adminin.CashListModel, totalCount int, err error) {
+func (s *sAdminCash) List(ctx context.Context, in *adminin.CashListInp) (list []*adminin.CashListModel, totalCount int, err error) {
var (
mod = dao.AdminCash.Ctx(ctx)
opMemberId = contexts.GetUserId(ctx)
@@ -109,9 +109,7 @@ func (s *sAdminCash) List(ctx context.Context, in adminin.CashListInp) (list []*
for _, v := range list {
var member *entity.AdminMember
- err = dao.AdminMember.Ctx(ctx).
- Fields("real_name", "username").Where("id", v.MemberId).Scan(&member)
- if err != nil {
+ if err = dao.AdminMember.Ctx(ctx).Fields("real_name", "username").Where("id", v.MemberId).Scan(&member); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
@@ -125,7 +123,7 @@ func (s *sAdminCash) List(ctx context.Context, in adminin.CashListInp) (list []*
}
// Apply 申请提现
-func (s *sAdminCash) Apply(ctx context.Context, in adminin.CashApplyInp) (err error) {
+func (s *sAdminCash) Apply(ctx context.Context, in *adminin.CashApplyInp) (err error) {
var (
config *model.CashConfig
member *entity.AdminMember
@@ -185,7 +183,7 @@ func (s *sAdminCash) Apply(ctx context.Context, in adminin.CashApplyInp) (err er
return
}
- conf, err := service.SysConfig().GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "cash"})
+ conf, err := service.SysConfig().GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "cash"})
if err != nil {
return
}
@@ -232,7 +230,7 @@ func (s *sAdminCash) Apply(ctx context.Context, in adminin.CashApplyInp) (err er
}
// 更新余额
- _, err = service.AdminCreditsLog().SaveBalance(ctx, adminin.CreditsLogSaveBalanceInp{
+ _, err = service.AdminCreditsLog().SaveBalance(ctx, &adminin.CreditsLogSaveBalanceInp{
MemberId: in.MemberId,
AppId: contexts.GetModule(ctx),
AddonsName: contexts.GetAddonName(ctx),
@@ -253,7 +251,7 @@ func (s *sAdminCash) Apply(ctx context.Context, in adminin.CashApplyInp) (err er
}
// Payment 提现打款处理
-func (s *sAdminCash) Payment(ctx context.Context, in adminin.CashPaymentInp) (err error) {
+func (s *sAdminCash) Payment(ctx context.Context, in *adminin.CashPaymentInp) (err error) {
if !service.AdminMember().VerifySuperId(ctx, contexts.GetUserId(ctx)) {
err = gerror.New("没有访问权限")
return
diff --git a/server/internal/logic/admin/credits_log.go b/server/internal/logic/admin/credits_log.go
index 1cfe169..016bc63 100644
--- a/server/internal/logic/admin/credits_log.go
+++ b/server/internal/logic/admin/credits_log.go
@@ -20,6 +20,7 @@ import (
"hotgo/internal/service"
"hotgo/utility/convert"
"hotgo/utility/excel"
+ "hotgo/utility/validate"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/os/gctx"
@@ -42,8 +43,8 @@ func (s *sAdminCreditsLog) Model(ctx context.Context, option ...*handler.Option)
}
// SaveBalance 更新余额
-func (s *sAdminCreditsLog) SaveBalance(ctx context.Context, in adminin.CreditsLogSaveBalanceInp) (res *adminin.CreditsLogSaveBalanceModel, err error) {
- if err = in.Filter(ctx); err != nil {
+func (s *sAdminCreditsLog) SaveBalance(ctx context.Context, in *adminin.CreditsLogSaveBalanceInp) (res *adminin.CreditsLogSaveBalanceModel, err error) {
+ if err = validate.PreFilter(ctx, in); err != nil {
return
}
@@ -101,8 +102,8 @@ func (s *sAdminCreditsLog) SaveBalance(ctx context.Context, in adminin.CreditsLo
}
// SaveIntegral 更新积分
-func (s *sAdminCreditsLog) SaveIntegral(ctx context.Context, in adminin.CreditsLogSaveIntegralInp) (res *adminin.CreditsLogSaveIntegralModel, err error) {
- if err = in.Filter(ctx); err != nil {
+func (s *sAdminCreditsLog) SaveIntegral(ctx context.Context, in *adminin.CreditsLogSaveIntegralInp) (res *adminin.CreditsLogSaveIntegralModel, err error) {
+ if err = validate.PreFilter(ctx, in); err != nil {
return
}
@@ -160,7 +161,7 @@ func (s *sAdminCreditsLog) SaveIntegral(ctx context.Context, in adminin.CreditsL
}
// List 获取资产变动列表
-func (s *sAdminCreditsLog) List(ctx context.Context, in adminin.CreditsLogListInp) (list []*adminin.CreditsLogListModel, totalCount int, err error) {
+func (s *sAdminCreditsLog) List(ctx context.Context, in *adminin.CreditsLogListInp) (list []*adminin.CreditsLogListModel, totalCount int, err error) {
mod := s.Model(ctx)
// 查询变动ID
@@ -222,7 +223,7 @@ func (s *sAdminCreditsLog) List(ctx context.Context, in adminin.CreditsLogListIn
}
// Export 导出资产变动
-func (s *sAdminCreditsLog) Export(ctx context.Context, in adminin.CreditsLogListInp) (err error) {
+func (s *sAdminCreditsLog) Export(ctx context.Context, in *adminin.CreditsLogListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
diff --git a/server/internal/logic/admin/dept.go b/server/internal/logic/admin/dept.go
index fd092d7..68cbda9 100644
--- a/server/internal/logic/admin/dept.go
+++ b/server/internal/logic/admin/dept.go
@@ -33,7 +33,7 @@ func init() {
}
// Delete 删除
-func (s *sAdminDept) Delete(ctx context.Context, in adminin.DeptDeleteInp) (err error) {
+func (s *sAdminDept) Delete(ctx context.Context, in *adminin.DeptDeleteInp) (err error) {
var models *entity.AdminDept
if err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Scan(&models); err != nil {
return err
@@ -56,12 +56,49 @@ func (s *sAdminDept) Delete(ctx context.Context, in adminin.DeptDeleteInp) (err
return
}
-// Edit 修改/新增
-func (s *sAdminDept) Edit(ctx context.Context, in adminin.DeptEditInp) (err error) {
- if err = hgorm.IsUnique(ctx, &dao.AdminDept, g.Map{dao.AdminDept.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
+// VerifyUnique 验证部门唯一属性
+func (s *sAdminDept) VerifyUnique(ctx context.Context, in *adminin.VerifyUniqueInp) (err error) {
+ if in.Where == nil {
return
}
+ cols := dao.AdminDept.Columns()
+ msgMap := g.MapStrStr{
+ cols.Name: "部门名称已存在,请换一个",
+ cols.Code: "部门编码已存在,请换一个",
+ }
+
+ for k, v := range in.Where {
+ if v == "" {
+ continue
+ }
+ message, ok := msgMap[k]
+ if !ok {
+ err = gerror.Newf("字段 [ %v ] 未配置唯一属性验证", k)
+ return
+ }
+ if err = hgorm.IsUnique(ctx, &dao.AdminDept, g.Map{k: v}, message, in.Id); err != nil {
+ return
+ }
+ }
+ return
+}
+
+// Edit 修改/新增
+func (s *sAdminDept) Edit(ctx context.Context, in *adminin.DeptEditInp) (err error) {
+ // 验证唯一性
+ err = s.VerifyUnique(ctx, &adminin.VerifyUniqueInp{
+ Id: in.Id,
+ Where: g.Map{
+ dao.AdminDept.Columns().Name: in.Name,
+ dao.AdminDept.Columns().Code: in.Code,
+ },
+ })
+ if err != nil {
+ return
+ }
+
+ // 生成下级关系树
if in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, &dao.AdminDept, in.Pid); err != nil {
return
}
@@ -70,7 +107,7 @@ func (s *sAdminDept) Edit(ctx context.Context, in adminin.DeptEditInp) (err erro
if in.Id > 0 {
// 获取父级tree
var pTree gdb.Value
- pTree, err = dao.AdminDept.Ctx(ctx).Where("id", in.Pid).Fields("tree").Value()
+ pTree, err = dao.AdminDept.Ctx(ctx).WherePri(in.Pid).Fields("tree").Value()
if err != nil {
return
}
@@ -115,7 +152,7 @@ func updateChildrenTree(ctx context.Context, _id int64, _level int, _tree string
}
// Status 更新部门状态
-func (s *sAdminDept) Status(ctx context.Context, in adminin.DeptStatusInp) (err error) {
+func (s *sAdminDept) Status(ctx context.Context, in *adminin.DeptStatusInp) (err error) {
if _, err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Data("status", in.Status).Update(); err != nil {
err = gerror.Wrap(err, "更新部门状态失败!")
}
@@ -123,7 +160,7 @@ func (s *sAdminDept) Status(ctx context.Context, in adminin.DeptStatusInp) (err
}
// MaxSort 最大排序
-func (s *sAdminDept) MaxSort(ctx context.Context, in adminin.DeptMaxSortInp) (res *adminin.DeptMaxSortModel, err error) {
+func (s *sAdminDept) MaxSort(ctx context.Context, in *adminin.DeptMaxSortInp) (res *adminin.DeptMaxSortModel, err error) {
if in.Id > 0 {
if err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, "获取部门数据异常!")
@@ -135,12 +172,12 @@ func (s *sAdminDept) MaxSort(ctx context.Context, in adminin.DeptMaxSortInp) (re
res = new(adminin.DeptMaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
// View 获取指定部门信息
-func (s *sAdminDept) View(ctx context.Context, in adminin.DeptViewInp) (res *adminin.DeptViewModel, err error) {
+func (s *sAdminDept) View(ctx context.Context, in *adminin.DeptViewInp) (res *adminin.DeptViewModel, err error) {
if err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取部门信息失败!")
}
@@ -148,7 +185,7 @@ func (s *sAdminDept) View(ctx context.Context, in adminin.DeptViewInp) (res *adm
}
// Option 选项
-func (s *sAdminDept) Option(ctx context.Context, in adminin.DeptOptionInp) (res *adminin.DeptOptionModel, totalCount int, err error) {
+func (s *sAdminDept) Option(ctx context.Context, in *adminin.DeptOptionInp) (res *adminin.DeptOptionModel, totalCount int, err error) {
var (
mod = dao.AdminDept.Ctx(ctx)
models []*entity.AdminDept
@@ -180,43 +217,72 @@ func (s *sAdminDept) Option(ctx context.Context, in adminin.DeptOptionInp) (res
}
// List 获取列表
-func (s *sAdminDept) List(ctx context.Context, in adminin.DeptListInp) (res *adminin.DeptListModel, err error) {
+func (s *sAdminDept) List(ctx context.Context, in *adminin.DeptListInp) (res *adminin.DeptListModel, err error) {
var (
mod = dao.AdminDept.Ctx(ctx)
+ cols = dao.AdminDept.Columns()
models []*entity.AdminDept
ids []int64
pids []int64
)
- // 部门名称
- if in.Name != "" {
- columns, err := dao.AdminDept.Ctx(ctx).Fields("pid").WhereLike("name", "%"+in.Name+"%").Array()
- if err != nil {
- err = gerror.Wrap(err, "过滤部门列表失败-1!")
- return nil, err
- }
-
+ appends := func(columns []gdb.Value) {
ds := g.NewVar(columns).Int64s()
ids = append(ids, ds...)
pids = append(pids, ds...)
- if len(ids) == 0 {
+ }
+
+ // 部门名称
+ if in.Name != "" {
+ columns, err := dao.AdminDept.Ctx(ctx).Fields(cols.Pid).WhereLike(cols.Name, "%"+in.Name+"%").Array()
+ if err != nil {
+ err = gerror.Wrap(err, "查询部门名称失败!")
+ return nil, err
+ }
+
+ if len(columns) == 0 {
return nil, nil
}
+ appends(columns)
}
if in.Code != "" {
- columns, err := dao.AdminDept.Ctx(ctx).Fields("pid").WhereLike("code", "%"+in.Code+"%").Array()
+ columns, err := dao.AdminDept.Ctx(ctx).Fields(cols.Pid).WhereLike(cols.Code, "%"+in.Code+"%").Array()
if err != nil {
- err = gerror.Wrap(err, "过滤部门列表失败-2!")
+ err = gerror.Wrap(err, "查询部门编码失败!")
return nil, err
}
- ds := g.NewVar(columns).Int64s()
- ids = append(ids, ds...)
- pids = append(pids, ds...)
- if len(ids) == 0 {
+ if len(columns) == 0 {
return nil, nil
}
+ appends(columns)
+ }
+
+ if in.Leader != "" {
+ columns, err := dao.AdminDept.Ctx(ctx).Fields(cols.Pid).Where(cols.Leader, in.Leader).Array()
+ if err != nil {
+ err = gerror.Wrap(err, "查询负责人失败!")
+ return nil, err
+ }
+
+ if len(columns) == 0 {
+ return nil, nil
+ }
+ appends(columns)
+ }
+
+ if len(in.CreatedAt) == 2 {
+ columns, err := dao.AdminDept.Ctx(ctx).Fields(cols.Pid).WhereBetween(cols.CreatedAt, in.CreatedAt[0], in.CreatedAt[1]).Array()
+ if err != nil {
+ err = gerror.Wrap(err, "查询创建时间失败!")
+ return nil, err
+ }
+
+ if len(columns) == 0 {
+ return nil, nil
+ }
+ appends(columns)
}
if len(ids) > 0 {
@@ -224,7 +290,7 @@ func (s *sAdminDept) List(ctx context.Context, in adminin.DeptListInp) (res *adm
}
if err = mod.Order("pid asc,sort asc").Scan(&models); err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
+ err = gerror.Wrap(err, "获取部门列表失败!")
return
}
diff --git a/server/internal/logic/admin/member.go b/server/internal/logic/admin/member.go
index 85d70d2..9cddb07 100644
--- a/server/internal/logic/admin/member.go
+++ b/server/internal/logic/admin/member.go
@@ -28,12 +28,24 @@ import (
"hotgo/internal/service"
"hotgo/utility/tree"
"hotgo/utility/validate"
+ "sync"
)
-type sAdminMember struct{}
+// SuperAdmin 超级管理员用户
+type SuperAdmin struct {
+ sync.RWMutex
+ RoleId int64 // 超管角色ID
+ MemberIds map[int64]struct{} // 超管用户ID
+}
+
+type sAdminMember struct {
+ superAdmin *SuperAdmin
+}
func NewAdminMember() *sAdminMember {
- return &sAdminMember{}
+ return &sAdminMember{
+ superAdmin: new(SuperAdmin),
+ }
}
func init() {
@@ -41,7 +53,7 @@ func init() {
}
// AddBalance 增加余额
-func (s *sAdminMember) AddBalance(ctx context.Context, in adminin.MemberAddBalanceInp) (err error) {
+func (s *sAdminMember) AddBalance(ctx context.Context, in *adminin.MemberAddBalanceInp) (err error) {
var (
mb *entity.AdminMember
memberId = contexts.GetUserId(ctx)
@@ -59,7 +71,7 @@ func (s *sAdminMember) AddBalance(ctx context.Context, in adminin.MemberAddBalan
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
// 更新我的余额
- _, err = service.AdminCreditsLog().SaveBalance(ctx, adminin.CreditsLogSaveBalanceInp{
+ _, err = service.AdminCreditsLog().SaveBalance(ctx, &adminin.CreditsLogSaveBalanceInp{
MemberId: memberId,
AppId: in.AppId,
AddonsName: in.AddonsName,
@@ -72,7 +84,7 @@ func (s *sAdminMember) AddBalance(ctx context.Context, in adminin.MemberAddBalan
}
// 更新对方余额
- _, err = service.AdminCreditsLog().SaveBalance(ctx, adminin.CreditsLogSaveBalanceInp{
+ _, err = service.AdminCreditsLog().SaveBalance(ctx, &adminin.CreditsLogSaveBalanceInp{
MemberId: mb.Id,
AppId: in.AppId,
AddonsName: in.AddonsName,
@@ -85,7 +97,7 @@ func (s *sAdminMember) AddBalance(ctx context.Context, in adminin.MemberAddBalan
}
// AddIntegral 增加积分
-func (s *sAdminMember) AddIntegral(ctx context.Context, in adminin.MemberAddIntegralInp) (err error) {
+func (s *sAdminMember) AddIntegral(ctx context.Context, in *adminin.MemberAddIntegralInp) (err error) {
var (
mb *entity.AdminMember
memberId = contexts.GetUserId(ctx)
@@ -103,7 +115,7 @@ func (s *sAdminMember) AddIntegral(ctx context.Context, in adminin.MemberAddInte
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
// 更新我的余额
- _, err = service.AdminCreditsLog().SaveIntegral(ctx, adminin.CreditsLogSaveIntegralInp{
+ _, err = service.AdminCreditsLog().SaveIntegral(ctx, &adminin.CreditsLogSaveIntegralInp{
MemberId: memberId,
AppId: in.AppId,
AddonsName: in.AddonsName,
@@ -116,7 +128,7 @@ func (s *sAdminMember) AddIntegral(ctx context.Context, in adminin.MemberAddInte
}
// 更新对方余额
- _, err = service.AdminCreditsLog().SaveIntegral(ctx, adminin.CreditsLogSaveIntegralInp{
+ _, err = service.AdminCreditsLog().SaveIntegral(ctx, &adminin.CreditsLogSaveIntegralInp{
MemberId: mb.Id,
AppId: in.AppId,
AddonsName: in.AddonsName,
@@ -129,7 +141,7 @@ func (s *sAdminMember) AddIntegral(ctx context.Context, in adminin.MemberAddInte
}
// UpdateCash 修改提现信息
-func (s *sAdminMember) UpdateCash(ctx context.Context, in adminin.MemberUpdateCashInp) (err error) {
+func (s *sAdminMember) UpdateCash(ctx context.Context, in *adminin.MemberUpdateCashInp) (err error) {
memberId := contexts.Get(ctx).User.Id
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -165,7 +177,7 @@ func (s *sAdminMember) UpdateCash(ctx context.Context, in adminin.MemberUpdateCa
}
// UpdateEmail 换绑邮箱
-func (s *sAdminMember) UpdateEmail(ctx context.Context, in adminin.MemberUpdateEmailInp) (err error) {
+func (s *sAdminMember) UpdateEmail(ctx context.Context, in *adminin.MemberUpdateEmailInp) (err error) {
memberId := contexts.Get(ctx).User.Id
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -195,7 +207,7 @@ func (s *sAdminMember) UpdateEmail(ctx context.Context, in adminin.MemberUpdateE
// 存在原绑定号码,需要进行验证
if mb.Email != "" {
- err = service.SysEmsLog().VerifyCode(ctx, sysin.VerifyEmsCodeInp{
+ err = service.SysEmsLog().VerifyCode(ctx, &sysin.VerifyEmsCodeInp{
Event: consts.EmsTemplateBind,
Email: mb.Email,
Code: in.Code,
@@ -217,7 +229,7 @@ func (s *sAdminMember) UpdateEmail(ctx context.Context, in adminin.MemberUpdateE
}
// UpdateMobile 换绑手机号
-func (s *sAdminMember) UpdateMobile(ctx context.Context, in adminin.MemberUpdateMobileInp) (err error) {
+func (s *sAdminMember) UpdateMobile(ctx context.Context, in *adminin.MemberUpdateMobileInp) (err error) {
memberId := contexts.Get(ctx).User.Id
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -247,7 +259,7 @@ func (s *sAdminMember) UpdateMobile(ctx context.Context, in adminin.MemberUpdate
// 存在原绑定号码,需要进行验证
if mb.Mobile != "" {
- err = service.SysSmsLog().VerifyCode(ctx, sysin.VerifyCodeInp{
+ err = service.SysSmsLog().VerifyCode(ctx, &sysin.VerifyCodeInp{
Event: consts.SmsTemplateBind,
Mobile: mb.Mobile,
Code: in.Code,
@@ -269,7 +281,7 @@ func (s *sAdminMember) UpdateMobile(ctx context.Context, in adminin.MemberUpdate
}
// UpdateProfile 更新用户资料
-func (s *sAdminMember) UpdateProfile(ctx context.Context, in adminin.MemberUpdateProfileInp) (err error) {
+func (s *sAdminMember) UpdateProfile(ctx context.Context, in *adminin.MemberUpdateProfileInp) (err error) {
memberId := contexts.Get(ctx).User.Id
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -306,7 +318,7 @@ func (s *sAdminMember) UpdateProfile(ctx context.Context, in adminin.MemberUpdat
}
// UpdatePwd 修改登录密码
-func (s *sAdminMember) UpdatePwd(ctx context.Context, in adminin.MemberUpdatePwdInp) (err error) {
+func (s *sAdminMember) UpdatePwd(ctx context.Context, in *adminin.MemberUpdatePwdInp) (err error) {
var mb entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).WherePri(in.Id).Scan(&mb); err != nil {
err = gerror.Wrap(err, "获取用户信息失败,请稍后重试!")
@@ -330,7 +342,7 @@ func (s *sAdminMember) UpdatePwd(ctx context.Context, in adminin.MemberUpdatePwd
}
// ResetPwd 重置密码
-func (s *sAdminMember) ResetPwd(ctx context.Context, in adminin.MemberResetPwdInp) (err error) {
+func (s *sAdminMember) ResetPwd(ctx context.Context, in *adminin.MemberResetPwdInp) (err error) {
var (
mb *entity.AdminMember
memberId = contexts.GetUserId(ctx)
@@ -358,7 +370,7 @@ func (s *sAdminMember) ResetPwd(ctx context.Context, in adminin.MemberResetPwdIn
}
// VerifyUnique 验证管理员唯一属性
-func (s *sAdminMember) VerifyUnique(ctx context.Context, in adminin.VerifyUniqueInp) (err error) {
+func (s *sAdminMember) VerifyUnique(ctx context.Context, in *adminin.VerifyUniqueInp) (err error) {
if in.Where == nil {
return
}
@@ -388,7 +400,7 @@ func (s *sAdminMember) VerifyUnique(ctx context.Context, in adminin.VerifyUnique
}
// Delete 删除
-func (s *sAdminMember) Delete(ctx context.Context, in adminin.MemberDeleteInp) (err error) {
+func (s *sAdminMember) Delete(ctx context.Context, in *adminin.MemberDeleteInp) (err error) {
if s.VerifySuperId(ctx, gconv.Int64(in.Id)) {
err = gerror.New("超管账号禁止删除!")
return
@@ -425,7 +437,7 @@ func (s *sAdminMember) Delete(ctx context.Context, in adminin.MemberDeleteInp) (
}
// Edit 修改/新增
-func (s *sAdminMember) Edit(ctx context.Context, in adminin.MemberEditInp) (err error) {
+func (s *sAdminMember) Edit(ctx context.Context, in *adminin.MemberEditInp) (err error) {
opMemberId := contexts.GetUserId(ctx)
if opMemberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -438,7 +450,7 @@ func (s *sAdminMember) Edit(ctx context.Context, in adminin.MemberEditInp) (err
}
cols := dao.AdminMember.Columns()
- err = s.VerifyUnique(ctx, adminin.VerifyUniqueInp{
+ err = s.VerifyUnique(ctx, &adminin.VerifyUniqueInp{
Id: in.Id,
Where: g.Map{
cols.Username: in.Username,
@@ -490,6 +502,10 @@ func (s *sAdminMember) Edit(ctx context.Context, in adminin.MemberEditInp) (err
if err = dao.AdminMemberPost.UpdatePostIds(ctx, in.Id, in.PostIds); err != nil {
err = gerror.Wrap(err, "更新用户岗位失败,请稍后重试!")
}
+
+ if in.RoleId == s.superAdmin.RoleId {
+ s.LoadSuperAdmin(ctx)
+ }
return
})
}
@@ -524,12 +540,16 @@ func (s *sAdminMember) Edit(ctx context.Context, in adminin.MemberEditInp) (err
if err = dao.AdminMemberPost.UpdatePostIds(ctx, id, in.PostIds); err != nil {
err = gerror.Wrap(err, "新增用户岗位失败,请稍后重试!")
}
+
+ if in.RoleId == s.superAdmin.RoleId {
+ s.LoadSuperAdmin(ctx)
+ }
return
})
}
// View 获取用户信息
-func (s *sAdminMember) View(ctx context.Context, in adminin.MemberViewInp) (res *adminin.MemberViewModel, err error) {
+func (s *sAdminMember) View(ctx context.Context, in *adminin.MemberViewInp) (res *adminin.MemberViewModel, err error) {
if err = s.FilterAuthModel(ctx, contexts.GetUserId(ctx)).Hook(hook.MemberInfo).WherePri(in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取用户信息失败,请稍后重试!")
}
@@ -537,7 +557,7 @@ func (s *sAdminMember) View(ctx context.Context, in adminin.MemberViewInp) (res
}
// List 获取列表
-func (s *sAdminMember) List(ctx context.Context, in adminin.MemberListInp) (list []*adminin.MemberListModel, totalCount int, err error) {
+func (s *sAdminMember) List(ctx context.Context, in *adminin.MemberListInp) (list []*adminin.MemberListModel, totalCount int, err error) {
mod := s.FilterAuthModel(ctx, contexts.GetUserId(ctx))
cols := dao.AdminMember.Columns()
@@ -590,14 +610,13 @@ func (s *sAdminMember) List(ctx context.Context, in adminin.MemberListInp) (list
err = gerror.Wrap(err, "获取用户岗位数据失败!")
return nil, 0, err
}
-
v.PostIds = g.NewVar(columns).Int64s()
}
return
}
// Status 更新状态
-func (s *sAdminMember) Status(ctx context.Context, in adminin.MemberStatusInp) (err error) {
+func (s *sAdminMember) Status(ctx context.Context, in *adminin.MemberStatusInp) (err error) {
if s.VerifySuperId(ctx, in.Id) {
err = gerror.New("超管账号不能更改状态")
return
@@ -652,7 +671,7 @@ func (s *sAdminMember) LoginMemberInfo(ctx context.Context) (res *adminin.LoginM
res.Permissions = permissions
// 登录统计
- stat, err := s.MemberLoginStat(ctx, adminin.MemberLoginStatInp{MemberId: memberId})
+ stat, err := s.MemberLoginStat(ctx, &adminin.MemberLoginStatInp{MemberId: memberId})
if err != nil {
return
}
@@ -665,7 +684,7 @@ func (s *sAdminMember) LoginMemberInfo(ctx context.Context) (res *adminin.LoginM
}
// MemberLoginStat 用户登录统计
-func (s *sAdminMember) MemberLoginStat(ctx context.Context, in adminin.MemberLoginStatInp) (res *adminin.MemberLoginStatModel, err error) {
+func (s *sAdminMember) MemberLoginStat(ctx context.Context, in *adminin.MemberLoginStatInp) (res *adminin.MemberLoginStatModel, err error) {
var (
models *entity.SysLoginLog
cols = dao.SysLoginLog.Columns()
@@ -697,7 +716,7 @@ func (s *sAdminMember) MemberLoginStat(ctx context.Context, in adminin.MemberLog
}
// GetIdByCode 通过邀请码获取用户ID
-func (s *sAdminMember) GetIdByCode(ctx context.Context, in adminin.GetIdByCodeInp) (res *adminin.GetIdByCodeModel, err error) {
+func (s *sAdminMember) GetIdByCode(ctx context.Context, in *adminin.GetIdByCodeInp) (res *adminin.GetIdByCodeModel, err error) {
if err = dao.AdminMember.Ctx(ctx).Fields(adminin.GetIdByCodeModel{}).Where(dao.AdminMember.Columns().InviteCode, in.Code).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取用户信息失败,请稍后重试!")
}
@@ -705,7 +724,7 @@ func (s *sAdminMember) GetIdByCode(ctx context.Context, in adminin.GetIdByCodeIn
}
// Select 获取可选的用户选项
-func (s *sAdminMember) Select(ctx context.Context, in adminin.MemberSelectInp) (res []*adminin.MemberSelectModel, err error) {
+func (s *sAdminMember) Select(ctx context.Context, in *adminin.MemberSelectInp) (res []*adminin.MemberSelectModel, err error) {
err = dao.AdminMember.Ctx(ctx).
Fields("id as value,real_name as label,username,avatar").
Handler(handler.FilterAuthWithField("id")).
@@ -718,12 +737,45 @@ func (s *sAdminMember) Select(ctx context.Context, in adminin.MemberSelectInp) (
// VerifySuperId 验证是否为超管
func (s *sAdminMember) VerifySuperId(ctx context.Context, verifyId int64) bool {
- for _, id := range g.Cfg().MustGet(ctx, "hotgo.admin.superIds").Int64s() {
- if id == verifyId {
- return true
- }
+ if s.superAdmin == nil || s.superAdmin.MemberIds == nil {
+ g.Log().Error(ctx, "superAdmin is not initialized.")
+ return false
}
- return false
+
+ s.superAdmin.RLock()
+ defer s.superAdmin.RUnlock()
+
+ _, ok := s.superAdmin.MemberIds[verifyId]
+ return ok
+}
+
+// LoadSuperAdmin 加载超管数据
+func (s *sAdminMember) LoadSuperAdmin(ctx context.Context) {
+ s.superAdmin.Lock()
+ defer s.superAdmin.Unlock()
+
+ value, err := dao.AdminRole.Ctx(ctx).Where(dao.AdminRole.Columns().Key, consts.SuperRoleKey).Value()
+ if err != nil {
+ g.Log().Errorf(ctx, "LoadSuperAdmin AdminRole err:%+v", err)
+ return
+ }
+
+ if value.IsEmpty() || value.IsNil() {
+ g.Log().Error(ctx, "the superAdmin role must be configured.")
+ return
+ }
+
+ array, err := dao.AdminMember.Ctx(ctx).Fields(dao.AdminMember.Columns().Id).Where(dao.AdminMember.Columns().RoleId, value).Array()
+ if err != nil {
+ g.Log().Errorf(ctx, "LoadSuperAdmin AdminMember err:%+v", err)
+ return
+ }
+
+ s.superAdmin.MemberIds = make(map[int64]struct{}, len(array))
+ for _, v := range array {
+ s.superAdmin.MemberIds[v.Int64()] = struct{}{}
+ }
+ s.superAdmin.RoleId = value.Int64()
}
func (s *sAdminMember) FilterAuthModel(ctx context.Context, memberId int64) *gdb.Model {
diff --git a/server/internal/logic/admin/menu.go b/server/internal/logic/admin/menu.go
index 4a37ac6..dbb6cb8 100644
--- a/server/internal/logic/admin/menu.go
+++ b/server/internal/logic/admin/menu.go
@@ -36,7 +36,7 @@ func init() {
}
// Delete 删除
-func (s *sAdminMenu) Delete(ctx context.Context, in adminin.MenuDeleteInp) (err error) {
+func (s *sAdminMenu) Delete(ctx context.Context, in *adminin.MenuDeleteInp) (err error) {
exist, err := dao.AdminMenu.Ctx(ctx).Where("pid", in.Id).One()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -50,7 +50,7 @@ func (s *sAdminMenu) Delete(ctx context.Context, in adminin.MenuDeleteInp) (err
}
// VerifyUnique 验证菜单唯一属性
-func (s *sAdminMenu) VerifyUnique(ctx context.Context, in adminin.VerifyUniqueInp) (err error) {
+func (s *sAdminMenu) VerifyUnique(ctx context.Context, in *adminin.VerifyUniqueInp) (err error) {
if in.Where == nil {
return
}
@@ -78,9 +78,9 @@ func (s *sAdminMenu) VerifyUnique(ctx context.Context, in adminin.VerifyUniqueIn
}
// Edit 修改/新增
-func (s *sAdminMenu) Edit(ctx context.Context, in adminin.MenuEditInp) (err error) {
+func (s *sAdminMenu) Edit(ctx context.Context, in *adminin.MenuEditInp) (err error) {
// 验证唯一性
- err = s.VerifyUnique(ctx, adminin.VerifyUniqueInp{
+ err = s.VerifyUnique(ctx, &adminin.VerifyUniqueInp{
Id: in.Id,
Where: g.Map{
dao.AdminMenu.Columns().Title: in.Title,
@@ -132,7 +132,7 @@ func (s *sAdminMenu) Edit(ctx context.Context, in adminin.MenuEditInp) (err erro
}
// List 获取菜单列表
-func (s *sAdminMenu) List(ctx context.Context, in adminin.MenuListInp) (res *adminin.MenuListModel, err error) {
+func (s *sAdminMenu) List(ctx context.Context, in *adminin.MenuListInp) (res *adminin.MenuListModel, err error) {
var models []*entity.AdminMenu
if err = dao.AdminMenu.Ctx(ctx).Order("sort asc,id desc").Scan(&models); err != nil {
return
@@ -144,14 +144,14 @@ func (s *sAdminMenu) List(ctx context.Context, in adminin.MenuListInp) (res *adm
}
// genNaiveMenus 生成NaiveUI菜单格式
-func (s *sAdminMenu) genNaiveMenus(menus []adminin.MenuRouteSummary) (sources []adminin.MenuRoute) {
+func (s *sAdminMenu) genNaiveMenus(menus []*adminin.MenuRouteSummary) (sources []*adminin.MenuRoute) {
for _, men := range menus {
- var source adminin.MenuRoute
+ var source = new(adminin.MenuRoute)
source.Name = men.Name
source.Path = men.Path
source.Redirect = men.Redirect
source.Component = men.Component
- source.Meta = adminin.MenuRouteMeta{
+ source.Meta = &adminin.MenuRouteMeta{
Title: men.Title,
Icon: men.Icon,
KeepAlive: men.KeepAlive == 1,
@@ -174,10 +174,10 @@ func (s *sAdminMenu) genNaiveMenus(menus []adminin.MenuRouteSummary) (sources []
}
// getChildrenList 生成菜单树
-func (s *sAdminMenu) getChildrenList(menu *adminin.MenuRouteSummary, treeMap map[string][]adminin.MenuRouteSummary) (err error) {
+func (s *sAdminMenu) getChildrenList(menu *adminin.MenuRouteSummary, treeMap map[string][]*adminin.MenuRouteSummary) (err error) {
menu.Children = treeMap[gconv.String(menu.Id)]
for i := 0; i < len(menu.Children); i++ {
- if err = s.getChildrenList(&menu.Children[i], treeMap); err != nil {
+ if err = s.getChildrenList(menu.Children[i], treeMap); err != nil {
return
}
}
@@ -187,9 +187,9 @@ func (s *sAdminMenu) getChildrenList(menu *adminin.MenuRouteSummary, treeMap map
// GetMenuList 获取菜单列表
func (s *sAdminMenu) GetMenuList(ctx context.Context, memberId int64) (res *role.DynamicRes, err error) {
var (
- allMenus []adminin.MenuRouteSummary
- menus []adminin.MenuRouteSummary
- treeMap = make(map[string][]adminin.MenuRouteSummary)
+ allMenus []*adminin.MenuRouteSummary
+ menus []*adminin.MenuRouteSummary
+ treeMap = make(map[string][]*adminin.MenuRouteSummary)
mod = dao.AdminMenu.Ctx(ctx).Where("status", consts.StatusEnabled).WhereIn("type", []int{1, 2})
)
@@ -221,7 +221,7 @@ func (s *sAdminMenu) GetMenuList(ctx context.Context, memberId int64) (res *role
menus = treeMap["0"]
for i := 0; i < len(menus); i++ {
- err = s.getChildrenList(&menus[i], treeMap)
+ err = s.getChildrenList(menus[i], treeMap)
}
res = new(role.DynamicRes)
diff --git a/server/internal/logic/admin/notice.go b/server/internal/logic/admin/notice.go
index 96ff499..76a70db 100644
--- a/server/internal/logic/admin/notice.go
+++ b/server/internal/logic/admin/notice.go
@@ -41,13 +41,13 @@ func (s *sAdminNotice) Model(ctx context.Context, option ...*handler.Option) *gd
}
// Delete 删除
-func (s *sAdminNotice) Delete(ctx context.Context, in adminin.NoticeDeleteInp) (err error) {
+func (s *sAdminNotice) Delete(ctx context.Context, in *adminin.NoticeDeleteInp) (err error) {
_, err = s.Model(ctx).Where("id", in.Id).Delete()
return
}
// Edit 修改/新增
-func (s *sAdminNotice) Edit(ctx context.Context, in adminin.NoticeEditInp) (err error) {
+func (s *sAdminNotice) Edit(ctx context.Context, in *adminin.NoticeEditInp) (err error) {
var member = contexts.Get(ctx).User
if member == nil {
err = gerror.New("获取用户信息失败!")
@@ -108,12 +108,11 @@ func (s *sAdminNotice) Edit(ctx context.Context, in adminin.NoticeEditInp) (err
websocket.SendToAll(response)
}
})
-
return
}
// Status 更新部门状态
-func (s *sAdminNotice) Status(ctx context.Context, in adminin.NoticeStatusInp) (err error) {
+func (s *sAdminNotice) Status(ctx context.Context, in *adminin.NoticeStatusInp) (err error) {
if in.Id <= 0 {
err = gerror.New("ID不能为空")
return
@@ -135,7 +134,7 @@ func (s *sAdminNotice) Status(ctx context.Context, in adminin.NoticeStatusInp) (
}
// MaxSort 最大排序
-func (s *sAdminNotice) MaxSort(ctx context.Context, in adminin.NoticeMaxSortInp) (res *adminin.NoticeMaxSortModel, err error) {
+func (s *sAdminNotice) MaxSort(ctx context.Context, in *adminin.NoticeMaxSortInp) (res *adminin.NoticeMaxSortModel, err error) {
if err = dao.AdminNotice.Ctx(ctx).Order("sort desc").Scan(&res); err != nil {
return
}
@@ -144,12 +143,12 @@ func (s *sAdminNotice) MaxSort(ctx context.Context, in adminin.NoticeMaxSortInp)
res = new(adminin.NoticeMaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
// View 获取指定字典类型信息
-func (s *sAdminNotice) View(ctx context.Context, in adminin.NoticeViewInp) (res *adminin.NoticeViewModel, err error) {
+func (s *sAdminNotice) View(ctx context.Context, in *adminin.NoticeViewInp) (res *adminin.NoticeViewModel, err error) {
if err = s.Model(ctx).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
@@ -159,7 +158,7 @@ func (s *sAdminNotice) View(ctx context.Context, in adminin.NoticeViewInp) (res
}
// List 获取列表
-func (s *sAdminNotice) List(ctx context.Context, in adminin.NoticeListInp) (list []*adminin.NoticeListModel, totalCount int, err error) {
+func (s *sAdminNotice) List(ctx context.Context, in *adminin.NoticeListInp) (list []*adminin.NoticeListModel, totalCount int, err error) {
var memberId = contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -224,7 +223,7 @@ func (s *sAdminNotice) List(ctx context.Context, in adminin.NoticeListInp) (list
}
// PullMessages 拉取未读消息列表
-func (s *sAdminNotice) PullMessages(ctx context.Context, in adminin.PullMessagesInp) (res *adminin.PullMessagesModel, err error) {
+func (s *sAdminNotice) PullMessages(ctx context.Context, in *adminin.PullMessagesInp) (res *adminin.PullMessagesModel, err error) {
var memberId = contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -237,7 +236,7 @@ func (s *sAdminNotice) PullMessages(ctx context.Context, in adminin.PullMessages
}
res = new(adminin.PullMessagesModel)
- unread, err := s.UnreadCount(ctx, adminin.NoticeUnreadCountInp{MemberId: memberId, MessageIds: messageIds})
+ unread, err := s.UnreadCount(ctx, &adminin.NoticeUnreadCountInp{MemberId: memberId, MessageIds: messageIds})
if err != nil {
return
}
@@ -268,7 +267,7 @@ func (s *sAdminNotice) PullMessages(ctx context.Context, in adminin.PullMessages
}
// UnreadCount 获取所有类型消息的未读数量
-func (s *sAdminNotice) UnreadCount(ctx context.Context, in adminin.NoticeUnreadCountInp) (res *adminin.NoticeUnreadCountModel, err error) {
+func (s *sAdminNotice) UnreadCount(ctx context.Context, in *adminin.NoticeUnreadCountInp) (res *adminin.NoticeUnreadCountModel, err error) {
if in.MemberId <= 0 {
if in.MemberId = contexts.GetUserId(ctx); in.MemberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -338,7 +337,7 @@ func (s *sAdminNotice) messageIds(ctx context.Context, memberId int64) (ids []in
}
// UpRead 更新已读
-func (s *sAdminNotice) UpRead(ctx context.Context, in adminin.NoticeUpReadInp) (err error) {
+func (s *sAdminNotice) UpRead(ctx context.Context, in *adminin.NoticeUpReadInp) (err error) {
var (
data *entity.AdminNotice
memberId = contexts.GetUserId(ctx)
@@ -361,7 +360,7 @@ func (s *sAdminNotice) UpRead(ctx context.Context, in adminin.NoticeUpReadInp) (
}
// ReadAll 已读全部
-func (s *sAdminNotice) ReadAll(ctx context.Context, in adminin.NoticeReadAllInp) (err error) {
+func (s *sAdminNotice) ReadAll(ctx context.Context, in *adminin.NoticeReadAllInp) (err error) {
var memberId = contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -417,9 +416,7 @@ func (s *sAdminNotice) ReadAll(ctx context.Context, in adminin.NoticeReadAllInp)
// updatedReadClicks 更新公告已读次数
func (s *sAdminNotice) updatedReadClicks(ctx context.Context, noticeId, memberId int64) (err error) {
- var (
- models *entity.AdminNoticeRead
- )
+ var models *entity.AdminNoticeRead
err = dao.AdminNoticeRead.Ctx(ctx).
Where(dao.AdminNoticeRead.Columns().NoticeId, noticeId).
Where(dao.AdminNoticeRead.Columns().MemberId, memberId).
@@ -437,7 +434,7 @@ func (s *sAdminNotice) updatedReadClicks(ctx context.Context, noticeId, memberId
}
// MessageList 我的消息列表
-func (s *sAdminNotice) MessageList(ctx context.Context, in adminin.NoticeMessageListInp) (list []*adminin.NoticeMessageListModel, totalCount int, err error) {
+func (s *sAdminNotice) MessageList(ctx context.Context, in *adminin.NoticeMessageListInp) (list []*adminin.NoticeMessageListModel, totalCount int, err error) {
var memberId = contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
@@ -457,16 +454,16 @@ func (s *sAdminNotice) MessageList(ctx context.Context, in adminin.NoticeMessage
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
- return list, totalCount, err
+ return
}
if totalCount == 0 {
- return list, totalCount, nil
+ return
}
if err = mod.Page(in.Page, in.PerPage).Order("id desc").Scan(&list); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
- return list, totalCount, err
+ return
}
for _, v := range list {
@@ -482,5 +479,5 @@ func (s *sAdminNotice) MessageList(ctx context.Context, in adminin.NoticeMessage
}
}
}
- return list, totalCount, err
+ return
}
diff --git a/server/internal/logic/admin/order.go b/server/internal/logic/admin/order.go
index cfb95dd..e6cdf70 100644
--- a/server/internal/logic/admin/order.go
+++ b/server/internal/logic/admin/order.go
@@ -48,8 +48,8 @@ func (s *sAdminOrder) Model(ctx context.Context, option ...*handler.Option) *gdb
}
// AcceptRefund 受理申请退款
-func (s *sAdminOrder) AcceptRefund(ctx context.Context, in adminin.OrderAcceptRefundInp) (err error) {
- view, err := s.View(ctx, adminin.OrderViewInp{Id: in.Id})
+func (s *sAdminOrder) AcceptRefund(ctx context.Context, in *adminin.OrderAcceptRefundInp) (err error) {
+ view, err := s.View(ctx, &adminin.OrderViewInp{Id: in.Id})
if err != nil {
return err
}
@@ -68,7 +68,7 @@ func (s *sAdminOrder) AcceptRefund(ctx context.Context, in adminin.OrderAcceptRe
// 同意退款
if in.Status == consts.OrderStatusReturned {
// 更新余额
- _, err = service.AdminCreditsLog().SaveBalance(ctx, adminin.CreditsLogSaveBalanceInp{
+ _, err = service.AdminCreditsLog().SaveBalance(ctx, &adminin.CreditsLogSaveBalanceInp{
MemberId: view.MemberId,
AppId: contexts.GetModule(ctx),
AddonsName: contexts.GetAddonName(ctx),
@@ -81,7 +81,7 @@ func (s *sAdminOrder) AcceptRefund(ctx context.Context, in adminin.OrderAcceptRe
return err
}
- _, err = service.PayRefund().Refund(ctx, payin.PayRefundInp{
+ _, err = service.PayRefund().Refund(ctx, &payin.PayRefundInp{
OrderSn: view.OrderSn,
RefundMoney: view.Money,
Reason: view.RefundReason,
@@ -98,16 +98,14 @@ func (s *sAdminOrder) AcceptRefund(ctx context.Context, in adminin.OrderAcceptRe
}
_, err = s.Model(ctx).Where(dao.AdminOrder.Columns().Id, in.Id).Data(update).Update()
-
return
})
-
return
}
// ApplyRefund 申请退款
-func (s *sAdminOrder) ApplyRefund(ctx context.Context, in adminin.OrderApplyRefundInp) (err error) {
- view, err := s.View(ctx, adminin.OrderViewInp{Id: in.Id})
+func (s *sAdminOrder) ApplyRefund(ctx context.Context, in *adminin.OrderApplyRefundInp) (err error) {
+ view, err := s.View(ctx, &adminin.OrderViewInp{Id: in.Id})
if err != nil {
return err
}
@@ -137,7 +135,7 @@ func (s *sAdminOrder) ApplyRefund(ctx context.Context, in adminin.OrderApplyRefu
}
// PayNotify 支付成功通知
-func (s *sAdminOrder) PayNotify(ctx context.Context, in payin.NotifyCallFuncInp) (err error) {
+func (s *sAdminOrder) PayNotify(ctx context.Context, in *payin.NotifyCallFuncInp) (err error) {
var models *entity.AdminOrder
if err = s.Model(ctx).Where(dao.AdminOrder.Columns().OrderSn, in.Pay.OrderSn).Scan(&models); err != nil {
return
@@ -163,7 +161,7 @@ func (s *sAdminOrder) PayNotify(ctx context.Context, in payin.NotifyCallFuncInp)
}
// 更新余额
- _, err = service.AdminCreditsLog().SaveBalance(ctx, adminin.CreditsLogSaveBalanceInp{
+ _, err = service.AdminCreditsLog().SaveBalance(ctx, &adminin.CreditsLogSaveBalanceInp{
MemberId: models.MemberId,
AppId: in.Pay.AppId,
AddonsName: in.Pay.AddonsName,
@@ -195,7 +193,7 @@ func (s *sAdminOrder) PayNotify(ctx context.Context, in payin.NotifyCallFuncInp)
}
// Create 创建充值订单
-func (s *sAdminOrder) Create(ctx context.Context, in adminin.OrderCreateInp) (res *adminin.OrderCreateModel, err error) {
+func (s *sAdminOrder) Create(ctx context.Context, in *adminin.OrderCreateInp) (res *adminin.OrderCreateModel, err error) {
var (
subject = "支付订单"
orderSn = payment.GenOrderSn()
@@ -247,12 +245,11 @@ func (s *sAdminOrder) Create(ctx context.Context, in adminin.OrderCreateInp) (re
res.Order = create.Order
return
})
-
return
}
// List 获取充值订单列表
-func (s *sAdminOrder) List(ctx context.Context, in adminin.OrderListInp) (list []*adminin.OrderListModel, totalCount int, err error) {
+func (s *sAdminOrder) List(ctx context.Context, in *adminin.OrderListInp) (list []*adminin.OrderListModel, totalCount int, err error) {
mod := s.Model(ctx)
// 查询业务订单号
@@ -307,7 +304,7 @@ func (s *sAdminOrder) List(ctx context.Context, in adminin.OrderListInp) (list [
}
// Export 导出充值订单
-func (s *sAdminOrder) Export(ctx context.Context, in adminin.OrderListInp) (err error) {
+func (s *sAdminOrder) Export(ctx context.Context, in *adminin.OrderListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
@@ -334,7 +331,7 @@ func (s *sAdminOrder) Export(ctx context.Context, in adminin.OrderListInp) (err
}
// Edit 修改/新增充值订单
-func (s *sAdminOrder) Edit(ctx context.Context, in adminin.OrderEditInp) (err error) {
+func (s *sAdminOrder) Edit(ctx context.Context, in *adminin.OrderEditInp) (err error) {
// 修改
if in.Id > 0 {
_, err = s.Model(ctx).
@@ -356,7 +353,7 @@ func (s *sAdminOrder) Edit(ctx context.Context, in adminin.OrderEditInp) (err er
}
// Delete 删除充值订单
-func (s *sAdminOrder) Delete(ctx context.Context, in adminin.OrderDeleteInp) (err error) {
+func (s *sAdminOrder) Delete(ctx context.Context, in *adminin.OrderDeleteInp) (err error) {
_, err = s.Model(ctx).
Where(dao.AdminOrder.Columns().Id, in.Id).
Where(dao.AdminOrder.Columns().Status, consts.OrderStatusClose).
@@ -365,13 +362,13 @@ func (s *sAdminOrder) Delete(ctx context.Context, in adminin.OrderDeleteInp) (er
}
// View 获取充值订单指定信息
-func (s *sAdminOrder) View(ctx context.Context, in adminin.OrderViewInp) (res *adminin.OrderViewModel, err error) {
+func (s *sAdminOrder) View(ctx context.Context, in *adminin.OrderViewInp) (res *adminin.OrderViewModel, err error) {
err = s.Model(ctx).Where(dao.AdminOrder.Columns().Id, in.Id).Scan(&res)
return
}
// Status 更新充值订单状态
-func (s *sAdminOrder) Status(ctx context.Context, in adminin.OrderStatusInp) (err error) {
+func (s *sAdminOrder) Status(ctx context.Context, in *adminin.OrderStatusInp) (err error) {
if in.Id <= 0 {
err = gerror.New("ID不能为空")
return
diff --git a/server/internal/logic/admin/post.go b/server/internal/logic/admin/post.go
index 217e2ef..51ec8c2 100644
--- a/server/internal/logic/admin/post.go
+++ b/server/internal/logic/admin/post.go
@@ -8,12 +8,13 @@ package admin
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/frame/g"
"hotgo/internal/consts"
"hotgo/internal/dao"
+ "hotgo/internal/library/hgorm"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/form"
"hotgo/internal/service"
- "hotgo/utility/validate"
)
type sAdminPost struct{}
@@ -27,8 +28,8 @@ func init() {
}
// Delete 删除
-func (s *sAdminPost) Delete(ctx context.Context, in adminin.PostDeleteInp) (err error) {
- exist, err := dao.AdminMemberPost.Ctx(ctx).Where("post_id", in.Id).One()
+func (s *sAdminPost) Delete(ctx context.Context, in *adminin.PostDeleteInp) (err error) {
+ exist, err := dao.AdminMemberPost.Ctx(ctx).Where(dao.AdminMemberPost.Columns().PostId, in.Id).One()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
@@ -38,44 +39,55 @@ func (s *sAdminPost) Delete(ctx context.Context, in adminin.PostDeleteInp) (err
return gerror.New("请先解除该岗位下所有已关联用户关联关系!")
}
- _, err = dao.AdminPost.Ctx(ctx).Where("id", in.Id).Delete()
+ _, err = dao.AdminPost.Ctx(ctx).WherePri(in.Id).Delete()
+ return
+}
+
+// VerifyUnique 验证部门唯一属性
+func (s *sAdminPost) VerifyUnique(ctx context.Context, in *adminin.VerifyUniqueInp) (err error) {
+ if in.Where == nil {
+ return
+ }
+
+ cols := dao.AdminPost.Columns()
+ msgMap := g.MapStrStr{
+ cols.Name: "岗位名称已存在,请换一个",
+ cols.Code: "岗位编码已存在,请换一个",
+ }
+
+ for k, v := range in.Where {
+ if v == "" {
+ continue
+ }
+ message, ok := msgMap[k]
+ if !ok {
+ err = gerror.Newf("字段 [ %v ] 未配置唯一属性验证", k)
+ return
+ }
+ if err = hgorm.IsUnique(ctx, &dao.AdminPost, g.Map{k: v}, message, in.Id); err != nil {
+ return
+ }
+ }
return
}
// Edit 修改/新增
-func (s *sAdminPost) Edit(ctx context.Context, in adminin.PostEditInp) (err error) {
- if in.Name == "" {
- err = gerror.New("名称不能为空")
- return
- }
- if in.Code == "" {
- err = gerror.New("编码不能为空")
- return
- }
-
- uniqueName, err := dao.AdminPost.IsUniqueName(ctx, in.Id, in.Name)
+func (s *sAdminPost) Edit(ctx context.Context, in *adminin.PostEditInp) (err error) {
+ // 验证唯一性
+ err = s.VerifyUnique(ctx, &adminin.VerifyUniqueInp{
+ Id: in.Id,
+ Where: g.Map{
+ dao.AdminPost.Columns().Name: in.Name,
+ dao.AdminPost.Columns().Code: in.Code,
+ },
+ })
if err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
- return
- }
- if !uniqueName {
- err = gerror.New("名称已存在")
- return
- }
-
- uniqueCode, err := dao.AdminPost.IsUniqueCode(ctx, in.Id, in.Code)
- if err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
- return
- }
- if !uniqueCode {
- err = gerror.New("编码已存在")
return
}
// 修改
if in.Id > 0 {
- _, err = dao.AdminPost.Ctx(ctx).Where("id", in.Id).Data(in).Update()
+ _, err = dao.AdminPost.Ctx(ctx).WherePri(in.Id).Data(in).Update()
return
}
@@ -85,9 +97,9 @@ func (s *sAdminPost) Edit(ctx context.Context, in adminin.PostEditInp) (err erro
}
// MaxSort 最大排序
-func (s *sAdminPost) MaxSort(ctx context.Context, in adminin.PostMaxSortInp) (res *adminin.PostMaxSortModel, err error) {
+func (s *sAdminPost) MaxSort(ctx context.Context, in *adminin.PostMaxSortInp) (res *adminin.PostMaxSortModel, err error) {
if in.Id > 0 {
- if err = dao.AdminMenu.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
+ if err = dao.AdminPost.Ctx(ctx).WherePri(in.Id).OrderDesc(dao.AdminPost.Columns().Sort).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
@@ -96,119 +108,73 @@ func (s *sAdminPost) MaxSort(ctx context.Context, in adminin.PostMaxSortInp) (re
if res == nil {
res = new(adminin.PostMaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
- return
-}
-
-// NameUnique 菜单名称是否唯一
-func (s *sAdminPost) NameUnique(ctx context.Context, in adminin.PostNameUniqueInp) (res *adminin.PostNameUniqueModel, err error) {
- isUnique, err := dao.AdminPost.IsUniqueName(ctx, in.Id, in.Name)
- if err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
- return
- }
-
- res = new(adminin.PostNameUniqueModel)
- res.IsUnique = isUnique
- return
-}
-
-// CodeUnique 编码是否唯一
-func (s *sAdminPost) CodeUnique(ctx context.Context, in adminin.PostCodeUniqueInp) (res *adminin.PostCodeUniqueModel, err error) {
- isUnique, err := dao.AdminPost.IsUniqueCode(ctx, in.Id, in.Code)
- if err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
- return
- }
-
- res = new(adminin.PostCodeUniqueModel)
- res.IsUnique = isUnique
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
// View 获取指定岗位信息
-func (s *sAdminPost) View(ctx context.Context, in adminin.PostViewInp) (res *adminin.PostViewModel, err error) {
- err = dao.AdminPost.Ctx(ctx).Where("id", in.Id).Scan(&res)
+func (s *sAdminPost) View(ctx context.Context, in *adminin.PostViewInp) (res *adminin.PostViewModel, err error) {
+ err = dao.AdminPost.Ctx(ctx).WherePri(in.Id).Scan(&res)
return
}
// List 获取列表
-func (s *sAdminPost) List(ctx context.Context, in adminin.PostListInp) (list []*adminin.PostListModel, totalCount int, err error) {
+func (s *sAdminPost) List(ctx context.Context, in *adminin.PostListInp) (list []*adminin.PostListModel, totalCount int, err error) {
mod := dao.AdminPost.Ctx(ctx)
+ cols := dao.AdminPost.Columns()
// 访问路径
if in.Name != "" {
- mod = mod.WhereLike("name", "%"+in.Name+"%")
+ mod = mod.WhereLike(cols.Name, "%"+in.Name+"%")
}
// 模块
if in.Code != "" {
- mod = mod.Where("code", in.Code)
+ mod = mod.Where(cols.Code, in.Code)
}
// 请求方式
if in.Status > 0 {
- mod = mod.Where("status", in.Status)
+ mod = mod.Where(cols.Status, in.Status)
+ }
+
+ if len(in.CreatedAt) == 2 {
+ mod = mod.WhereBetween(cols.CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
}
totalCount, err = mod.Count()
if err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
+ err = gerror.Wrap(err, "获取岗位列表失败!")
return
}
if totalCount == 0 {
- return list, totalCount, nil
+ return
}
- err = mod.Page(in.Page, in.PerPage).Order("id asc").Scan(&list)
+ err = mod.Page(in.Page, in.PerPage).OrderAsc(cols.Sort).Scan(&list)
return
}
// GetMemberByStartName 获取指定用户的第一岗位
func (s *sAdminPost) GetMemberByStartName(ctx context.Context, memberId int64) (name string, err error) {
// 默认取第一岗位
- postId, err := dao.AdminMemberPost.Ctx(ctx).
- Fields("post_id").
- Where("member_id", memberId).
- Limit(1).
- Value()
+ postId, err := dao.AdminMemberPost.Ctx(ctx).Fields(dao.AdminMemberPost.Columns().PostId).Where(dao.AdminMemberPost.Columns().MemberId, memberId).Limit(1).Value()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
- val, err := dao.AdminPost.Ctx(ctx).
- Fields("name").
- Where("id", postId.Int()).
- Order("id desc").
- Value()
+ val, err := dao.AdminPost.Ctx(ctx).Fields(dao.AdminPost.Columns().Name).WherePri(postId.Int()).OrderDesc(dao.AdminPost.Columns().Id).Value()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
-
return val.String(), nil
}
// Status 更新状态
-func (s *sAdminPost) Status(ctx context.Context, in adminin.PostStatusInp) (err error) {
- if in.Id <= 0 {
- err = gerror.New("ID不能为空")
- return
- }
-
- if in.Status <= 0 {
- err = gerror.New("状态不能为空")
- return
- }
-
- if !validate.InSlice(consts.StatusSlice, in.Status) {
- err = gerror.New("状态不正确")
- return
- }
-
- // 修改
- _, err = dao.AdminPost.Ctx(ctx).Where("id", in.Id).Data("status", in.Status).Update()
+func (s *sAdminPost) Status(ctx context.Context, in *adminin.PostStatusInp) (err error) {
+ _, err = dao.AdminPost.Ctx(ctx).WherePri(in.Id).Data(dao.AdminPost.Columns().Status, in.Status).Update()
return
}
diff --git a/server/internal/logic/admin/role.go b/server/internal/logic/admin/role.go
index efe9186..6355572 100644
--- a/server/internal/logic/admin/role.go
+++ b/server/internal/logic/admin/role.go
@@ -39,7 +39,6 @@ func init() {
func (s *sAdminRole) Verify(ctx context.Context, path, method string) bool {
var (
user = contexts.Get(ctx).User
- sk = g.Cfg().MustGet(ctx, "hotgo.admin.superRoleKey")
err error
)
@@ -48,7 +47,7 @@ func (s *sAdminRole) Verify(ctx context.Context, path, method string) bool {
return false
}
- if service.AdminMember().VerifySuperId(ctx, user.Id) || user.RoleKey == sk.String() {
+ if service.AdminMember().VerifySuperId(ctx, user.Id) {
return true
}
@@ -61,7 +60,7 @@ func (s *sAdminRole) Verify(ctx context.Context, path, method string) bool {
}
// List 获取列表
-func (s *sAdminRole) List(ctx context.Context, in adminin.RoleListInp) (res *adminin.RoleListModel, totalCount int, err error) {
+func (s *sAdminRole) List(ctx context.Context, in *adminin.RoleListInp) (res *adminin.RoleListModel, totalCount int, err error) {
var (
mod = dao.AdminRole.Ctx(ctx)
models []*entity.AdminRole
@@ -113,11 +112,8 @@ func (s *sAdminRole) GetMemberList(ctx context.Context, id int64) (list []*admin
}
// GetPermissions 更改角色菜单权限
-func (s *sAdminRole) GetPermissions(ctx context.Context, in adminin.GetPermissionsInp) (res *adminin.GetPermissionsModel, err error) {
- values, err := dao.AdminRoleMenu.Ctx(ctx).
- Fields("menu_id").
- Where("role_id", in.RoleId).
- Array()
+func (s *sAdminRole) GetPermissions(ctx context.Context, in *adminin.GetPermissionsInp) (res *adminin.GetPermissionsModel, err error) {
+ values, err := dao.AdminRoleMenu.Ctx(ctx).Fields("menu_id").Where("role_id", in.RoleId).Array()
if err != nil {
return
}
@@ -134,7 +130,7 @@ func (s *sAdminRole) GetPermissions(ctx context.Context, in adminin.GetPermissio
}
// UpdatePermissions 更改角色菜单权限
-func (s *sAdminRole) UpdatePermissions(ctx context.Context, in adminin.UpdatePermissionsInp) (err error) {
+func (s *sAdminRole) UpdatePermissions(ctx context.Context, in *adminin.UpdatePermissionsInp) (err error) {
err = dao.AdminRoleMenu.Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
if _, err = dao.AdminRoleMenu.Ctx(ctx).Where("role_id", in.RoleId).Delete(); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -166,7 +162,7 @@ func (s *sAdminRole) UpdatePermissions(ctx context.Context, in adminin.UpdatePer
return casbin.Refresh(ctx)
}
-func (s *sAdminRole) Edit(ctx context.Context, in adminin.RoleEditInp) (err error) {
+func (s *sAdminRole) Edit(ctx context.Context, in *adminin.RoleEditInp) (err error) {
if err = hgorm.IsUnique(ctx, &dao.AdminRole, g.Map{dao.AdminRole.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
return
}
@@ -231,7 +227,7 @@ func updateRoleChildrenTree(ctx context.Context, _id int64, _level int, _tree st
return
}
-func (s *sAdminRole) Delete(ctx context.Context, in adminin.RoleDeleteInp) (err error) {
+func (s *sAdminRole) Delete(ctx context.Context, in *adminin.RoleDeleteInp) (err error) {
var models *entity.AdminRole
if err = dao.AdminRole.Ctx(ctx).Where("id", in.Id).Scan(&models); err != nil {
return
@@ -270,11 +266,7 @@ func (s *sAdminRole) DataScopeSelect() (res form.Selects) {
}
func (s *sAdminRole) DataScopeEdit(ctx context.Context, in *adminin.DataScopeEditInp) (err error) {
- var (
- models *entity.AdminRole
- sk = g.Cfg().MustGet(ctx, "hotgo.admin.superRoleKey")
- )
-
+ var models *entity.AdminRole
if err = dao.AdminRole.Ctx(ctx).Where("id", in.Id).Scan(&models); err != nil {
return
}
@@ -283,7 +275,7 @@ func (s *sAdminRole) DataScopeEdit(ctx context.Context, in *adminin.DataScopeEdi
return gerror.New("角色不存在")
}
- if models.Key == sk.String() {
+ if models.Key == consts.SuperRoleKey {
return gerror.New("超管角色拥有全部权限,无需修改!")
}
diff --git a/server/internal/logic/admin/site.go b/server/internal/logic/admin/site.go
index 8887b4c..b9221d2 100644
--- a/server/internal/logic/admin/site.go
+++ b/server/internal/logic/admin/site.go
@@ -30,7 +30,7 @@ func init() {
}
// Register 账号注册
-func (s *sAdminSite) Register(ctx context.Context, in adminin.RegisterInp) (err error) {
+func (s *sAdminSite) Register(ctx context.Context, in *adminin.RegisterInp) (err error) {
config, err := service.SysConfig().GetLogin(ctx)
if err != nil {
return
@@ -42,12 +42,13 @@ func (s *sAdminSite) Register(ctx context.Context, in adminin.RegisterInp) (err
}
var data adminin.MemberAddInp
+
// 默认上级
data.Pid = 1
// 存在邀请人
if in.InviteCode != "" {
- pmb, err := service.AdminMember().GetIdByCode(ctx, adminin.GetIdByCodeInp{Code: in.InviteCode})
+ pmb, err := service.AdminMember().GetIdByCode(ctx, &adminin.GetIdByCodeInp{Code: in.InviteCode})
if err != nil {
return err
}
@@ -81,7 +82,7 @@ func (s *sAdminSite) Register(ctx context.Context, in adminin.RegisterInp) (err
}
// 验证唯一性
- err = service.AdminMember().VerifyUnique(ctx, adminin.VerifyUniqueInp{
+ err = service.AdminMember().VerifyUnique(ctx, &adminin.VerifyUniqueInp{
Where: g.Map{
dao.AdminMember.Columns().Username: in.Username,
dao.AdminMember.Columns().Mobile: in.Mobile,
@@ -92,7 +93,7 @@ func (s *sAdminSite) Register(ctx context.Context, in adminin.RegisterInp) (err
}
// 验证短信验证码
- err = service.SysSmsLog().VerifyCode(ctx, sysin.VerifyCodeInp{
+ err = service.SysSmsLog().VerifyCode(ctx, &sysin.VerifyCodeInp{
Event: consts.SmsTemplateRegister,
Mobile: in.Mobile,
Code: in.Code,
@@ -101,7 +102,7 @@ func (s *sAdminSite) Register(ctx context.Context, in adminin.RegisterInp) (err
return
}
- data.MemberEditInp = adminin.MemberEditInp{
+ data.MemberEditInp = &adminin.MemberEditInp{
Id: 0,
RoleId: config.RoleId,
PostIds: config.PostIds,
@@ -139,9 +140,9 @@ func (s *sAdminSite) Register(ctx context.Context, in adminin.RegisterInp) (err
}
// AccountLogin 账号登录
-func (s *sAdminSite) AccountLogin(ctx context.Context, in adminin.AccountLoginInp) (res *adminin.LoginModel, err error) {
+func (s *sAdminSite) AccountLogin(ctx context.Context, in *adminin.AccountLoginInp) (res *adminin.LoginModel, err error) {
defer func() {
- service.SysLoginLog().Push(ctx, sysin.LoginLogPushInp{Response: res, Err: err})
+ service.SysLoginLog().Push(ctx, &sysin.LoginLogPushInp{Response: res, Err: err})
}()
var mb *entity.AdminMember
@@ -177,9 +178,9 @@ func (s *sAdminSite) AccountLogin(ctx context.Context, in adminin.AccountLoginIn
}
// MobileLogin 手机号登录
-func (s *sAdminSite) MobileLogin(ctx context.Context, in adminin.MobileLoginInp) (res *adminin.LoginModel, err error) {
+func (s *sAdminSite) MobileLogin(ctx context.Context, in *adminin.MobileLoginInp) (res *adminin.LoginModel, err error) {
defer func() {
- service.SysLoginLog().Push(ctx, sysin.LoginLogPushInp{Response: res, Err: err})
+ service.SysLoginLog().Push(ctx, &sysin.LoginLogPushInp{Response: res, Err: err})
}()
var mb *entity.AdminMember
@@ -197,7 +198,7 @@ func (s *sAdminSite) MobileLogin(ctx context.Context, in adminin.MobileLoginInp)
res.Id = mb.Id
res.Username = mb.Username
- err = service.SysSmsLog().VerifyCode(ctx, sysin.VerifyCodeInp{
+ err = service.SysSmsLog().VerifyCode(ctx, &sysin.VerifyCodeInp{
Event: consts.SmsTemplateLogin,
Mobile: in.Mobile,
Code: in.Code,
@@ -249,7 +250,7 @@ func (s *sAdminSite) handleLogin(ctx context.Context, mb *entity.AdminMember) (r
LoginAt: gtime.Now(),
}
- loginToken, expires, err := token.Login(ctx, user)
+ lt, expires, err := token.Login(ctx, user)
if err != nil {
return nil, err
}
@@ -257,7 +258,7 @@ func (s *sAdminSite) handleLogin(ctx context.Context, mb *entity.AdminMember) (r
res = &adminin.LoginModel{
Username: user.Username,
Id: user.Id,
- Token: loginToken,
+ Token: lt,
Expires: expires,
}
return
diff --git a/server/internal/logic/common/upload.go b/server/internal/logic/common/upload.go
index 3be90d1..07b8036 100644
--- a/server/internal/logic/common/upload.go
+++ b/server/internal/logic/common/upload.go
@@ -8,7 +8,6 @@ package common
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
- "hotgo/internal/consts"
"hotgo/internal/library/storager"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
@@ -26,23 +25,8 @@ func init() {
}
// UploadFile 上传文件
-func (s *sCommonUpload) UploadFile(ctx context.Context, file *ghttp.UploadFile) (res *sysin.AttachmentListModel, err error) {
- attachment, err := storager.DoUpload(ctx, file, consts.UploadTypeFile)
- if err != nil {
- return
- }
-
- attachment.FileUrl = storager.LastUrl(ctx, attachment.FileUrl, attachment.Drive)
- res = &sysin.AttachmentListModel{
- SysAttachment: *attachment,
- SizeFormat: format.FileSize(attachment.Size),
- }
- return
-}
-
-// UploadImage 上传图片
-func (s *sCommonUpload) UploadImage(ctx context.Context, file *ghttp.UploadFile) (res *sysin.AttachmentListModel, err error) {
- attachment, err := storager.DoUpload(ctx, file, consts.UploadTypeImage)
+func (s *sCommonUpload) UploadFile(ctx context.Context, uploadType string, file *ghttp.UploadFile) (res *sysin.AttachmentListModel, err error) {
+ attachment, err := storager.DoUpload(ctx, uploadType, file)
if err != nil {
return
}
diff --git a/server/internal/logic/common/wechat.go b/server/internal/logic/common/wechat.go
index d01cb3b..1e269db 100644
--- a/server/internal/logic/common/wechat.go
+++ b/server/internal/logic/common/wechat.go
@@ -53,7 +53,7 @@ func init() {
}
// Authorize 微信用户授权
-func (s *sCommonWechat) Authorize(ctx context.Context, in commonin.WechatAuthorizeInp) (res *commonin.WechatAuthorizeModel, err error) {
+func (s *sCommonWechat) Authorize(ctx context.Context, in *commonin.WechatAuthorizeInp) (res *commonin.WechatAuthorizeModel, err error) {
basic, err := service.SysConfig().GetBasic(ctx)
if err != nil {
return
@@ -100,7 +100,7 @@ func (s *sCommonWechat) Authorize(ctx context.Context, in commonin.WechatAuthori
return
}
-func (s *sCommonWechat) AuthorizeCall(ctx context.Context, in commonin.WechatAuthorizeCallInp) (res *commonin.WechatAuthorizeCallModel, err error) {
+func (s *sCommonWechat) AuthorizeCall(ctx context.Context, in *commonin.WechatAuthorizeCallInp) (res *commonin.WechatAuthorizeCallModel, err error) {
data, ok := s.temp[in.State]
if !ok || data == nil {
err = gerror.New("授权无效或已过期,请重试")
diff --git a/server/internal/logic/logic.go b/server/internal/logic/logic.go
index 7a375c1..84ee81d 100644
--- a/server/internal/logic/logic.go
+++ b/server/internal/logic/logic.go
@@ -1,5 +1,5 @@
// ==========================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
diff --git a/server/internal/logic/middleware/init.go b/server/internal/logic/middleware/init.go
index 9f12804..d40723b 100644
--- a/server/internal/logic/middleware/init.go
+++ b/server/internal/logic/middleware/init.go
@@ -30,8 +30,9 @@ import (
)
type sMiddleware struct {
- LoginUrl string // 登录路由地址
- DemoWhiteList g.Map // 演示模式放行的路由白名单
+ LoginUrl string // 登录路由地址
+ DemoWhiteList g.Map // 演示模式放行的路由白名单
+ FilterRoutes map[string]ghttp.RouterItem // 支持预处理的web路由
}
func init() {
diff --git a/server/internal/logic/middleware/pre_filter.go b/server/internal/logic/middleware/pre_filter.go
new file mode 100644
index 0000000..8102b74
--- /dev/null
+++ b/server/internal/logic/middleware/pre_filter.go
@@ -0,0 +1,83 @@
+package middleware
+
+import (
+ "github.com/gogf/gf/v2/errors/gcode"
+ "github.com/gogf/gf/v2/net/ghttp"
+ "github.com/gogf/gf/v2/util/gconv"
+ "hotgo/internal/library/response"
+ "hotgo/utility/validate"
+ "reflect"
+)
+
+// GetFilterRoutes 获取支持预处理的web路由
+func (s *sMiddleware) GetFilterRoutes(r *ghttp.Request) map[string]ghttp.RouterItem {
+ // 首次访问时加载
+ if s.FilterRoutes == nil {
+ s.FilterRoutes = make(map[string]ghttp.RouterItem)
+ for _, v := range r.Server.GetRoutes() {
+ // 非规范路由不加载
+ if v.Handler.Info.Type.NumIn() != 2 {
+ continue
+ }
+
+ key := s.GenFilterRouteKey(v.Handler.Router)
+ if _, ok := s.FilterRoutes[key]; !ok {
+ s.FilterRoutes[key] = v
+ }
+ }
+ }
+ return s.FilterRoutes
+}
+
+// GenFilterRouteKey 生成路由唯一key
+func (s *sMiddleware) GenFilterRouteKey(router *ghttp.Router) string {
+ return router.Method + " " + router.Uri
+}
+
+// PreFilter 请求输入预处理
+// api使用gf规范路由并且XxxReq结构体实现了validate.Filter接口即可
+func (s *sMiddleware) PreFilter(r *ghttp.Request) {
+ router, ok := s.GetFilterRoutes(r)[s.GenFilterRouteKey(r.Router)]
+ if !ok {
+ r.Middleware.Next()
+ return
+ }
+
+ funcInfo := router.Handler.Info
+
+ // 非规范路由不处理
+ if funcInfo.Type.NumIn() != 2 {
+ r.Middleware.Next()
+ return
+ }
+
+ inputType := funcInfo.Type.In(1)
+ var inputObject reflect.Value
+ if inputType.Kind() == reflect.Ptr {
+ inputObject = reflect.New(inputType.Elem())
+ } else {
+ inputObject = reflect.New(inputType.Elem()).Elem()
+ }
+
+ // 先验证基本校验规则
+ if err := r.Parse(inputObject.Interface()); err != nil {
+ response.JsonExit(r, gcode.CodeInvalidRequest.Code(), err.Error())
+ return
+ }
+
+ // 没有实现预处理
+ if _, ok = inputObject.Interface().(validate.Filter); !ok {
+ r.Middleware.Next()
+ return
+ }
+
+ // 执行预处理
+ if err := validate.PreFilter(r.Context(), inputObject.Interface()); err != nil {
+ response.JsonExit(r, gcode.CodeInvalidParameter.Code(), err.Error())
+ return
+ }
+
+ // 过滤后的参数
+ r.SetParamMap(gconv.Map(inputObject.Interface()))
+ r.Middleware.Next()
+}
diff --git a/server/internal/logic/middleware/response.go b/server/internal/logic/middleware/response.go
index 3388061..f41d8b2 100644
--- a/server/internal/logic/middleware/response.go
+++ b/server/internal/logic/middleware/response.go
@@ -50,14 +50,12 @@ func (s *sMiddleware) responseHtml(r *ghttp.Request) {
r.Response.ClearBuffer()
_ = r.Response.WriteTplContent(simple.DefaultErrorTplContent(r.Context()), g.Map{"code": code, "message": message, "stack": resp})
- return
}
// responseXml xml响应
func (s *sMiddleware) responseXml(r *ghttp.Request) {
code, message, data := parseResponse(r)
response.RXml(r, code, message, data)
- return
}
// responseJson json响应
diff --git a/server/internal/logic/pay/notify.go b/server/internal/logic/pay/notify.go
index b3e5f0a..10968a9 100644
--- a/server/internal/logic/pay/notify.go
+++ b/server/internal/logic/pay/notify.go
@@ -18,7 +18,7 @@ import (
)
// Notify 异步通知
-func (s *sPay) Notify(ctx context.Context, in payin.PayNotifyInp) (res *payin.PayNotifyModel, err error) {
+func (s *sPay) Notify(ctx context.Context, in *payin.PayNotifyInp) (res *payin.PayNotifyModel, err error) {
data, err := payment.New(in.PayType).Notify(ctx, payin.NotifyInp{})
if err != nil {
return
@@ -80,6 +80,6 @@ func (s *sPay) Notify(ctx context.Context, in payin.PayNotifyInp) (res *payin.Pa
}
// 回调业务
- payment.NotifyCall(ctx, payin.NotifyCallFuncInp{Pay: models})
+ payment.NotifyCall(ctx, &payin.NotifyCallFuncInp{Pay: models})
return
}
diff --git a/server/internal/logic/pay/refund.go b/server/internal/logic/pay/refund.go
index 4436ae5..6c410c5 100644
--- a/server/internal/logic/pay/refund.go
+++ b/server/internal/logic/pay/refund.go
@@ -49,7 +49,7 @@ func (s *sPayRefund) Model(ctx context.Context, option ...*handler.Option) *gdb.
}
// Refund 订单退款
-func (s *sPayRefund) Refund(ctx context.Context, in payin.PayRefundInp) (res *payin.PayRefundModel, err error) {
+func (s *sPayRefund) Refund(ctx context.Context, in *payin.PayRefundInp) (res *payin.PayRefundModel, err error) {
var models *entity.PayLog
if err = service.Pay().Model(ctx).Where(dao.PayLog.Columns().OrderSn, in.OrderSn).Scan(&models); err != nil {
return
@@ -135,12 +135,11 @@ func (s *sPayRefund) Refund(ctx context.Context, in payin.PayRefundInp) (res *pa
if _, err = s.Model(ctx).Data(data).Insert(); err != nil {
return
}
-
return
}
// List 获取交易退款列表
-func (s *sPayRefund) List(ctx context.Context, in payin.PayRefundListInp) (list []*payin.PayRefundListModel, totalCount int, err error) {
+func (s *sPayRefund) List(ctx context.Context, in *payin.PayRefundListInp) (list []*payin.PayRefundListModel, totalCount int, err error) {
mod := s.Model(ctx)
// 查询变动ID
@@ -192,7 +191,7 @@ func (s *sPayRefund) List(ctx context.Context, in payin.PayRefundListInp) (list
}
// Export 导出交易退款
-func (s *sPayRefund) Export(ctx context.Context, in payin.PayRefundListInp) (err error) {
+func (s *sPayRefund) Export(ctx context.Context, in *payin.PayRefundListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
diff --git a/server/internal/logic/sys/addons.go b/server/internal/logic/sys/addons.go
index 74d2c3c..e6773a2 100644
--- a/server/internal/logic/sys/addons.go
+++ b/server/internal/logic/sys/addons.go
@@ -28,7 +28,7 @@ func init() {
}
// List 获取列表
-func (s *sSysAddons) List(ctx context.Context, in sysin.AddonsListInp) (list []*sysin.AddonsListModel, totalCount int, err error) {
+func (s *sSysAddons) List(ctx context.Context, in *sysin.AddonsListInp) (list []*sysin.AddonsListModel, totalCount int, err error) {
sks := addons.GetSkeletons()
if len(sks) == 0 {
return
@@ -36,7 +36,7 @@ func (s *sSysAddons) List(ctx context.Context, in sysin.AddonsListInp) (list []*
var (
i int
- _, perPage, offset = form.CalPage(ctx, in.Page, in.PerPage)
+ _, perPage, offset = form.CalPage(in.Page, in.PerPage)
)
for k, skeleton := range sks {
@@ -94,7 +94,7 @@ func (s *sSysAddons) List(ctx context.Context, in sysin.AddonsListInp) (list []*
}
// Selects 选项
-func (s *sSysAddons) Selects(ctx context.Context, in sysin.AddonsSelectsInp) (res *sysin.AddonsSelectsModel, err error) {
+func (s *sSysAddons) Selects(ctx context.Context, in *sysin.AddonsSelectsInp) (res *sysin.AddonsSelectsModel, err error) {
res = new(sysin.AddonsSelectsModel)
for k, v := range consts.AddonsGroupNameMap {
res.GroupType = append(res.GroupType, &form.Select{
@@ -118,7 +118,7 @@ func (s *sSysAddons) Selects(ctx context.Context, in sysin.AddonsSelectsInp) (re
}
// Build 提交生成
-func (s *sSysAddons) Build(ctx context.Context, in sysin.AddonsBuildInp) (err error) {
+func (s *sSysAddons) Build(ctx context.Context, in *sysin.AddonsBuildInp) (err error) {
genConfig, err := service.SysConfig().GetLoadGenerate(ctx)
if err != nil {
return
@@ -132,16 +132,16 @@ func (s *sSysAddons) Build(ctx context.Context, in sysin.AddonsBuildInp) (err er
}
// Install 安装模块
-func (s *sSysAddons) Install(ctx context.Context, in sysin.AddonsInstallInp) (err error) {
+func (s *sSysAddons) Install(ctx context.Context, in *sysin.AddonsInstallInp) (err error) {
return addons.Install(in.GetModule())
}
// Upgrade 更新模块
-func (s *sSysAddons) Upgrade(ctx context.Context, in sysin.AddonsUpgradeInp) (err error) {
+func (s *sSysAddons) Upgrade(ctx context.Context, in *sysin.AddonsUpgradeInp) (err error) {
return addons.Upgrade(in.GetModule())
}
// UnInstall 卸载模块
-func (s *sSysAddons) UnInstall(ctx context.Context, in sysin.AddonsUnInstallInp) (err error) {
+func (s *sSysAddons) UnInstall(ctx context.Context, in *sysin.AddonsUnInstallInp) (err error) {
return addons.UnInstall(in.GetModule())
}
diff --git a/server/internal/logic/sys/addons_config.go b/server/internal/logic/sys/addons_config.go
index edad31d..1381520 100644
--- a/server/internal/logic/sys/addons_config.go
+++ b/server/internal/logic/sys/addons_config.go
@@ -32,7 +32,7 @@ func init() {
}
// GetConfigByGroup 获取指定分组的配置
-func (s *sSysAddonsConfig) GetConfigByGroup(ctx context.Context, in sysin.GetAddonsConfigInp) (res *sysin.GetAddonsConfigModel, err error) {
+func (s *sSysAddonsConfig) GetConfigByGroup(ctx context.Context, in *sysin.GetAddonsConfigInp) (res *sysin.GetAddonsConfigModel, err error) {
if in.AddonName == "" {
err = gerror.New("插件名称不能为空")
return
@@ -84,7 +84,7 @@ func (s *sSysAddonsConfig) ConversionType(ctx context.Context, models *entity.Sy
}
// UpdateConfigByGroup 更新指定分组的配置
-func (s *sSysAddonsConfig) UpdateConfigByGroup(ctx context.Context, in sysin.UpdateAddonsConfigInp) (err error) {
+func (s *sSysAddonsConfig) UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateAddonsConfigInp) (err error) {
if in.AddonName == "" {
err = gerror.New("插件名称不能为空")
return
diff --git a/server/internal/logic/sys/attachment.go b/server/internal/logic/sys/attachment.go
index 9c76db1..d4f6673 100644
--- a/server/internal/logic/sys/attachment.go
+++ b/server/internal/logic/sys/attachment.go
@@ -10,6 +10,7 @@ import (
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"hotgo/internal/dao"
+ "hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm/handler"
"hotgo/internal/library/storager"
"hotgo/internal/model/input/sysin"
@@ -33,7 +34,7 @@ func (s *sSysAttachment) Model(ctx context.Context, option ...*handler.Option) *
}
// Delete 删除附件
-func (s *sSysAttachment) Delete(ctx context.Context, in sysin.AttachmentDeleteInp) (err error) {
+func (s *sSysAttachment) Delete(ctx context.Context, in *sysin.AttachmentDeleteInp) (err error) {
if _, err = s.Model(ctx).WherePri(in.Id).Delete(); err != nil {
err = gerror.Wrap(err, "删除附件失败,请稍后重试!")
}
@@ -41,7 +42,7 @@ func (s *sSysAttachment) Delete(ctx context.Context, in sysin.AttachmentDeleteIn
}
// View 获取附件信息
-func (s *sSysAttachment) View(ctx context.Context, in sysin.AttachmentViewInp) (res *sysin.AttachmentViewModel, err error) {
+func (s *sSysAttachment) View(ctx context.Context, in *sysin.AttachmentViewInp) (res *sysin.AttachmentViewModel, err error) {
if err = s.Model(ctx).WherePri(in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取附件信息失败,请稍后重试!")
}
@@ -49,21 +50,37 @@ func (s *sSysAttachment) View(ctx context.Context, in sysin.AttachmentViewInp) (
}
// List 获取附件列表
-func (s *sSysAttachment) List(ctx context.Context, in sysin.AttachmentListInp) (list []*sysin.AttachmentListModel, totalCount int, err error) {
+func (s *sSysAttachment) List(ctx context.Context, in *sysin.AttachmentListInp) (list []*sysin.AttachmentListModel, totalCount int, err error) {
mod := s.Model(ctx)
+ memberId := contexts.GetUserId(ctx)
- if in.MemberId > 0 {
+ // 超管允许查看指定用户的附件
+ if service.AdminMember().VerifySuperId(ctx, memberId) && in.MemberId > 0 {
mod = mod.Where(dao.SysAttachment.Columns().MemberId, in.MemberId)
+ } else {
+ mod = mod.Where(dao.SysAttachment.Columns().MemberId, memberId)
}
if in.Drive != "" {
mod = mod.Where(dao.SysAttachment.Columns().Drive, in.Drive)
}
+ if in.Name != "" {
+ mod = mod.WhereLike(dao.SysAttachment.Columns().Name, "%"+in.Name+"%")
+ }
+
if in.Status > 0 {
mod = mod.Where(dao.SysAttachment.Columns().Status, in.Status)
}
+ if len(in.UpdatedAt) == 2 {
+ mod = mod.WhereBetween(dao.SysAttachment.Columns().UpdatedAt, in.UpdatedAt[0], in.UpdatedAt[1])
+ }
+
+ if in.Kind != "" {
+ mod = mod.Where(dao.SysAttachment.Columns().Kind, in.Kind)
+ }
+
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, "获取附件数据行失败!")
@@ -85,3 +102,12 @@ func (s *sSysAttachment) List(ctx context.Context, in sysin.AttachmentListInp) (
}
return
}
+
+// ClearKind 清空上传类型
+func (s *sSysAttachment) ClearKind(ctx context.Context, in *sysin.AttachmentClearKindInp) (err error) {
+ memberId := contexts.GetUserId(ctx)
+ if _, err = s.Model(ctx).Where(dao.SysAttachment.Columns().MemberId, memberId).Where(dao.SysAttachment.Columns().Kind, in.Kind).Delete(); err != nil {
+ err = gerror.Wrap(err, "删除附件上传类型失败,请稍后重试!")
+ }
+ return
+}
diff --git a/server/internal/logic/sys/blacklist.go b/server/internal/logic/sys/blacklist.go
index d75225a..e242634 100644
--- a/server/internal/logic/sys/blacklist.go
+++ b/server/internal/logic/sys/blacklist.go
@@ -9,14 +9,13 @@ import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gtime"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/global"
- "hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
"hotgo/utility/convert"
- "hotgo/utility/validate"
"sync"
)
@@ -33,14 +32,14 @@ func init() {
}
// Delete 删除
-func (s *sSysBlacklist) Delete(ctx context.Context, in sysin.BlacklistDeleteInp) (err error) {
+func (s *sSysBlacklist) Delete(ctx context.Context, in *sysin.BlacklistDeleteInp) (err error) {
defer s.VariableLoad(ctx, err)
_, err = dao.SysBlacklist.Ctx(ctx).Where("id", in.Id).Delete()
return
}
// Edit 修改/新增
-func (s *sSysBlacklist) Edit(ctx context.Context, in sysin.BlacklistEditInp) (err error) {
+func (s *sSysBlacklist) Edit(ctx context.Context, in *sysin.BlacklistEditInp) (err error) {
defer s.VariableLoad(ctx, err)
if in.Ip == "" {
err = gerror.New("ip不能为空")
@@ -59,62 +58,38 @@ func (s *sSysBlacklist) Edit(ctx context.Context, in sysin.BlacklistEditInp) (er
}
// Status 更新部门状态
-func (s *sSysBlacklist) Status(ctx context.Context, in sysin.BlacklistStatusInp) (err error) {
+func (s *sSysBlacklist) Status(ctx context.Context, in *sysin.BlacklistStatusInp) (err error) {
defer s.VariableLoad(ctx, err)
- if in.Id <= 0 {
- err = gerror.New("ID不能为空")
- return
- }
-
- if in.Status <= 0 {
- err = gerror.New("状态不能为空")
- return
- }
-
- if !validate.InSlice(consts.StatusSlice, in.Status) {
- err = gerror.New("状态不正确")
- return
- }
-
// 修改
_, err = dao.SysBlacklist.Ctx(ctx).Where("id", in.Id).Data("status", in.Status).Update()
return
}
-// MaxSort 最大排序
-func (s *sSysBlacklist) MaxSort(ctx context.Context, in sysin.BlacklistMaxSortInp) (res *sysin.BlacklistMaxSortModel, err error) {
- if in.Id > 0 {
- if err = dao.SysBlacklist.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
- return
- }
- }
-
- if res == nil {
- res = new(sysin.BlacklistMaxSortModel)
- }
-
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
- return
-}
-
// View 获取指定字典类型信息
-func (s *sSysBlacklist) View(ctx context.Context, in sysin.BlacklistViewInp) (res *sysin.BlacklistViewModel, err error) {
+func (s *sSysBlacklist) View(ctx context.Context, in *sysin.BlacklistViewInp) (res *sysin.BlacklistViewModel, err error) {
err = dao.SysBlacklist.Ctx(ctx).Where("id", in.Id).Scan(&res)
return
}
// List 获取列表
-func (s *sSysBlacklist) List(ctx context.Context, in sysin.BlacklistListInp) (list []*sysin.BlacklistListModel, totalCount int, err error) {
+func (s *sSysBlacklist) List(ctx context.Context, in *sysin.BlacklistListInp) (list []*sysin.BlacklistListModel, totalCount int, err error) {
mod := dao.SysBlacklist.Ctx(ctx)
+ cols := dao.SysBlacklist.Columns()
- // 访问路径
if in.Ip != "" {
- mod = mod.Where("ip", in.Ip)
+ mod = mod.WhereLike(cols.Ip, "%"+in.Ip+"%")
+ }
+
+ if in.Remark != "" {
+ mod = mod.WhereLike(cols.Remark, "%"+in.Remark+"%")
}
- // 请求方式
if in.Status > 0 {
- mod = mod.Where("status", in.Status)
+ mod = mod.Where(cols.Status, in.Status)
+ }
+
+ if len(in.CreatedAt) == 2 {
+ mod = mod.WhereBetween(cols.CreatedAt, gtime.New(in.CreatedAt[0]), gtime.New(in.CreatedAt[1]))
}
totalCount, err = mod.Count()
diff --git a/server/internal/logic/sys/config.go b/server/internal/logic/sys/config.go
index 428c9b1..74dc0ec 100644
--- a/server/internal/logic/sys/config.go
+++ b/server/internal/logic/sys/config.go
@@ -16,6 +16,7 @@ import (
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/payment"
+ "hotgo/internal/library/sms"
"hotgo/internal/library/storager"
"hotgo/internal/library/token"
"hotgo/internal/library/wechat"
@@ -56,6 +57,12 @@ func (s *sSysConfig) InitConfig(ctx context.Context) {
}
storager.SetConfig(upload)
+ sm, err := s.GetSms(ctx)
+ if err != nil {
+ g.Log().Fatalf(ctx, "init sms conifg fail:%+v", err)
+ }
+ sms.SetConfig(sm)
+
tk, err := s.GetLoadToken(ctx)
if err != nil {
g.Log().Fatalf(ctx, "init token conifg fail:%+v", err)
@@ -65,7 +72,7 @@ func (s *sSysConfig) InitConfig(ctx context.Context) {
// GetLogin 获取登录配置
func (s *sSysConfig) GetLogin(ctx context.Context) (conf *model.LoginConfig, err error) {
- models, err := s.GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "login"})
+ models, err := s.GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "login"})
if err != nil {
return
}
@@ -75,7 +82,7 @@ func (s *sSysConfig) GetLogin(ctx context.Context) (conf *model.LoginConfig, err
// GetWechat 获取微信配置
func (s *sSysConfig) GetWechat(ctx context.Context) (conf *model.WechatConfig, err error) {
- models, err := s.GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "wechat"})
+ models, err := s.GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "wechat"})
if err != nil {
return
}
@@ -85,7 +92,7 @@ func (s *sSysConfig) GetWechat(ctx context.Context) (conf *model.WechatConfig, e
// GetPay 获取支付配置
func (s *sSysConfig) GetPay(ctx context.Context) (conf *model.PayConfig, err error) {
- models, err := s.GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "pay"})
+ models, err := s.GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "pay"})
if err != nil {
return
}
@@ -95,7 +102,7 @@ func (s *sSysConfig) GetPay(ctx context.Context) (conf *model.PayConfig, err err
// GetSms 获取短信配置
func (s *sSysConfig) GetSms(ctx context.Context) (conf *model.SmsConfig, err error) {
- models, err := s.GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "sms"})
+ models, err := s.GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "sms"})
if err != nil {
return
}
@@ -105,7 +112,7 @@ func (s *sSysConfig) GetSms(ctx context.Context) (conf *model.SmsConfig, err err
// GetGeo 获取地理配置
func (s *sSysConfig) GetGeo(ctx context.Context) (conf *model.GeoConfig, err error) {
- models, err := s.GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "geo"})
+ models, err := s.GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "geo"})
if err != nil {
return
}
@@ -115,7 +122,7 @@ func (s *sSysConfig) GetGeo(ctx context.Context) (conf *model.GeoConfig, err err
// GetUpload 获取上传配置
func (s *sSysConfig) GetUpload(ctx context.Context) (conf *model.UploadConfig, err error) {
- models, err := s.GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "upload"})
+ models, err := s.GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "upload"})
if err != nil {
return
}
@@ -125,7 +132,7 @@ func (s *sSysConfig) GetUpload(ctx context.Context) (conf *model.UploadConfig, e
// GetSmtp 获取邮件配置
func (s *sSysConfig) GetSmtp(ctx context.Context) (conf *model.EmailConfig, err error) {
- models, err := s.GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "smtp"})
+ models, err := s.GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "smtp"})
if err != nil {
return
}
@@ -140,7 +147,7 @@ func (s *sSysConfig) GetSmtp(ctx context.Context) (conf *model.EmailConfig, err
// GetBasic 获取基础配置
func (s *sSysConfig) GetBasic(ctx context.Context) (conf *model.BasicConfig, err error) {
- models, err := s.GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "basic"})
+ models, err := s.GetConfigByGroup(ctx, &sysin.GetConfigInp{Group: "basic"})
if err != nil {
return
}
@@ -185,7 +192,7 @@ func (s *sSysConfig) GetLoadServeLog(ctx context.Context) (conf *model.ServeLogC
}
// GetConfigByGroup 获取指定分组的配置
-func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error) {
+func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in *sysin.GetConfigInp) (res *sysin.GetConfigModel, err error) {
if in.Group == "" {
err = gerror.New("分组不能为空")
return
@@ -223,7 +230,7 @@ func (s *sSysConfig) ConversionType(ctx context.Context, models *entity.SysConfi
}
// UpdateConfigByGroup 更新指定分组的配置
-func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) (err error) {
+func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateConfigInp) (err error) {
if in.Group == "" {
err = gerror.New("分组不能为空")
return
@@ -285,7 +292,7 @@ func (s *sSysConfig) getConfigByKey(key string, models []*entity.SysConfig) *ent
}
// syncUpdate 同步更新一些加载配置
-func (s *sSysConfig) syncUpdate(ctx context.Context, in sysin.UpdateConfigInp) (err error) {
+func (s *sSysConfig) syncUpdate(ctx context.Context, in *sysin.UpdateConfigInp) (err error) {
switch in.Group {
case "wechat":
wx, err := s.GetWechat(ctx)
@@ -302,6 +309,11 @@ func (s *sSysConfig) syncUpdate(ctx context.Context, in sysin.UpdateConfigInp) (
if err == nil {
storager.SetConfig(upload)
}
+ case "sms":
+ sm, err := s.GetSms(ctx)
+ if err == nil {
+ sms.SetConfig(sm)
+ }
}
if err != nil {
diff --git a/server/internal/logic/sys/cron.go b/server/internal/logic/sys/cron.go
index d404629..a0cb559 100644
--- a/server/internal/logic/sys/cron.go
+++ b/server/internal/logic/sys/cron.go
@@ -50,7 +50,7 @@ func (s *sSysCron) StartCron(ctx context.Context) {
}
// Delete 删除
-func (s *sSysCron) Delete(ctx context.Context, in sysin.CronDeleteInp) (err error) {
+func (s *sSysCron) Delete(ctx context.Context, in *sysin.CronDeleteInp) (err error) {
var models *entity.SysCron
if err = dao.SysCron.Ctx(ctx).Where("id", in.Id).Scan(&models); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -72,7 +72,7 @@ func (s *sSysCron) Delete(ctx context.Context, in sysin.CronDeleteInp) (err erro
}
// Edit 修改/新增
-func (s *sSysCron) Edit(ctx context.Context, in sysin.CronEditInp) (err error) {
+func (s *sSysCron) Edit(ctx context.Context, in *sysin.CronEditInp) (err error) {
if in.Name == "" {
err = gerror.New("标题不能为空")
return
@@ -95,7 +95,7 @@ func (s *sSysCron) Edit(ctx context.Context, in sysin.CronEditInp) (err error) {
}
// Status 更新状态
-func (s *sSysCron) Status(ctx context.Context, in sysin.CronStatusInp) (err error) {
+func (s *sSysCron) Status(ctx context.Context, in *sysin.CronStatusInp) (err error) {
if in.Id <= 0 {
err = gerror.New("ID不能为空")
return
@@ -134,7 +134,7 @@ func (s *sSysCron) Status(ctx context.Context, in sysin.CronStatusInp) (err erro
}
// MaxSort 最大排序
-func (s *sSysCron) MaxSort(ctx context.Context, in sysin.CronMaxSortInp) (res *sysin.CronMaxSortModel, err error) {
+func (s *sSysCron) MaxSort(ctx context.Context, in *sysin.CronMaxSortInp) (res *sysin.CronMaxSortModel, err error) {
if err = dao.SysCron.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
return
}
@@ -143,12 +143,12 @@ func (s *sSysCron) MaxSort(ctx context.Context, in sysin.CronMaxSortInp) (res *s
res = new(sysin.CronMaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
// View 获取指定信息
-func (s *sSysCron) View(ctx context.Context, in sysin.CronViewInp) (res *sysin.CronViewModel, err error) {
+func (s *sSysCron) View(ctx context.Context, in *sysin.CronViewInp) (res *sysin.CronViewModel, err error) {
if err = dao.SysCron.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
return
}
@@ -156,7 +156,7 @@ func (s *sSysCron) View(ctx context.Context, in sysin.CronViewInp) (res *sysin.C
}
// List 获取列表
-func (s *sSysCron) List(ctx context.Context, in sysin.CronListInp) (list []*sysin.CronListModel, totalCount int, err error) {
+func (s *sSysCron) List(ctx context.Context, in *sysin.CronListInp) (list []*sysin.CronListModel, totalCount int, err error) {
mod := dao.SysCron.Ctx(ctx)
if in.Name != "" {
@@ -189,7 +189,7 @@ func (s *sSysCron) List(ctx context.Context, in sysin.CronListInp) (list []*sysi
}
// OnlineExec 在线执行
-func (s *sSysCron) OnlineExec(ctx context.Context, in sysin.OnlineExecInp) (err error) {
+func (s *sSysCron) OnlineExec(ctx context.Context, in *sysin.OnlineExecInp) (err error) {
var data *entity.SysCron
if err = dao.SysCron.Ctx(ctx).Where(dao.SysCron.Columns().Id, in.Id).Scan(&data); err != nil {
return
diff --git a/server/internal/logic/sys/cron_group.go b/server/internal/logic/sys/cron_group.go
index fbbc2a7..20dd41f 100644
--- a/server/internal/logic/sys/cron_group.go
+++ b/server/internal/logic/sys/cron_group.go
@@ -27,13 +27,13 @@ func init() {
}
// Delete 删除
-func (s *sSysCronGroup) Delete(ctx context.Context, in sysin.CronGroupDeleteInp) (err error) {
+func (s *sSysCronGroup) Delete(ctx context.Context, in *sysin.CronGroupDeleteInp) (err error) {
_, err = dao.SysCronGroup.Ctx(ctx).Where("id", in.Id).Delete()
return
}
// Edit 修改/新增
-func (s *sSysCronGroup) Edit(ctx context.Context, in sysin.CronGroupEditInp) (err error) {
+func (s *sSysCronGroup) Edit(ctx context.Context, in *sysin.CronGroupEditInp) (err error) {
// 修改
if in.Id > 0 {
if _, err = dao.SysCronGroup.Ctx(ctx).Fields(sysin.CronGroupUpdateFields{}).Where("id", in.Id).Data(in).Update(); err != nil {
@@ -50,7 +50,7 @@ func (s *sSysCronGroup) Edit(ctx context.Context, in sysin.CronGroupEditInp) (er
}
// Status 更新状态
-func (s *sSysCronGroup) Status(ctx context.Context, in sysin.CronGroupStatusInp) (err error) {
+func (s *sSysCronGroup) Status(ctx context.Context, in *sysin.CronGroupStatusInp) (err error) {
if _, err = dao.SysCronGroup.Ctx(ctx).Where("id", in.Id).Data("status", in.Status).Update(); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
}
@@ -58,7 +58,7 @@ func (s *sSysCronGroup) Status(ctx context.Context, in sysin.CronGroupStatusInp)
}
// MaxSort 最大排序
-func (s *sSysCronGroup) MaxSort(ctx context.Context, in sysin.CronGroupMaxSortInp) (res *sysin.CronGroupMaxSortModel, err error) {
+func (s *sSysCronGroup) MaxSort(ctx context.Context, in *sysin.CronGroupMaxSortInp) (res *sysin.CronGroupMaxSortModel, err error) {
if in.Id > 0 {
if err = dao.SysCronGroup.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -70,12 +70,12 @@ func (s *sSysCronGroup) MaxSort(ctx context.Context, in sysin.CronGroupMaxSortIn
res = new(sysin.CronGroupMaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
// View 获取指定信息
-func (s *sSysCronGroup) View(ctx context.Context, in sysin.CronGroupViewInp) (res *sysin.CronGroupViewModel, err error) {
+func (s *sSysCronGroup) View(ctx context.Context, in *sysin.CronGroupViewInp) (res *sysin.CronGroupViewModel, err error) {
if err = dao.SysCronGroup.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
}
@@ -83,7 +83,7 @@ func (s *sSysCronGroup) View(ctx context.Context, in sysin.CronGroupViewInp) (re
}
// List 获取列表
-func (s *sSysCronGroup) List(ctx context.Context, in sysin.CronGroupListInp) (list []*sysin.CronGroupListModel, totalCount int, err error) {
+func (s *sSysCronGroup) List(ctx context.Context, in *sysin.CronGroupListInp) (list []*sysin.CronGroupListModel, totalCount int, err error) {
mod := dao.SysCronGroup.Ctx(ctx)
if in.Name != "" {
@@ -111,7 +111,7 @@ func (s *sSysCronGroup) List(ctx context.Context, in sysin.CronGroupListInp) (li
}
// Select 选项
-func (s *sSysCronGroup) Select(ctx context.Context, in sysin.CronGroupSelectInp) (res *sysin.CronGroupSelectModel, err error) {
+func (s *sSysCronGroup) Select(ctx context.Context, in *sysin.CronGroupSelectInp) (res *sysin.CronGroupSelectModel, err error) {
var (
mod = dao.SysCronGroup.Ctx(ctx)
models []*entity.SysCronGroup
diff --git a/server/internal/logic/sys/curd_demo.go b/server/internal/logic/sys/curd_demo.go
index 48504c4..337fe33 100644
--- a/server/internal/logic/sys/curd_demo.go
+++ b/server/internal/logic/sys/curd_demo.go
@@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-// @AutoGenerate Version 2.7.3
+// @AutoGenerate Version 2.7.6
package sys
import (
@@ -43,7 +43,7 @@ func (s *sSysCurdDemo) Model(ctx context.Context, option ...*handler.Option) *gd
}
// List 获取生成演示列表
-func (s *sSysCurdDemo) List(ctx context.Context, in sysin.CurdDemoListInp) (list []*sysin.CurdDemoListModel, totalCount int, err error) {
+func (s *sSysCurdDemo) List(ctx context.Context, in *sysin.CurdDemoListInp) (list []*sysin.CurdDemoListModel, totalCount int, err error) {
mod := s.Model(ctx)
// 查询ID
@@ -88,6 +88,7 @@ func (s *sSysCurdDemo) List(ctx context.Context, in sysin.CurdDemoListInp) (list
})
if err != nil {
+ err = gerror.Wrap(err, "获取生成演示关联字段失败,请稍后重试!")
return
}
@@ -99,7 +100,7 @@ func (s *sSysCurdDemo) List(ctx context.Context, in sysin.CurdDemoListInp) (list
}
// Export 导出生成演示
-func (s *sSysCurdDemo) Export(ctx context.Context, in sysin.CurdDemoListInp) (err error) {
+func (s *sSysCurdDemo) Export(ctx context.Context, in *sysin.CurdDemoListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
@@ -126,27 +127,30 @@ func (s *sSysCurdDemo) Export(ctx context.Context, in sysin.CurdDemoListInp) (er
}
// Edit 修改/新增生成演示
-func (s *sSysCurdDemo) Edit(ctx context.Context, in sysin.CurdDemoEditInp) (err error) {
-
+func (s *sSysCurdDemo) Edit(ctx context.Context, in *sysin.CurdDemoEditInp) (err error) {
// 修改
if in.Id > 0 {
in.UpdatedBy = contexts.GetUserId(ctx)
- _, err = s.Model(ctx).
+ if _, err = s.Model(ctx).
Fields(sysin.CurdDemoUpdateFields{}).
- WherePri(in.Id).Data(in).Update()
+ WherePri(in.Id).Data(in).Update(); err != nil {
+ err = gerror.Wrap(err, "修改生成演示失败,请稍后重试!")
+ }
return
}
// 新增
in.CreatedBy = contexts.GetUserId(ctx)
- _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).
+ if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).
Fields(sysin.CurdDemoInsertFields{}).
- Data(in).Insert()
+ Data(in).Insert(); err != nil {
+ err = gerror.Wrap(err, "新增生成演示失败,请稍后重试!")
+ }
return
}
// Delete 删除生成演示
-func (s *sSysCurdDemo) Delete(ctx context.Context, in sysin.CurdDemoDeleteInp) (err error) {
+func (s *sSysCurdDemo) Delete(ctx context.Context, in *sysin.CurdDemoDeleteInp) (err error) {
if _, err = s.Model(ctx).WherePri(in.Id).Delete(); err != nil {
err = gerror.Wrap(err, "删除生成演示失败,请稍后重试!")
return
@@ -155,7 +159,7 @@ func (s *sSysCurdDemo) Delete(ctx context.Context, in sysin.CurdDemoDeleteInp) (
}
// MaxSort 获取生成演示最大排序
-func (s *sSysCurdDemo) MaxSort(ctx context.Context, in sysin.CurdDemoMaxSortInp) (res *sysin.CurdDemoMaxSortModel, err error) {
+func (s *sSysCurdDemo) MaxSort(ctx context.Context, in *sysin.CurdDemoMaxSortInp) (res *sysin.CurdDemoMaxSortModel, err error) {
if err = dao.SysGenCurdDemo.Ctx(ctx).Fields(dao.SysGenCurdDemo.Columns().Sort).OrderDesc(dao.SysGenCurdDemo.Columns().Sort).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取生成演示最大排序,请稍后重试!")
return
@@ -165,12 +169,12 @@ func (s *sSysCurdDemo) MaxSort(ctx context.Context, in sysin.CurdDemoMaxSortInp)
res = new(sysin.CurdDemoMaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
// View 获取生成演示指定信息
-func (s *sSysCurdDemo) View(ctx context.Context, in sysin.CurdDemoViewInp) (res *sysin.CurdDemoViewModel, err error) {
+func (s *sSysCurdDemo) View(ctx context.Context, in *sysin.CurdDemoViewInp) (res *sysin.CurdDemoViewModel, err error) {
if err = s.Model(ctx).WherePri(in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取生成演示信息,请稍后重试!")
return
@@ -179,7 +183,7 @@ func (s *sSysCurdDemo) View(ctx context.Context, in sysin.CurdDemoViewInp) (res
}
// Status 更新生成演示状态
-func (s *sSysCurdDemo) Status(ctx context.Context, in sysin.CurdDemoStatusInp) (err error) {
+func (s *sSysCurdDemo) Status(ctx context.Context, in *sysin.CurdDemoStatusInp) (err error) {
if _, err = s.Model(ctx).WherePri(in.Id).Data(g.Map{
dao.SysGenCurdDemo.Columns().Status: in.Status,
dao.SysGenCurdDemo.Columns().UpdatedBy: contexts.GetUserId(ctx),
@@ -191,7 +195,7 @@ func (s *sSysCurdDemo) Status(ctx context.Context, in sysin.CurdDemoStatusInp) (
}
// Switch 更新生成演示开关
-func (s *sSysCurdDemo) Switch(ctx context.Context, in sysin.CurdDemoSwitchInp) (err error) {
+func (s *sSysCurdDemo) Switch(ctx context.Context, in *sysin.CurdDemoSwitchInp) (err error) {
var fields = []string{
dao.SysGenCurdDemo.Columns().Switch,
diff --git a/server/internal/logic/sys/dict_data.go b/server/internal/logic/sys/dict_data.go
index 14cc01f..4bfeecf 100644
--- a/server/internal/logic/sys/dict_data.go
+++ b/server/internal/logic/sys/dict_data.go
@@ -25,7 +25,7 @@ func init() {
}
// Delete 删除
-func (s *sSysDictData) Delete(ctx context.Context, in sysin.DictDataDeleteInp) error {
+func (s *sSysDictData) Delete(ctx context.Context, in *sysin.DictDataDeleteInp) error {
_, err := dao.SysDictData.Ctx(ctx).Where("id", in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -35,7 +35,7 @@ func (s *sSysDictData) Delete(ctx context.Context, in sysin.DictDataDeleteInp) e
}
// Edit 修改/新增
-func (s *sSysDictData) Edit(ctx context.Context, in sysin.DictDataEditInp) (err error) {
+func (s *sSysDictData) Edit(ctx context.Context, in *sysin.DictDataEditInp) (err error) {
// 修改
if in.Id > 0 {
_, err = dao.SysDictData.Ctx(ctx).Fields(sysin.DictDataUpdateFields{}).WherePri(in.Id).Data(in).Update()
@@ -66,7 +66,7 @@ func (s *sSysDictData) Edit(ctx context.Context, in sysin.DictDataEditInp) (err
}
// List 获取列表
-func (s *sSysDictData) List(ctx context.Context, in sysin.DictDataListInp) (list []*sysin.DictDataListModel, totalCount int, err error) {
+func (s *sSysDictData) List(ctx context.Context, in *sysin.DictDataListInp) (list []*sysin.DictDataListModel, totalCount int, err error) {
mod := dao.SysDictData.Ctx(ctx)
// 类型ID
if in.TypeID > 0 {
@@ -113,7 +113,7 @@ func (s *sSysDictData) List(ctx context.Context, in sysin.DictDataListInp) (list
}
// Select 获取列表
-func (s *sSysDictData) Select(ctx context.Context, in sysin.DataSelectInp) (list sysin.DataSelectModel, err error) {
+func (s *sSysDictData) Select(ctx context.Context, in *sysin.DataSelectInp) (list sysin.DataSelectModel, err error) {
mod := dao.SysDictData.Ctx(ctx).Where("type", in.Type)
if in.Type != "" {
mod = mod.Where("type", in.Type)
diff --git a/server/internal/logic/sys/dict_type.go b/server/internal/logic/sys/dict_type.go
index 0a30927..24233dc 100644
--- a/server/internal/logic/sys/dict_type.go
+++ b/server/internal/logic/sys/dict_type.go
@@ -44,7 +44,7 @@ func (s *sSysDictType) Tree(ctx context.Context) (list []*sysin.DictTypeTree, er
}
// Delete 删除
-func (s *sSysDictType) Delete(ctx context.Context, in sysin.DictTypeDeleteInp) (err error) {
+func (s *sSysDictType) Delete(ctx context.Context, in *sysin.DictTypeDeleteInp) (err error) {
var models *entity.SysDictType
if err = dao.SysDictType.Ctx(ctx).Where("id", in.Id).Scan(&models); err != nil {
return
@@ -81,7 +81,7 @@ func (s *sSysDictType) Delete(ctx context.Context, in sysin.DictTypeDeleteInp) (
}
// Edit 修改/新增
-func (s *sSysDictType) Edit(ctx context.Context, in sysin.DictTypeEditInp) (err error) {
+func (s *sSysDictType) Edit(ctx context.Context, in *sysin.DictTypeEditInp) (err error) {
if err = hgorm.IsUnique(ctx, &dao.SysDictType, g.Map{dao.SysDictType.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
return
}
@@ -102,7 +102,7 @@ func (s *sSysDictType) Edit(ctx context.Context, in sysin.DictTypeEditInp) (err
}
// TreeSelect 获取类型关系树选项
-func (s *sSysDictType) TreeSelect(ctx context.Context, in sysin.DictTreeSelectInp) (list []*sysin.DictTypeTree, err error) {
+func (s *sSysDictType) TreeSelect(ctx context.Context, in *sysin.DictTreeSelectInp) (list []*sysin.DictTypeTree, err error) {
var (
mod = dao.SysDictType.Ctx(ctx)
models []*entity.SysDictType
diff --git a/server/internal/logic/sys/ems_log.go b/server/internal/logic/sys/ems_log.go
index f5dcce1..733d479 100644
--- a/server/internal/logic/sys/ems_log.go
+++ b/server/internal/logic/sys/ems_log.go
@@ -42,13 +42,13 @@ func init() {
}
// Delete 删除
-func (s *sSysEmsLog) Delete(ctx context.Context, in sysin.EmsLogDeleteInp) (err error) {
+func (s *sSysEmsLog) Delete(ctx context.Context, in *sysin.EmsLogDeleteInp) (err error) {
_, err = dao.SysEmsLog.Ctx(ctx).Where("id", in.Id).Delete()
return
}
// Edit 修改/新增
-func (s *sSysEmsLog) Edit(ctx context.Context, in sysin.EmsLogEditInp) (err error) {
+func (s *sSysEmsLog) Edit(ctx context.Context, in *sysin.EmsLogEditInp) (err error) {
if in.Ip == "" {
err = gerror.New("ip不能为空")
return
@@ -66,7 +66,7 @@ func (s *sSysEmsLog) Edit(ctx context.Context, in sysin.EmsLogEditInp) (err erro
}
// Status 更新部门状态
-func (s *sSysEmsLog) Status(ctx context.Context, in sysin.EmsLogStatusInp) (err error) {
+func (s *sSysEmsLog) Status(ctx context.Context, in *sysin.EmsLogStatusInp) (err error) {
if in.Id <= 0 {
err = gerror.New("ID不能为空")
return
@@ -88,13 +88,13 @@ func (s *sSysEmsLog) Status(ctx context.Context, in sysin.EmsLogStatusInp) (err
}
// View 获取指定字典类型信息
-func (s *sSysEmsLog) View(ctx context.Context, in sysin.EmsLogViewInp) (res *sysin.EmsLogViewModel, err error) {
+func (s *sSysEmsLog) View(ctx context.Context, in *sysin.EmsLogViewInp) (res *sysin.EmsLogViewModel, err error) {
err = dao.SysEmsLog.Ctx(ctx).Where("id", in.Id).Scan(&res)
return
}
// List 获取列表
-func (s *sSysEmsLog) List(ctx context.Context, in sysin.EmsLogListInp) (list []*sysin.EmsLogListModel, totalCount int, err error) {
+func (s *sSysEmsLog) List(ctx context.Context, in *sysin.EmsLogListInp) (list []*sysin.EmsLogListModel, totalCount int, err error) {
mod := dao.SysEmsLog.Ctx(ctx)
if in.Status > 0 {
@@ -116,7 +116,7 @@ func (s *sSysEmsLog) List(ctx context.Context, in sysin.EmsLogListInp) (list []*
}
// Send 发送邮件
-func (s *sSysEmsLog) Send(ctx context.Context, in sysin.SendEmsInp) (err error) {
+func (s *sSysEmsLog) Send(ctx context.Context, in *sysin.SendEmsInp) (err error) {
var models *entity.SysEmsLog
if err = dao.SysEmsLog.Ctx(ctx).Where("event", in.Event).Where("email", in.Email).Scan(&models); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -194,7 +194,7 @@ func (s *sSysEmsLog) Send(ctx context.Context, in sysin.SendEmsInp) (err error)
return
}
-func (s *sSysEmsLog) newView(ctx context.Context, in sysin.SendEmsInp, config *model.EmailConfig) (view *gview.View, err error) {
+func (s *sSysEmsLog) newView(ctx context.Context, in *sysin.SendEmsInp, config *model.EmailConfig) (view *gview.View, err error) {
view = gview.New()
err = view.SetConfig(gview.Config{
Delimiters: g.Cfg().MustGet(ctx, "viewer.delimiters").Strings(),
@@ -349,7 +349,7 @@ func (s *sSysEmsLog) AllowSend(ctx context.Context, models *entity.SysEmsLog, co
}
// VerifyCode 效验验证码
-func (s *sSysEmsLog) VerifyCode(ctx context.Context, in sysin.VerifyEmsCodeInp) (err error) {
+func (s *sSysEmsLog) VerifyCode(ctx context.Context, in *sysin.VerifyEmsCodeInp) (err error) {
if in.Event == "" {
err = gerror.New("事件不能为空")
return
diff --git a/server/internal/logic/sys/gen_codes.go b/server/internal/logic/sys/gen_codes.go
index 967474f..8dfdc93 100644
--- a/server/internal/logic/sys/gen_codes.go
+++ b/server/internal/logic/sys/gen_codes.go
@@ -35,13 +35,13 @@ func init() {
}
// Delete 删除
-func (s *sSysGenCodes) Delete(ctx context.Context, in sysin.GenCodesDeleteInp) (err error) {
+func (s *sSysGenCodes) Delete(ctx context.Context, in *sysin.GenCodesDeleteInp) (err error) {
_, err = dao.SysGenCodes.Ctx(ctx).Where("id", in.Id).Delete()
return
}
// Edit 修改/新增
-func (s *sSysGenCodes) Edit(ctx context.Context, in sysin.GenCodesEditInp) (res *sysin.GenCodesEditModel, err error) {
+func (s *sSysGenCodes) Edit(ctx context.Context, in *sysin.GenCodesEditInp) (res *sysin.GenCodesEditModel, err error) {
if in.GenType == 0 {
err = gerror.New("生成类型不能为空")
return
@@ -99,7 +99,7 @@ func (s *sSysGenCodes) Edit(ctx context.Context, in sysin.GenCodesEditInp) (res
}
// Status 更新部门状态
-func (s *sSysGenCodes) Status(ctx context.Context, in sysin.GenCodesStatusInp) (err error) {
+func (s *sSysGenCodes) Status(ctx context.Context, in *sysin.GenCodesStatusInp) (err error) {
if in.Id <= 0 {
err = gerror.New("ID不能为空")
return
@@ -120,7 +120,7 @@ func (s *sSysGenCodes) Status(ctx context.Context, in sysin.GenCodesStatusInp) (
}
// MaxSort 最大排序
-func (s *sSysGenCodes) MaxSort(ctx context.Context, in sysin.GenCodesMaxSortInp) (res *sysin.GenCodesMaxSortModel, err error) {
+func (s *sSysGenCodes) MaxSort(ctx context.Context, in *sysin.GenCodesMaxSortInp) (res *sysin.GenCodesMaxSortModel, err error) {
if in.Id > 0 {
if err = dao.SysGenCodes.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -132,18 +132,18 @@ func (s *sSysGenCodes) MaxSort(ctx context.Context, in sysin.GenCodesMaxSortInp)
res = new(sysin.GenCodesMaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
// View 获取指定字典类型信息
-func (s *sSysGenCodes) View(ctx context.Context, in sysin.GenCodesViewInp) (res *sysin.GenCodesViewModel, err error) {
+func (s *sSysGenCodes) View(ctx context.Context, in *sysin.GenCodesViewInp) (res *sysin.GenCodesViewModel, err error) {
err = dao.SysGenCodes.Ctx(ctx).Where("id", in.Id).Scan(&res)
return
}
// List 获取列表
-func (s *sSysGenCodes) List(ctx context.Context, in sysin.GenCodesListInp) (list []*sysin.GenCodesListModel, totalCount int, err error) {
+func (s *sSysGenCodes) List(ctx context.Context, in *sysin.GenCodesListInp) (list []*sysin.GenCodesListModel, totalCount int, err error) {
mod := dao.SysGenCodes.Ctx(ctx)
if in.GenType > 0 {
@@ -195,17 +195,16 @@ func (s *sSysGenCodes) List(ctx context.Context, in sysin.GenCodesListInp) (list
v.GenTemplateGroup = getTpGroup(v)
}
}
-
return
}
// Selects 选项
-func (s *sSysGenCodes) Selects(ctx context.Context, in sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error) {
+func (s *sSysGenCodes) Selects(ctx context.Context, in *sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error) {
return hggen.TableSelects(ctx, in)
}
// TableSelect 表选项
-func (s *sSysGenCodes) TableSelect(ctx context.Context, in sysin.GenCodesTableSelectInp) (res []*sysin.GenCodesTableSelectModel, err error) {
+func (s *sSysGenCodes) TableSelect(ctx context.Context, in *sysin.GenCodesTableSelectInp) (res []*sysin.GenCodesTableSelectModel, err error) {
var (
sql = "SELECT TABLE_NAME as value, TABLE_COMMENT as label FROM information_schema.`TABLES` WHERE TABLE_SCHEMA = '%s'"
config = g.DB(in.Name).GetConfig()
@@ -248,14 +247,13 @@ func (s *sSysGenCodes) TableSelect(ctx context.Context, in sysin.GenCodesTableSe
row.DefAlias = gstr.CaseCamelLower(newValue)
row.Name = fmt.Sprintf("%s (%s)", v.Value, v.Label)
row.Label = row.Name
-
res = append(res, row)
}
return
}
// ColumnSelect 表字段选项
-func (s *sSysGenCodes) ColumnSelect(ctx context.Context, in sysin.GenCodesColumnSelectInp) (res []*sysin.GenCodesColumnSelectModel, err error) {
+func (s *sSysGenCodes) ColumnSelect(ctx context.Context, in *sysin.GenCodesColumnSelectInp) (res []*sysin.GenCodesColumnSelectModel, err error) {
var (
sql = "select COLUMN_NAME as value,COLUMN_COMMENT as label from information_schema.COLUMNS where TABLE_SCHEMA = '%s' and TABLE_NAME = '%s'"
config = g.DB(in.Name).GetConfig()
@@ -278,31 +276,31 @@ func (s *sSysGenCodes) ColumnSelect(ctx context.Context, in sysin.GenCodesColumn
}
// ColumnList 表字段列表
-func (s *sSysGenCodes) ColumnList(ctx context.Context, in sysin.GenCodesColumnListInp) (res []*sysin.GenCodesColumnListModel, err error) {
+func (s *sSysGenCodes) ColumnList(ctx context.Context, in *sysin.GenCodesColumnListInp) (res []*sysin.GenCodesColumnListModel, err error) {
return hggen.TableColumns(ctx, in)
}
// Preview 生成预览
-func (s *sSysGenCodes) Preview(ctx context.Context, in sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error) {
+func (s *sSysGenCodes) Preview(ctx context.Context, in *sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error) {
return hggen.Preview(ctx, in)
}
// Build 提交生成
-func (s *sSysGenCodes) Build(ctx context.Context, in sysin.GenCodesBuildInp) (err error) {
+func (s *sSysGenCodes) Build(ctx context.Context, in *sysin.GenCodesBuildInp) (err error) {
// 先保存配置
ein := in.SysGenCodes
- if _, err = s.Edit(ctx, sysin.GenCodesEditInp{SysGenCodes: ein}); err != nil {
+ if _, err = s.Edit(ctx, &sysin.GenCodesEditInp{SysGenCodes: ein}); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
- if err = s.Status(ctx, sysin.GenCodesStatusInp{Id: in.Id, Status: consts.GenCodesStatusOk}); err != nil {
+ if err = s.Status(ctx, &sysin.GenCodesStatusInp{Id: in.Id, Status: consts.GenCodesStatusOk}); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if err = hggen.Build(ctx, in); err != nil {
- _ = s.Status(ctx, sysin.GenCodesStatusInp{Id: in.Id, Status: consts.GenCodesStatusFail})
+ _ = s.Status(ctx, &sysin.GenCodesStatusInp{Id: in.Id, Status: consts.GenCodesStatusFail})
return err
}
return
diff --git a/server/internal/logic/sys/log.go b/server/internal/logic/sys/log.go
index f18a0af..4b7639e 100644
--- a/server/internal/logic/sys/log.go
+++ b/server/internal/logic/sys/log.go
@@ -41,7 +41,7 @@ func init() {
}
// Export 导出
-func (s *sSysLog) Export(ctx context.Context, in sysin.LogListInp) (err error) {
+func (s *sSysLog) Export(ctx context.Context, in *sysin.LogListInp) (err error) {
// 导出格式
type exportImage struct {
Id int64 `json:"id" description:""`
@@ -235,7 +235,7 @@ func (s *sSysLog) AnalysisLog(ctx context.Context) entity.SysLog {
}
// View 获取指定字典类型信息
-func (s *sSysLog) View(ctx context.Context, in sysin.LogViewInp) (res *sysin.LogViewModel, err error) {
+func (s *sSysLog) View(ctx context.Context, in *sysin.LogViewInp) (res *sysin.LogViewModel, err error) {
if err = dao.SysLog.Ctx(ctx).Hook(hook.CityLabel).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
@@ -252,13 +252,13 @@ func (s *sSysLog) View(ctx context.Context, in sysin.LogViewInp) (res *sysin.Log
}
// Delete 删除
-func (s *sSysLog) Delete(ctx context.Context, in sysin.LogDeleteInp) (err error) {
+func (s *sSysLog) Delete(ctx context.Context, in *sysin.LogDeleteInp) (err error) {
_, err = dao.SysLog.Ctx(ctx).Where("id", in.Id).Delete()
return
}
// List 列表
-func (s *sSysLog) List(ctx context.Context, in sysin.LogListInp) (list []*sysin.LogListModel, totalCount int, err error) {
+func (s *sSysLog) List(ctx context.Context, in *sysin.LogListInp) (list []*sysin.LogListModel, totalCount int, err error) {
mod := dao.SysLog.Ctx(ctx).FieldsEx("get_data", "header_data", "post_data")
// 访问路径
@@ -287,13 +287,6 @@ func (s *sSysLog) List(ctx context.Context, in sysin.LogListInp) (list []*sysin.
}
// 日期范围
- if in.StartTime != "" {
- mod = mod.WhereGTE("created_at", in.StartTime)
- }
- if in.EndTime != "" {
- mod = mod.WhereLTE("created_at", in.EndTime)
- }
-
if len(in.CreatedAt) == 2 {
mod = mod.WhereBetween("created_at", gtime.New(in.CreatedAt[0]), gtime.New(in.CreatedAt[1]))
}
diff --git a/server/internal/logic/sys/login_log.go b/server/internal/logic/sys/login_log.go
index f532d08..70c304c 100644
--- a/server/internal/logic/sys/login_log.go
+++ b/server/internal/logic/sys/login_log.go
@@ -49,7 +49,7 @@ func (s *sSysLoginLog) Model(ctx context.Context) *gdb.Model {
}
// List 获取登录日志列表
-func (s *sSysLoginLog) List(ctx context.Context, in sysin.LoginLogListInp) (list []*sysin.LoginLogListModel, totalCount int, err error) {
+func (s *sSysLoginLog) List(ctx context.Context, in *sysin.LoginLogListInp) (list []*sysin.LoginLogListModel, totalCount int, err error) {
mod := dao.SysLoginLog.Ctx(ctx)
// 查询状态
@@ -111,7 +111,7 @@ func (s *sSysLoginLog) List(ctx context.Context, in sysin.LoginLogListInp) (list
}
// Export 导出登录日志
-func (s *sSysLoginLog) Export(ctx context.Context, in sysin.LoginLogListInp) (err error) {
+func (s *sSysLoginLog) Export(ctx context.Context, in *sysin.LoginLogListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
@@ -138,19 +138,19 @@ func (s *sSysLoginLog) Export(ctx context.Context, in sysin.LoginLogListInp) (er
}
// Delete 删除登录日志
-func (s *sSysLoginLog) Delete(ctx context.Context, in sysin.LoginLogDeleteInp) (err error) {
+func (s *sSysLoginLog) Delete(ctx context.Context, in *sysin.LoginLogDeleteInp) (err error) {
_, err = dao.SysLoginLog.Ctx(ctx).Where(dao.SysLoginLog.Columns().Id, in.Id).Delete()
return
}
// View 获取登录日志指定信息
-func (s *sSysLoginLog) View(ctx context.Context, in sysin.LoginLogViewInp) (res *sysin.LoginLogViewModel, err error) {
+func (s *sSysLoginLog) View(ctx context.Context, in *sysin.LoginLogViewInp) (res *sysin.LoginLogViewModel, err error) {
err = dao.SysLoginLog.Ctx(ctx).Where(dao.SysLoginLog.Columns().Id, in.Id).Scan(&res)
return
}
// Push 推送登录日志
-func (s *sSysLoginLog) Push(ctx context.Context, in sysin.LoginLogPushInp) {
+func (s *sSysLoginLog) Push(ctx context.Context, in *sysin.LoginLogPushInp) {
if in.Response == nil {
in.Response = new(adminin.LoginModel)
}
diff --git a/server/internal/logic/sys/provinces.go b/server/internal/logic/sys/provinces.go
index 0f16197..54a7f3d 100644
--- a/server/internal/logic/sys/provinces.go
+++ b/server/internal/logic/sys/provinces.go
@@ -40,7 +40,7 @@ func (s *sSysProvinces) Tree(ctx context.Context) (list []*sysin.ProvincesTree,
}
// Delete 删除省市区数据
-func (s *sSysProvinces) Delete(ctx context.Context, in sysin.ProvincesDeleteInp) (err error) {
+func (s *sSysProvinces) Delete(ctx context.Context, in *sysin.ProvincesDeleteInp) (err error) {
var models *entity.SysProvinces
if err = dao.SysProvinces.Ctx(ctx).Where("id", in.Id).Scan(&models); err != nil {
err = gerror.Wrap(err, "获取省市区数据失败!")
@@ -71,14 +71,14 @@ func (s *sSysProvinces) Delete(ctx context.Context, in sysin.ProvincesDeleteInp)
}
// Edit 修改/新增省市区数据
-func (s *sSysProvinces) Edit(ctx context.Context, in sysin.ProvincesEditInp) (err error) {
+func (s *sSysProvinces) Edit(ctx context.Context, in *sysin.ProvincesEditInp) (err error) {
// 关系树
in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, &dao.SysProvinces, in.Pid)
if err != nil {
return
}
- models, err := s.View(ctx, sysin.ProvincesViewInp{Id: in.Id})
+ models, err := s.View(ctx, &sysin.ProvincesViewInp{Id: in.Id})
if err != nil {
return
}
@@ -99,7 +99,7 @@ func (s *sSysProvinces) Edit(ctx context.Context, in sysin.ProvincesEditInp) (er
}
// Status 更新省市区状态
-func (s *sSysProvinces) Status(ctx context.Context, in sysin.ProvincesStatusInp) (err error) {
+func (s *sSysProvinces) Status(ctx context.Context, in *sysin.ProvincesStatusInp) (err error) {
if _, err = dao.SysProvinces.Ctx(ctx).Where("id", in.Id).Data("status", in.Status).Update(); err != nil {
err = gerror.Wrap(err, "更新省市区状态失败!")
}
@@ -107,7 +107,7 @@ func (s *sSysProvinces) Status(ctx context.Context, in sysin.ProvincesStatusInp)
}
// MaxSort 最大排序
-func (s *sSysProvinces) MaxSort(ctx context.Context, in sysin.ProvincesMaxSortInp) (res *sysin.ProvincesMaxSortModel, err error) {
+func (s *sSysProvinces) MaxSort(ctx context.Context, in *sysin.ProvincesMaxSortInp) (res *sysin.ProvincesMaxSortModel, err error) {
if err = dao.SysProvinces.Ctx(ctx).Fields(dao.SysProvinces.Columns().Sort).OrderDesc(dao.SysProvinces.Columns().Sort).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取省市区最大排序失败!")
return
@@ -116,12 +116,12 @@ func (s *sSysProvinces) MaxSort(ctx context.Context, in sysin.ProvincesMaxSortIn
if res == nil {
res = new(sysin.ProvincesMaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
// View 获取省市区信息
-func (s *sSysProvinces) View(ctx context.Context, in sysin.ProvincesViewInp) (res *sysin.ProvincesViewModel, err error) {
+func (s *sSysProvinces) View(ctx context.Context, in *sysin.ProvincesViewInp) (res *sysin.ProvincesViewModel, err error) {
if err = dao.SysProvinces.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取省市区信息失败!")
}
@@ -129,7 +129,7 @@ func (s *sSysProvinces) View(ctx context.Context, in sysin.ProvincesViewInp) (re
}
// List 获取列表
-func (s *sSysProvinces) List(ctx context.Context, in sysin.ProvincesListInp) (list []*sysin.ProvincesListModel, totalCount int, err error) {
+func (s *sSysProvinces) List(ctx context.Context, in *sysin.ProvincesListInp) (list []*sysin.ProvincesListModel, totalCount int, err error) {
mod := dao.SysProvinces.Ctx(ctx)
if in.Title != "" {
@@ -157,7 +157,7 @@ func (s *sSysProvinces) List(ctx context.Context, in sysin.ProvincesListInp) (li
}
// ChildrenList 获取省市区下级列表
-func (s *sSysProvinces) ChildrenList(ctx context.Context, in sysin.ProvincesChildrenListInp) (list []*sysin.ProvincesChildrenListModel, totalCount int, err error) {
+func (s *sSysProvinces) ChildrenList(ctx context.Context, in *sysin.ProvincesChildrenListInp) (list []*sysin.ProvincesChildrenListModel, totalCount int, err error) {
mod := dao.SysProvinces.Ctx(ctx)
if in.Title != "" {
@@ -189,7 +189,7 @@ func (s *sSysProvinces) ChildrenList(ctx context.Context, in sysin.ProvincesChil
}
// UniqueId 获取省市区下级列表
-func (s *sSysProvinces) UniqueId(ctx context.Context, in sysin.ProvincesUniqueIdInp) (res *sysin.ProvincesUniqueIdModel, err error) {
+func (s *sSysProvinces) UniqueId(ctx context.Context, in *sysin.ProvincesUniqueIdInp) (res *sysin.ProvincesUniqueIdModel, err error) {
res = new(sysin.ProvincesUniqueIdModel)
res.IsUnique = true
if in.NewId == 0 {
@@ -204,7 +204,7 @@ func (s *sSysProvinces) UniqueId(ctx context.Context, in sysin.ProvincesUniqueId
}
// Select 省市区选项
-func (s *sSysProvinces) Select(ctx context.Context, in sysin.ProvincesSelectInp) (res *sysin.ProvincesSelectModel, err error) {
+func (s *sSysProvinces) Select(ctx context.Context, in *sysin.ProvincesSelectInp) (res *sysin.ProvincesSelectModel, err error) {
res = new(sysin.ProvincesSelectModel)
mod := dao.SysProvinces.Ctx(ctx).Fields("id as value, title as label, level").Where("pid", in.Value)
diff --git a/server/internal/logic/sys/serve_license.go b/server/internal/logic/sys/serve_license.go
new file mode 100644
index 0000000..79a5d1a
--- /dev/null
+++ b/server/internal/logic/sys/serve_license.go
@@ -0,0 +1,193 @@
+// Package sys
+// @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
+// @AutoGenerate Version 2.7.6
+package sys
+
+import (
+ "context"
+ "fmt"
+ "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"
+ "hotgo/internal/dao"
+ "hotgo/internal/library/hgorm"
+ "hotgo/internal/library/hgorm/handler"
+ "hotgo/internal/model/input/form"
+ "hotgo/internal/model/input/sysin"
+ "hotgo/internal/service"
+ "hotgo/utility/convert"
+ "hotgo/utility/excel"
+)
+
+type sSysServeLicense struct{}
+
+func NewSysServeLicense() *sSysServeLicense {
+ return &sSysServeLicense{}
+}
+
+func init() {
+ service.RegisterSysServeLicense(NewSysServeLicense())
+}
+
+// Model 服务许可证ORM模型
+func (s *sSysServeLicense) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
+ return handler.Model(dao.SysServeLicense.Ctx(ctx), option...)
+}
+
+// List 获取服务许可证列表
+func (s *sSysServeLicense) List(ctx context.Context, in *sysin.ServeLicenseListInp) (list []*sysin.ServeLicenseListModel, totalCount int, err error) {
+ mod := s.Model(ctx)
+
+ // 查询许可ID
+ if in.Id > 0 {
+ mod = mod.Where(dao.SysServeLicense.Columns().Id, in.Id)
+ }
+
+ // 查询分组
+ if in.Group != "" {
+ mod = mod.Where(dao.SysServeLicense.Columns().Group, in.Group)
+ }
+
+ // 查询许可名称
+ if in.Name != "" {
+ mod = mod.WhereLike(dao.SysServeLicense.Columns().Name, "%"+in.Name+"%")
+ }
+
+ // 查询应用ID
+ if in.Appid != "" {
+ mod = mod.Where(dao.SysServeLicense.Columns().Appid, in.Appid)
+ }
+
+ // 查询授权结束时间
+ if len(in.EndAt) == 2 {
+ mod = mod.WhereBetween(dao.SysServeLicense.Columns().EndAt, in.EndAt[0], in.EndAt[1])
+ }
+
+ // 查询状态
+ if in.Status > 0 {
+ mod = mod.Where(dao.SysServeLicense.Columns().Status, in.Status)
+ }
+
+ // 查询创建时间
+ if len(in.CreatedAt) == 2 {
+ mod = mod.WhereBetween(dao.SysServeLicense.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
+ }
+
+ totalCount, err = mod.Clone().Count()
+ if err != nil {
+ err = gerror.Wrap(err, "获取服务许可证数据行失败,请稍后重试!")
+ return
+ }
+
+ if totalCount == 0 {
+ return
+ }
+
+ if err = mod.Fields(sysin.ServeLicenseListModel{}).Page(in.Page, in.PerPage).OrderDesc(dao.SysServeLicense.Columns().Id).Scan(&list); err != nil {
+ err = gerror.Wrap(err, "获取服务许可证列表失败,请稍后重试!")
+ return
+ }
+
+ serv := service.TCPServer().Instance()
+ for _, v := range list {
+ v.Online = serv.GetAppIdOnline(v.Appid)
+ }
+ return
+}
+
+// Export 导出服务许可证
+func (s *sSysServeLicense) Export(ctx context.Context, in *sysin.ServeLicenseListInp) (err error) {
+ list, totalCount, err := s.List(ctx, in)
+ if err != nil {
+ return
+ }
+
+ // 字段的排序是依据tags的字段顺序,如果你不想使用默认的排序方式,可以直接定义 tags = []string{"字段名称", "字段名称2", ...}
+ tags, err := convert.GetEntityDescTags(sysin.ServeLicenseExportModel{})
+ if err != nil {
+ return
+ }
+
+ var (
+ fileName = "导出服务许可证-" + gctx.CtxId(ctx) + ".xlsx"
+ sheetName = fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list))
+ exports []sysin.ServeLicenseExportModel
+ )
+
+ if err = gconv.Scan(list, &exports); err != nil {
+ return
+ }
+
+ err = excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
+ return
+}
+
+// Edit 修改/新增服务许可证
+func (s *sSysServeLicense) Edit(ctx context.Context, in *sysin.ServeLicenseEditInp) (err error) {
+ // 验证'Appid'唯一
+ if err = hgorm.IsUnique(ctx, &dao.SysServeLicense, g.Map{dao.SysServeLicense.Columns().Appid: in.Appid}, "应用ID已存在", in.Id); err != nil {
+ return
+ }
+ // 修改
+ if in.Id > 0 {
+ if _, err = s.Model(ctx).Fields(sysin.ServeLicenseUpdateFields{}).WherePri(in.Id).Data(in).Update(); err != nil {
+ err = gerror.Wrap(err, "修改服务许可证失败,请稍后重试!")
+ }
+ return
+ }
+
+ // 新增
+ if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).Fields(sysin.ServeLicenseInsertFields{}).Data(in).Insert(); err != nil {
+ err = gerror.Wrap(err, "新增服务许可证失败,请稍后重试!")
+ }
+ return
+}
+
+// Delete 删除服务许可证
+func (s *sSysServeLicense) Delete(ctx context.Context, in *sysin.ServeLicenseDeleteInp) (err error) {
+ if _, err = s.Model(ctx).WherePri(in.Id).Delete(); err != nil {
+ err = gerror.Wrap(err, "删除服务许可证失败,请稍后重试!")
+ return
+ }
+ return
+}
+
+// View 获取服务许可证指定信息
+func (s *sSysServeLicense) View(ctx context.Context, in *sysin.ServeLicenseViewInp) (res *sysin.ServeLicenseViewModel, err error) {
+ if err = s.Model(ctx).WherePri(in.Id).Scan(&res); err != nil {
+ err = gerror.Wrap(err, "获取服务许可证信息,请稍后重试!")
+ return
+ }
+ return
+}
+
+// Status 更新服务许可证状态
+func (s *sSysServeLicense) Status(ctx context.Context, in *sysin.ServeLicenseStatusInp) (err error) {
+ update := g.Map{
+ dao.SysServeLicense.Columns().Status: in.Status,
+ }
+
+ if _, err = s.Model(ctx).WherePri(in.Id).Data(update).Update(); err != nil {
+ err = gerror.Wrap(err, "更新服务许可证状态失败,请稍后重试!")
+ return
+ }
+ return
+}
+
+// AssignRouter 分配服务许可证路由
+func (s *sSysServeLicense) AssignRouter(ctx context.Context, in *sysin.ServeLicenseAssignRouterInp) (err error) {
+ update := g.Map{
+ dao.SysServeLicense.Columns().Routes: in.Routes,
+ }
+
+ if _, err = s.Model(ctx).WherePri(in.Id).Data(update).Update(); err != nil {
+ err = gerror.Wrap(err, "分配服务许可证路由失败,请稍后重试!")
+ return
+ }
+ return
+}
diff --git a/server/internal/logic/sys/serve_log.go b/server/internal/logic/sys/serve_log.go
index e4f8626..c845262 100644
--- a/server/internal/logic/sys/serve_log.go
+++ b/server/internal/logic/sys/serve_log.go
@@ -38,7 +38,7 @@ func (s *sSysServeLog) Model(ctx context.Context) *gdb.Model {
}
// List 获取服务日志列表
-func (s *sSysServeLog) List(ctx context.Context, in sysin.ServeLogListInp) (list []*sysin.ServeLogListModel, totalCount int, err error) {
+func (s *sSysServeLog) List(ctx context.Context, in *sysin.ServeLogListInp) (list []*sysin.ServeLogListModel, totalCount int, err error) {
mod := dao.SysServeLog.Ctx(ctx)
// 查询链路ID
@@ -86,7 +86,7 @@ func (s *sSysServeLog) List(ctx context.Context, in sysin.ServeLogListInp) (list
}
// Export 导出服务日志
-func (s *sSysServeLog) Export(ctx context.Context, in sysin.ServeLogListInp) (err error) {
+func (s *sSysServeLog) Export(ctx context.Context, in *sysin.ServeLogListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
@@ -113,13 +113,13 @@ func (s *sSysServeLog) Export(ctx context.Context, in sysin.ServeLogListInp) (er
}
// Delete 删除服务日志
-func (s *sSysServeLog) Delete(ctx context.Context, in sysin.ServeLogDeleteInp) (err error) {
+func (s *sSysServeLog) Delete(ctx context.Context, in *sysin.ServeLogDeleteInp) (err error) {
_, err = dao.SysServeLog.Ctx(ctx).Where(dao.SysServeLog.Columns().Id, in.Id).Delete()
return
}
// View 获取服务日志指定信息
-func (s *sSysServeLog) View(ctx context.Context, in sysin.ServeLogViewInp) (res *sysin.ServeLogViewModel, err error) {
+func (s *sSysServeLog) View(ctx context.Context, in *sysin.ServeLogViewInp) (res *sysin.ServeLogViewModel, err error) {
err = dao.SysServeLog.Ctx(ctx).Where(dao.SysServeLog.Columns().Id, in.Id).Scan(&res)
return
}
diff --git a/server/internal/logic/sys/sms_log.go b/server/internal/logic/sys/sms_log.go
index 977960f..2e17531 100644
--- a/server/internal/logic/sys/sms_log.go
+++ b/server/internal/logic/sys/sms_log.go
@@ -18,7 +18,6 @@ import (
"hotgo/internal/library/sms"
"hotgo/internal/model"
"hotgo/internal/model/entity"
- "hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
"hotgo/utility/validate"
@@ -36,13 +35,13 @@ func init() {
}
// Delete 删除
-func (s *sSysSmsLog) Delete(ctx context.Context, in sysin.SmsLogDeleteInp) (err error) {
- _, err = dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Delete()
+func (s *sSysSmsLog) Delete(ctx context.Context, in *sysin.SmsLogDeleteInp) (err error) {
+ _, err = dao.SysSmsLog.Ctx(ctx).WherePri(in.Id).Delete()
return
}
// Edit 修改/新增
-func (s *sSysSmsLog) Edit(ctx context.Context, in sysin.SmsLogEditInp) (err error) {
+func (s *sSysSmsLog) Edit(ctx context.Context, in *sysin.SmsLogEditInp) (err error) {
if in.Ip == "" {
err = gerror.New("ip不能为空")
return
@@ -50,7 +49,7 @@ func (s *sSysSmsLog) Edit(ctx context.Context, in sysin.SmsLogEditInp) (err erro
// 修改
if in.Id > 0 {
- _, err = dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Data(in).Update()
+ _, err = dao.SysSmsLog.Ctx(ctx).WherePri(in.Id).Data(in).Update()
return
}
@@ -59,8 +58,8 @@ func (s *sSysSmsLog) Edit(ctx context.Context, in sysin.SmsLogEditInp) (err erro
return
}
-// Status 更新部门状态
-func (s *sSysSmsLog) Status(ctx context.Context, in sysin.SmsLogStatusInp) (err error) {
+// Status 更新短信状态
+func (s *sSysSmsLog) Status(ctx context.Context, in *sysin.SmsLogStatusInp) (err error) {
if in.Id <= 0 {
err = gerror.New("ID不能为空")
return
@@ -77,30 +76,13 @@ func (s *sSysSmsLog) Status(ctx context.Context, in sysin.SmsLogStatusInp) (err
}
// 修改
- _, err = dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Data("status", in.Status).Update()
- return
-}
-
-// MaxSort 最大排序
-func (s *sSysSmsLog) MaxSort(ctx context.Context, in sysin.SmsLogMaxSortInp) (res *sysin.SmsLogMaxSortModel, err error) {
- if in.Id > 0 {
- if err = dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
- err = gerror.Wrap(err, consts.ErrorORM)
- return
- }
- }
-
- if res == nil {
- res = new(sysin.SmsLogMaxSortModel)
- }
-
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ _, err = dao.SysSmsLog.Ctx(ctx).WherePri(in.Id).Data(dao.SysSmsLog.Columns().Status, in.Status).Update()
return
}
// View 获取指定字典类型信息
-func (s *sSysSmsLog) View(ctx context.Context, in sysin.SmsLogViewInp) (res *sysin.SmsLogViewModel, err error) {
- if err = dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
+func (s *sSysSmsLog) View(ctx context.Context, in *sysin.SmsLogViewInp) (res *sysin.SmsLogViewModel, err error) {
+ if err = dao.SysSmsLog.Ctx(ctx).WherePri(in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
@@ -108,44 +90,49 @@ func (s *sSysSmsLog) View(ctx context.Context, in sysin.SmsLogViewInp) (res *sys
}
// List 获取列表
-func (s *sSysSmsLog) List(ctx context.Context, in sysin.SmsLogListInp) (list []*sysin.SmsLogListModel, totalCount int, err error) {
+func (s *sSysSmsLog) List(ctx context.Context, in *sysin.SmsLogListInp) (list []*sysin.SmsLogListModel, totalCount int, err error) {
mod := dao.SysSmsLog.Ctx(ctx)
+ cols := dao.SysSmsLog.Columns()
if in.Mobile != "" {
- mod = mod.WhereLike("mobile", "%"+in.Mobile+"%")
+ mod = mod.WhereLike(cols.Mobile, "%"+in.Mobile+"%")
}
if in.Ip != "" {
- mod = mod.Where("ip", in.Ip)
+ mod = mod.Where(cols.Ip, in.Ip)
}
if in.Event != "" {
- mod = mod.Where("event", in.Event)
+ mod = mod.Where(cols.Event, in.Event)
}
if in.Status > 0 {
- mod = mod.Where("status", in.Status)
+ mod = mod.Where(cols.Status, in.Status)
+ }
+
+ if len(in.CreatedAt) == 2 {
+ mod = mod.WhereBetween(cols.CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
}
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
- return list, totalCount, err
+ return
}
if totalCount == 0 {
- return list, totalCount, nil
+ return
}
- if err = mod.Page(in.Page, in.PerPage).Order("id desc").Scan(&list); err != nil {
+ if err = mod.Page(in.Page, in.PerPage).OrderDesc(cols.Id).Scan(&list); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
- return list, totalCount, err
+ return
}
- return list, totalCount, err
+ return
}
// SendCode 发送验证码
-func (s *sSysSmsLog) SendCode(ctx context.Context, in sysin.SendCodeInp) (err error) {
+func (s *sSysSmsLog) SendCode(ctx context.Context, in *sysin.SendCodeInp) (err error) {
if in.Event == "" {
err = gerror.New("事件不能为空")
return
@@ -157,7 +144,7 @@ func (s *sSysSmsLog) SendCode(ctx context.Context, in sysin.SendCodeInp) (err er
}
var models *entity.SysSmsLog
- if err = dao.SysSmsLog.Ctx(ctx).Where("event", in.Event).Where("mobile", in.Mobile).Scan(&models); err != nil {
+ if err = dao.SysSmsLog.Ctx(ctx).Where(dao.SysSmsLog.Columns().Event, in.Event).Where(dao.SysSmsLog.Columns().Mobile, in.Mobile).Scan(&models); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
@@ -179,7 +166,7 @@ func (s *sSysSmsLog) SendCode(ctx context.Context, in sysin.SendCodeInp) (err er
in.Code = grand.Digits(4)
}
- if err = sms.New(config.SmsDrive).SendCode(ctx, in, config); err != nil {
+ if err = sms.New(config.SmsDrive).SendCode(ctx, in); err != nil {
return
}
@@ -272,7 +259,7 @@ func (s *sSysSmsLog) AllowSend(ctx context.Context, models *entity.SysSmsLog, co
}
// VerifyCode 效验验证码
-func (s *sSysSmsLog) VerifyCode(ctx context.Context, in sysin.VerifyCodeInp) (err error) {
+func (s *sSysSmsLog) VerifyCode(ctx context.Context, in *sysin.VerifyCodeInp) (err error) {
if in.Event == "" {
err = gerror.New("事件不能为空")
return
@@ -289,7 +276,8 @@ func (s *sSysSmsLog) VerifyCode(ctx context.Context, in sysin.VerifyCodeInp) (er
}
var models *entity.SysSmsLog
- if err = dao.SysSmsLog.Ctx(ctx).Where("event", in.Event).Where("mobile", in.Mobile).Order("id desc").Scan(&models); err != nil {
+ cols := dao.SysSmsLog.Columns()
+ if err = dao.SysSmsLog.Ctx(ctx).Where(cols.Event, in.Event).Where(cols.Mobile, in.Mobile).OrderDesc(cols.Id).Scan(&models); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
@@ -317,15 +305,15 @@ func (s *sSysSmsLog) VerifyCode(ctx context.Context, in sysin.VerifyCodeInp) (er
}
if models.Code != in.Code {
- _, _ = dao.SysSmsLog.Ctx(ctx).Where("id", models.Id).Increment("times", 1)
+ _, _ = dao.SysSmsLog.Ctx(ctx).WherePri(models.Id).Increment(cols.Times, 1)
err = gerror.New("验证码错误!")
return
}
- _, err = dao.SysSmsLog.Ctx(ctx).Where("id", models.Id).Data(g.Map{
- "times": models.Times + 1,
- "status": consts.SmsStatusUsed,
- "updated_at": gtime.Now(),
+ _, err = dao.SysSmsLog.Ctx(ctx).WherePri(models.Id).Data(g.Map{
+ cols.Times: models.Times + 1,
+ cols.Status: consts.SmsStatusUsed,
+ cols.UpdatedAt: gtime.Now(),
}).Update()
return
}
diff --git a/server/internal/logic/tcpclient/auth.go b/server/internal/logic/tcpclient/auth.go
index 7b62c49..a240ef4 100644
--- a/server/internal/logic/tcpclient/auth.go
+++ b/server/internal/logic/tcpclient/auth.go
@@ -1,10 +1,17 @@
+// Package tcpclient
+// @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 tcpclient
import (
"context"
"github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gctx"
+ "hotgo/api/servmsg"
"hotgo/internal/library/network/tcp"
- "hotgo/internal/model/input/msgin"
+ "hotgo/internal/model/input/servmsgin"
"hotgo/internal/service"
"hotgo/utility/simple"
)
@@ -12,7 +19,7 @@ import (
// tcp客户端
type sAuthClient struct {
client *tcp.Client
- summary *msgin.AuthSummaryData
+ summary *servmsgin.AuthSummaryModel
}
func init() {
@@ -23,6 +30,11 @@ func newAuthClient() *sAuthClient {
return &sAuthClient{}
}
+// Instance 获取实例
+func (s *sAuthClient) Instance() *tcp.Client {
+ return s.client
+}
+
// Start 启动服务
func (s *sAuthClient) Start(ctx context.Context) {
g.Log().Debug(ctx, "AuthClient start..")
@@ -38,39 +50,37 @@ func (s *sAuthClient) Start(ctx context.Context) {
return
}
- simple.SafeGo(ctx, func(ctx context.Context) {
- s.client, err = tcp.NewClient(&tcp.ClientConfig{
- Addr: config.Client.Auth.Address,
- Auth: &tcp.AuthMeta{
- Group: config.Client.Auth.Group,
- Name: config.Client.Auth.Name,
- AppId: config.Client.Auth.AppId,
- SecretKey: config.Client.Auth.SecretKey,
+ // 创建客户端配置
+ clientConfig := &tcp.ClientConfig{
+ Addr: config.Client.Auth.Address,
+ AutoReconnect: true,
+ Auth: &tcp.AuthMeta{
+ Name: config.Client.Auth.Name,
+ Extra: g.Map{
+ "test": 13,
},
- LoginEvent: s.onLoginEvent,
- CloseEvent: s.onCloseEvent,
- })
+ Group: config.Client.Auth.Group,
+ AppId: config.Client.Auth.AppId,
+ SecretKey: config.Client.Auth.SecretKey,
+ },
+ LoginEvent: s.onLoginEvent,
+ CloseEvent: s.onCloseEvent,
+ }
- if err != nil {
- g.Log().Errorf(ctx, "AuthClient NewClient fail:%+v", err)
- return
- }
+ simple.SafeGo(ctx, func(ctx context.Context) {
+ s.client = tcp.NewClient(clientConfig)
- err = s.client.RegisterRouter(map[string]tcp.RouterHandler{
- "ResponseAuthSummary": s.OnResponseAuthSummary,
- })
-
- if err != nil {
- g.Log().Errorf(ctx, "AuthClient RegisterRouter fail:%+v", err)
- return
- }
+ // 注册路由
+ s.client.RegisterRouter(
+ s.OnResponseAuthSummary, // 响应授权信息
+ s.OnResponseExampleHello, // 一个tcp请求例子
+ )
if err = s.client.Start(); err != nil {
g.Log().Errorf(ctx, "AuthClient Start fail:%+v", err)
return
}
})
-
}
// Stop 停止服务
@@ -81,22 +91,20 @@ func (s *sAuthClient) Stop(ctx context.Context) {
}
}
-// IsLogin 是否已登录认证
-func (s *sAuthClient) IsLogin() bool {
- if s.client == nil {
- return false
- }
- return s.client.IsLogin
-}
-
// onLoginEvent 登录认证成功事件
func (s *sAuthClient) onLoginEvent() {
+ ctx := gctx.New()
- // 获取授权数据
- _ = s.client.Send(s.client.Ctx, &msgin.AuthSummary{})
+ // 获取授权信息
+ s.client.Send(ctx, &servmsg.AuthSummaryReq{})
+
+ // 测试例子,实际使用时可以注释掉
+ s.testExample(ctx)
+
+ g.Log().Debug(ctx, "AuthClient login succeed.")
}
// onCloseEvent 连接关闭回调事件
func (s *sAuthClient) onCloseEvent() {
- // ...
+ g.Log().Debug(gctx.New(), "AuthClient closed.")
}
diff --git a/server/internal/logic/tcpclient/auth_handle.go b/server/internal/logic/tcpclient/auth_handle.go
index edb99d0..110ff64 100644
--- a/server/internal/logic/tcpclient/auth_handle.go
+++ b/server/internal/logic/tcpclient/auth_handle.go
@@ -1,24 +1,54 @@
+// Package tcpclient
+// @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 tcpclient
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
- "hotgo/internal/model/input/msgin"
+ "github.com/gogf/gf/v2/frame/g"
+ "hotgo/api/servmsg"
)
-// OnResponseAuthSummary 获取授权信息
-func (s *sAuthClient) OnResponseAuthSummary(ctx context.Context, args ...interface{}) {
- var in *msgin.ResponseAuthSummary
- if err := gconv.Scan(args[0], &in); err != nil {
- s.client.Logger.Warningf(ctx, "OnResponseAuthSummary Scan err:%+v", err)
- return
- }
-
- if err := in.GetError(); err != nil {
- s.client.Logger.Warningf(ctx, "OnResponseAuthSummary GetError:%+v", err)
+// OnResponseAuthSummary 响应授权信息
+func (s *sAuthClient) OnResponseAuthSummary(ctx context.Context, req *servmsg.AuthSummaryRes) {
+ if err := req.GetError(); err != nil {
+ g.Log().Warningf(ctx, "OnResponseAuthSummary GetError:%+v", err)
return
}
// 拿到授权的数据,可以是一些动态的功能、路由、权限控制等
- s.summary = in.Data
+ s.summary = req.Data
+}
+
+// OnResponseExampleHello 一个tcp请求例子
+func (s *sAuthClient) OnResponseExampleHello(ctx context.Context, req *servmsg.ExampleHelloRes) {
+ if err := req.GetError(); err != nil {
+ g.Log().Warningf(ctx, "OnResponseExampleHello GetError:%+v", err)
+ return
+ }
+
+ g.Log().Infof(ctx, "OnResponseExampleHello data:%+v", req.Data)
+}
+
+// testExample 测试例子
+func (s *sAuthClient) testExample(ctx context.Context) {
+ // 发起tcp请求
+ // 异步执行,服务端返回消息后会转到`OnResponseExampleHello`中
+ s.client.Send(ctx, &servmsg.ExampleHelloReq{
+ Name: "Tom",
+ })
+
+ // 发起rpc请求
+ // 同步执行,阻塞等待服务端返回消息
+ var req = &servmsg.ExampleRPCHelloReq{
+ Name: "Tony",
+ }
+ var res *servmsg.ExampleRPCHelloRes
+ if err := s.client.RequestScan(ctx, req, &res); err != nil {
+ g.Log().Warningf(ctx, "client.Request ExampleRPCHelloReq err:%+v", err)
+ return
+ }
+ g.Log().Infof(ctx, "ExampleRPCHelloRes data:%+v", res.Data)
}
diff --git a/server/internal/logic/tcpclient/client.go b/server/internal/logic/tcpclient/client.go
index e5d9df3..311a066 100644
--- a/server/internal/logic/tcpclient/client.go
+++ b/server/internal/logic/tcpclient/client.go
@@ -1 +1,6 @@
+// Package tcpclient
+// @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 tcpclient
diff --git a/server/internal/logic/tcpclient/cron.go b/server/internal/logic/tcpclient/cron.go
index eff8ae5..4e53649 100644
--- a/server/internal/logic/tcpclient/cron.go
+++ b/server/internal/logic/tcpclient/cron.go
@@ -1,8 +1,14 @@
+// Package tcpclient
+// @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 tcpclient
import (
"context"
"github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gctx"
"hotgo/internal/library/network/tcp"
"hotgo/internal/service"
"hotgo/utility/simple"
@@ -21,6 +27,11 @@ func newCronClient() *sCronClient {
return &sCronClient{}
}
+// Instance 获取实例
+func (s *sCronClient) Instance() *tcp.Client {
+ return s.client
+}
+
// Start 启动服务
func (s *sCronClient) Start(ctx context.Context) {
g.Log().Debug(ctx, "CronClient start..")
@@ -36,42 +47,39 @@ func (s *sCronClient) Start(ctx context.Context) {
return
}
+ // 创建客户端配置
+ clientConfig := &tcp.ClientConfig{
+ Addr: config.Client.Cron.Address,
+ AutoReconnect: true,
+ Auth: &tcp.AuthMeta{
+ Name: config.Client.Cron.Name,
+ Group: config.Client.Cron.Group,
+ AppId: config.Client.Cron.AppId,
+ SecretKey: config.Client.Cron.SecretKey,
+ },
+ LoginEvent: s.onLoginEvent,
+ CloseEvent: s.onCloseEvent,
+ }
+
simple.SafeGo(ctx, func(ctx context.Context) {
- s.client, err = tcp.NewClient(&tcp.ClientConfig{
- Addr: config.Client.Cron.Address,
- Auth: &tcp.AuthMeta{
- Group: config.Client.Cron.Group,
- Name: config.Client.Cron.Name,
- AppId: config.Client.Cron.AppId,
- SecretKey: config.Client.Cron.SecretKey,
- },
- LoginEvent: s.onLoginEvent,
- CloseEvent: s.onCloseEvent,
- })
+ s.client = tcp.NewClient(clientConfig)
- if err != nil {
- g.Log().Errorf(ctx, "CronClient NewClient fail:%+v", err)
- return
- }
+ // 注册RPC路由
+ s.client.RegisterRPCRouter(
+ s.OnCronDelete, // 删除任务
+ s.OnCronEdit, // 编辑任务
+ s.OnCronStatus, // 修改任务状态
+ s.OnCronOnlineExec, // 执行一次任务
+ )
- err = s.client.RegisterRouter(map[string]tcp.RouterHandler{
- "CronDelete": s.OnCronDelete, // 删除任务
- "CronEdit": s.OnCronEdit, // 编辑任务
- "CronStatus": s.OnCronStatus, // 修改任务状态
- "CronOnlineExec": s.OnCronOnlineExec, // 执行一次任务
- })
-
- if err != nil {
- g.Log().Errorf(ctx, "CronClient RegisterRouter fail:%+v", err)
- return
- }
+ // 注册拦截器
+ s.client.RegisterInterceptor(s.DefaultInterceptor)
if err = s.client.Start(); err != nil {
g.Log().Errorf(ctx, "CronClient Start fail:%+v", err)
return
}
})
-
}
// Stop 停止服务
@@ -82,20 +90,12 @@ func (s *sCronClient) Stop(ctx context.Context) {
}
}
-// IsLogin 是否已登录认证
-func (s *sCronClient) IsLogin() bool {
- if s.client == nil {
- return false
- }
- return s.client.IsLogin
-}
-
// onLoginEvent 登录认证成功事件
func (s *sCronClient) onLoginEvent() {
- // ...
+ g.Log().Debug(gctx.New(), "CronClient login succeed.")
}
// onCloseEvent 连接关闭回调事件
func (s *sCronClient) onCloseEvent() {
- // ...
+ g.Log().Debug(gctx.New(), "CronClient closed.")
}
diff --git a/server/internal/logic/tcpclient/cron_handle.go b/server/internal/logic/tcpclient/cron_handle.go
index fd4b3ae..c16cf61 100644
--- a/server/internal/logic/tcpclient/cron_handle.go
+++ b/server/internal/logic/tcpclient/cron_handle.go
@@ -1,96 +1,36 @@
+// Package tcpclient
+// @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 tcpclient
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
- "hotgo/internal/model/input/msgin"
+ "hotgo/api/servmsg"
"hotgo/internal/service"
)
// OnCronDelete 删除任务
-func (s *sCronClient) OnCronDelete(ctx context.Context, args ...interface{}) {
- var (
- in *msgin.CronDelete
- res = new(msgin.ResponseCronDelete)
- )
-
- if err := gconv.Scan(args[0], &in); err != nil {
- res.Code = 1
- res.Message = err.Error()
- _ = s.client.Reply(ctx, res)
- return
- }
-
- if err := service.SysCron().Delete(ctx, in.CronDeleteInp); err != nil {
- res.Code = 2
- res.Message = err.Error()
- }
-
- _ = s.client.Reply(ctx, res)
+func (s *sCronClient) OnCronDelete(ctx context.Context, req *servmsg.CronDeleteReq) (res *servmsg.CronDeleteRes, err error) {
+ err = service.SysCron().Delete(ctx, req.CronDeleteInp)
+ return
}
// OnCronEdit 编辑任务
-func (s *sCronClient) OnCronEdit(ctx context.Context, args ...interface{}) {
- var (
- in *msgin.CronEdit
- res = new(msgin.ResponseCronEdit)
- )
-
- if err := gconv.Scan(args[0], &in); err != nil {
- res.Code = 1
- res.Message = err.Error()
- _ = s.client.Reply(ctx, res)
- return
- }
-
- if err := service.SysCron().Edit(ctx, in.CronEditInp); err != nil {
- res.Code = 2
- res.Message = err.Error()
- }
-
- _ = s.client.Reply(ctx, res)
+func (s *sCronClient) OnCronEdit(ctx context.Context, req *servmsg.CronEditReq) (res *servmsg.CronEditRes, err error) {
+ err = service.SysCron().Edit(ctx, req.CronEditInp)
+ return
}
// OnCronStatus 修改任务状态
-func (s *sCronClient) OnCronStatus(ctx context.Context, args ...interface{}) {
- var (
- in *msgin.CronStatus
- res = new(msgin.ResponseCronStatus)
- )
-
- if err := gconv.Scan(args[0], &in); err != nil {
- res.Code = 1
- res.Message = err.Error()
- _ = s.client.Reply(ctx, res)
- return
- }
-
- if err := service.SysCron().Status(ctx, in.CronStatusInp); err != nil {
- res.Code = 2
- res.Message = err.Error()
- }
-
- _ = s.client.Reply(ctx, res)
+func (s *sCronClient) OnCronStatus(ctx context.Context, req *servmsg.CronStatusReq) (res *servmsg.CronStatusRes, err error) {
+ err = service.SysCron().Status(ctx, req.CronStatusInp)
+ return
}
// OnCronOnlineExec 执行一次任务
-func (s *sCronClient) OnCronOnlineExec(ctx context.Context, args ...interface{}) {
- var (
- in *msgin.CronOnlineExec
- res = new(msgin.ResponseCronOnlineExec)
- )
-
- if err := gconv.Scan(args[0], &in); err != nil {
- res.Code = 1
- res.Message = err.Error()
- _ = s.client.Reply(ctx, res)
- return
- }
-
- if err := service.SysCron().OnlineExec(ctx, in.OnlineExecInp); err != nil {
- res.Code = 1
- res.Message = err.Error()
- }
-
- _ = s.client.Reply(ctx, res)
+func (s *sCronClient) OnCronOnlineExec(ctx context.Context, req *servmsg.CronOnlineExecReq) (res *servmsg.CronOnlineExecRes, err error) {
+ err = service.SysCron().OnlineExec(ctx, req.OnlineExecInp)
+ return
}
diff --git a/server/internal/logic/tcpclient/cron_interceptor.go b/server/internal/logic/tcpclient/cron_interceptor.go
new file mode 100644
index 0000000..5637c8f
--- /dev/null
+++ b/server/internal/logic/tcpclient/cron_interceptor.go
@@ -0,0 +1,18 @@
+// Package tcpclient
+// @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 tcpclient
+
+import (
+ "context"
+ "hotgo/internal/library/network/tcp"
+)
+
+// DefaultInterceptor 默认拦截器
+func (s *sCronClient) DefaultInterceptor(ctx context.Context, msg *tcp.Message) (err error) {
+ //conn := tcp.ConnFromCtx(ctx)
+ //g.Log().Debugf(ctx, "DefaultInterceptor msg:%+v, conn:%+v", msg, gjson.New(conn).String())
+ return
+}
diff --git a/server/internal/logic/tcpserver/auth_handle.go b/server/internal/logic/tcpserver/auth_handle.go
index 13be139..f150e90 100644
--- a/server/internal/logic/tcpserver/auth_handle.go
+++ b/server/internal/logic/tcpserver/auth_handle.go
@@ -1,76 +1,80 @@
+// Package tcpserver
+// @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 tcpserver
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/util/gconv"
+ "hotgo/api/servmsg"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/network/tcp"
"hotgo/internal/model/entity"
- "hotgo/internal/model/input/msgin"
+ "hotgo/internal/model/input/servmsgin"
+ "hotgo/internal/service"
)
// OnAuthSummary 获取授权信息
-func (s *sTCPServer) OnAuthSummary(ctx context.Context, args ...interface{}) {
+func (s *sTCPServer) OnAuthSummary(ctx context.Context, req *servmsg.AuthSummaryReq) {
var (
- in *msgin.AuthSummary
- user = tcp.GetCtx(ctx)
- res = new(msgin.ResponseAuthSummary)
+ conn = tcp.ConnFromCtx(ctx)
models *entity.SysServeLicense
+ res = new(servmsg.AuthSummaryRes)
)
- if err := gconv.Scan(args, &in); err != nil {
- res.Code = 1
- res.Message = err.Error()
- _ = s.serv.Reply(ctx, res)
+ if conn == nil {
+ g.Log().Warningf(ctx, "conn is nil.")
return
}
- if user.Auth == nil {
- res.Code = 2
- res.Message = "登录信息获取失败,请重新登录"
- _ = s.serv.Reply(ctx, res)
+ if conn.Auth == nil {
+ res.SetError(gerror.New("登录信息获取失败,请重新登录"))
+ conn.Send(ctx, res)
return
}
- if err := dao.SysServeLicense.Ctx(ctx).Where("appid = ?", user.Auth.AppId).Scan(&models); err != nil {
- res.Code = 3
- res.Message = err.Error()
- _ = s.serv.Reply(ctx, res)
+ if err := dao.SysServeLicense.Ctx(ctx).Where("appid = ?", conn.Auth.AppId).Scan(&models); err != nil {
+ res.SetError(err)
+ conn.Send(ctx, res)
return
}
if models == nil {
- res.Code = 4
- res.Message = "授权信息不存在"
- _ = s.serv.Reply(ctx, res)
+ res.SetError(gerror.New("授权信息不存在"))
+ conn.Send(ctx, res)
return
}
if models.Status != consts.StatusEnabled {
- res.Code = 5
- res.Message = "授权已禁用,请联系管理员"
- _ = s.serv.Reply(ctx, res)
+ res.SetError(gerror.New("授权已禁用,请联系管理员"))
+ conn.Send(ctx, res)
return
}
- if models.Group != user.Auth.Group {
- res.Code = 6
- res.Message = "你登录的授权分组未得到授权,请联系管理员"
- _ = s.serv.Reply(ctx, res)
+ if models.Group != conn.Auth.Group {
+ res.SetError(gerror.New("你登录的授权分组未得到授权,请联系管理员"))
+ conn.Send(ctx, res)
return
}
if models.EndAt.Before(gtime.Now()) {
- res.Code = 7
- res.Message = "授权已过期,请联系管理员"
- _ = s.serv.Reply(ctx, res)
+ res.SetError(gerror.New("授权已过期,请联系管理员"))
+ conn.Send(ctx, res)
return
}
- res.Data = new(msgin.AuthSummaryData)
- res.Data.EndAt = models.EndAt
- res.Data.Online = models.Online
- _ = s.serv.Reply(ctx, res)
+ data := new(servmsgin.AuthSummaryModel)
+ data.EndAt = models.EndAt
+ data.Online = service.TCPServer().Instance().GetAppIdOnline(models.Appid)
+
+ // 请填充你的授权数据
+ // ...
+
+ res.Data = data
+ conn.Send(ctx, res)
}
diff --git a/server/internal/logic/tcpserver/cron_handle.go b/server/internal/logic/tcpserver/cron_handle.go
index ca1f59e..d6a5a24 100644
--- a/server/internal/logic/tcpserver/cron_handle.go
+++ b/server/internal/logic/tcpserver/cron_handle.go
@@ -1,117 +1,97 @@
+// Package tcpserver
+// @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 tcpserver
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/util/gconv"
+ "hotgo/api/servmsg"
"hotgo/internal/consts"
- "hotgo/internal/model/input/msgin"
)
// CronDelete 删除任务
-func (s *sTCPServer) CronDelete(ctx context.Context, in *msgin.CronDelete) (err error) {
- clients := s.serv.GetGroupClients(consts.TCPClientGroupCron)
+func (s *sTCPServer) CronDelete(ctx context.Context, in *servmsg.CronDeleteReq) (err error) {
+ clients := s.serv.GetGroupClients(consts.LicenseGroupCron)
if len(clients) == 0 {
err = gerror.New("没有在线的定时任务服务")
return
}
for _, client := range clients {
- res, err := s.serv.RpcRequest(ctx, client, in)
- if err != nil {
- return err
+ var res servmsg.CronDeleteRes
+ if err = s.serv.RequestScan(ctx, client, in, &res); err != nil {
+ return
}
- var resp = new(msgin.ResponseCronDelete)
- if err = gconv.Scan(res, &resp); err != nil {
- return err
- }
-
- if err = resp.GetError(); err != nil {
- return err
+ if err = res.GetError(); err != nil {
+ return
}
}
-
return
}
// CronEdit 编辑任务
-func (s *sTCPServer) CronEdit(ctx context.Context, in *msgin.CronEdit) (err error) {
- clients := s.serv.GetGroupClients(consts.TCPClientGroupCron)
+func (s *sTCPServer) CronEdit(ctx context.Context, in *servmsg.CronEditReq) (err error) {
+ clients := s.serv.GetGroupClients(consts.LicenseGroupCron)
if len(clients) == 0 {
err = gerror.New("没有在线的定时任务服务")
return
}
for _, client := range clients {
- res, err := s.serv.RpcRequest(ctx, client, in)
- if err != nil {
- return err
+ var res servmsg.CronEditRes
+ if err = s.serv.RequestScan(ctx, client, in, &res); err != nil {
+ return
}
- var resp = new(msgin.ResponseCronEdit)
- if err = gconv.Scan(res, &resp); err != nil {
- return err
- }
-
- if err = resp.GetError(); err != nil {
- return err
+ if err = res.GetError(); err != nil {
+ return
}
}
-
return
}
// CronStatus 修改任务状态
-func (s *sTCPServer) CronStatus(ctx context.Context, in *msgin.CronStatus) (err error) {
- clients := s.serv.GetGroupClients(consts.TCPClientGroupCron)
+func (s *sTCPServer) CronStatus(ctx context.Context, in *servmsg.CronStatusReq) (err error) {
+ clients := s.serv.GetGroupClients(consts.LicenseGroupCron)
if len(clients) == 0 {
err = gerror.New("没有在线的定时任务服务")
return
}
for _, client := range clients {
- res, err := s.serv.RpcRequest(ctx, client, in)
- if err != nil {
- return err
+ var res servmsg.CronStatusRes
+ if err = s.serv.RequestScan(ctx, client, in, &res); err != nil {
+ return
}
- var resp = new(msgin.ResponseCronStatus)
- if err = gconv.Scan(res, &resp); err != nil {
- return err
- }
-
- if err = resp.GetError(); err != nil {
- return err
+ if err = res.GetError(); err != nil {
+ return
}
}
-
return
}
// CronOnlineExec 执行一次任务
-func (s *sTCPServer) CronOnlineExec(ctx context.Context, in *msgin.CronOnlineExec) (err error) {
- clients := s.serv.GetGroupClients(consts.TCPClientGroupCron)
+func (s *sTCPServer) CronOnlineExec(ctx context.Context, in *servmsg.CronOnlineExecReq) (err error) {
+ clients := s.serv.GetGroupClients(consts.LicenseGroupCron)
if len(clients) == 0 {
err = gerror.New("没有在线的定时任务服务")
return
}
for _, client := range clients {
- res, err := s.serv.RpcRequest(ctx, client, in)
- if err != nil {
- return err
+ var res servmsg.CronOnlineExecRes
+ if err = s.serv.RequestScan(ctx, client, in, &res); err != nil {
+ return
}
- var resp = new(msgin.ResponseCronOnlineExec)
- if err = gconv.Scan(res, &resp); err != nil {
- return err
- }
-
- if err = resp.GetError(); err != nil {
- return err
+ if err = res.GetError(); err != nil {
+ return
}
}
-
return
}
diff --git a/server/internal/logic/tcpserver/example_handle.go b/server/internal/logic/tcpserver/example_handle.go
new file mode 100644
index 0000000..3f22574
--- /dev/null
+++ b/server/internal/logic/tcpserver/example_handle.go
@@ -0,0 +1,49 @@
+package tcpserver
+
+import (
+ "context"
+ "fmt"
+ "github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gtime"
+ "hotgo/api/servmsg"
+ "hotgo/internal/consts"
+ "hotgo/internal/library/network/tcp"
+ "hotgo/internal/model/input/servmsgin"
+)
+
+// OnExampleHello 一个tcp请求例子
+func (s *sTCPServer) OnExampleHello(ctx context.Context, req *servmsg.ExampleHelloReq) {
+ var (
+ conn = tcp.ConnFromCtx(ctx)
+ res = new(servmsg.ExampleHelloRes)
+ data = new(servmsgin.ExampleHelloModel)
+ )
+
+ if conn == nil {
+ g.Log().Warningf(ctx, "conn is nil.")
+ return
+ }
+
+ if conn.Auth == nil {
+ res.SetError(gerror.New("连接未认证,请确认已登录成功!"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ data.Desc = fmt.Sprintf("Hello %v, 你的APPID:%v,当前HotGo版本:%v,你成功请求了`servmsg.ExampleHelloReq`接口!", req.Name, conn.Auth.AppId, consts.VersionApp)
+ data.Timestamp = gtime.Now()
+ res.Data = data
+ conn.Send(ctx, res)
+}
+
+// OnExampleRPCHello 一个rpc请求例子
+func (s *sTCPServer) OnExampleRPCHello(ctx context.Context, req *servmsg.ExampleRPCHelloReq) (res *servmsg.ExampleRPCHelloRes, err error) {
+ var data = new(servmsgin.ExampleHelloModel)
+ data.Desc = fmt.Sprintf("Hello %v, 当前HotGo版本:%v,你成功请求了`servmsg.ExampleRPCHelloReq`接口!", req.Name, consts.VersionApp)
+ data.Timestamp = gtime.Now()
+
+ res = new(servmsg.ExampleRPCHelloRes)
+ res.Data = data
+ return
+}
diff --git a/server/internal/logic/tcpserver/server.go b/server/internal/logic/tcpserver/server.go
index 7dc830d..c0dd88b 100644
--- a/server/internal/logic/tcpserver/server.go
+++ b/server/internal/logic/tcpserver/server.go
@@ -1,3 +1,8 @@
+// Package tcpserver
+// @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 tcpserver
import (
@@ -20,40 +25,39 @@ func newTCPServer() *sTCPServer {
return &sTCPServer{}
}
+// Instance 获取实例
+func (s *sTCPServer) Instance() *tcp.Server {
+ return s.serv
+}
+
// Start 启动服务
func (s *sTCPServer) Start(ctx context.Context) {
simple.SafeGo(ctx, func(ctx context.Context) {
g.Log().Debug(ctx, "TCPServer start..")
- server, err := tcp.NewServer(&tcp.ServerConfig{
+ s.serv = tcp.NewServer(&tcp.ServerConfig{
Name: simple.AppName(ctx),
Addr: g.Cfg().MustGet(ctx, "tcp.server.address").String(),
})
- if err != nil {
- g.Log().Warningf(ctx, "TCPServer start fail:%+v", err)
- return
- }
+ // 注册路由
+ s.serv.RegisterRouter(
+ s.onServerLogin, // 服务登录
+ s.onServerHeartbeat, // 心跳
+ s.OnAuthSummary, // 获取授权信息
+ s.OnExampleHello, // 一个tcp请求例子
+ )
- s.serv = server
+ // 注册RPC路由
+ s.serv.RegisterRPCRouter(
+ s.OnExampleRPCHello, // 一个rpc请求例子
+ )
- // 消息队列路由
- s.serv.RegisterQueueRouter(map[string]tcp.RouterHandler{
- // ...
- })
-
- // 定时任务路由
- s.serv.RegisterCronRouter(map[string]tcp.RouterHandler{
- // ...
- })
-
- // 授权服务路由
- s.serv.RegisterAuthRouter(map[string]tcp.RouterHandler{
- "AuthSummary": s.OnAuthSummary, // 获取授权信息
- })
+ // 注册拦截器
+ s.serv.RegisterInterceptor(s.DefaultInterceptor, s.PreFilterInterceptor)
// 服务监听
- if err = s.serv.Listen(); err != nil {
+ if err := s.serv.Listen(); err != nil {
if !s.serv.IsClose() {
g.Log().Warningf(ctx, "TCPServer Listen err:%v", err)
}
diff --git a/server/internal/logic/tcpserver/server_handle.go b/server/internal/logic/tcpserver/server_handle.go
new file mode 100644
index 0000000..bf9be35
--- /dev/null
+++ b/server/internal/logic/tcpserver/server_handle.go
@@ -0,0 +1,167 @@
+// Package tcpserver
+// @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 tcpserver
+
+import (
+ "context"
+ "fmt"
+ "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/internal/consts"
+ "hotgo/internal/dao"
+ "hotgo/internal/library/network/tcp"
+ "hotgo/internal/model/entity"
+ "hotgo/utility/convert"
+ "hotgo/utility/encrypt"
+)
+
+// onServerLogin 处理客户端登录
+func (s *sTCPServer) onServerLogin(ctx context.Context, req *tcp.ServerLoginReq) {
+ var (
+ conn = tcp.ConnFromCtx(ctx)
+ models *entity.SysServeLicense
+ res = new(tcp.ServerLoginRes)
+ cols = dao.SysServeLicense.Columns()
+ )
+
+ if conn == nil {
+ g.Log().Warningf(ctx, "conn is nil.")
+ return
+ }
+
+ if err := dao.SysServeLicense.Ctx(ctx).Where(cols.Appid, req.AppId).Scan(&models); err != nil {
+ return
+ }
+ if models == nil {
+ res.SetError(gerror.New("授权信息不存在"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ // 验证签名
+ sign := encrypt.Md5ToString(fmt.Sprintf("%v%v%v", models.Appid, req.Timestamp, models.SecretKey))
+ if sign != req.Sign {
+ res.SetError(gerror.New("签名错误,请检查!"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ if models.Status != consts.StatusEnabled {
+ res.SetError(gerror.New("授权已禁用,请联系管理员"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ if models.Group != req.Group {
+ res.SetError(gerror.New("你登录的授权分组未得到授权,请联系管理员"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ if models.EndAt.Before(gtime.Now()) {
+ res.SetError(gerror.New("授权已过期,请联系管理员"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ ip := gstr.StrTillEx(conn.RemoteAddr().String(), ":")
+ if !convert.MatchIpStrategy(models.AllowedIps, ip) {
+ res.SetError(gerror.New("IP(" + ip + ")未授权,请联系管理员"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ var routes []string
+ if err := models.Routes.Scan(&routes); err != nil {
+ res.SetError(gerror.New("授权路由解析失败,请联系管理员"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ // 拿出当前登录应用的所有客户端
+ clients := s.serv.GetAppIdClients(models.Appid)
+
+ // 检查多地登录,如果连接超过上限,则断开当前许可证下的所有连接
+ if len(clients)+1 > models.OnlineLimit {
+ for _, client := range clients {
+ client.Close()
+ }
+ res.SetError(gerror.New("授权登录端超出上限,请勿多地登录"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ for _, client := range clients {
+ if client.Auth.Name == req.Name {
+ res.SetError(gerror.Newf("应用名称[%v]已存在登录用户,当前连接已被拒绝。", req.Name))
+ conn.Send(ctx, res)
+ return
+ }
+ }
+
+ auth := &tcp.AuthMeta{
+ Name: req.Name,
+ Extra: req.Extra,
+ Group: models.Group,
+ AppId: models.Appid,
+ SecretKey: models.SecretKey,
+ EndAt: models.EndAt,
+ Routes: routes,
+ }
+ s.serv.AuthClient(conn, auth)
+
+ update := g.Map{
+ cols.LoginTimes: models.LoginTimes + 1,
+ cols.LastLoginAt: gtime.Now(),
+ cols.LastActiveAt: gtime.Now(),
+ cols.RemoteAddr: conn.RemoteAddr().String(),
+ }
+ if _, err := dao.SysServeLicense.Ctx(ctx).Where(cols.Id, models.Id).Data(update).Update(); err != nil {
+ res.SetError(err)
+ conn.Send(ctx, res)
+ return
+ }
+
+ g.Log().Debugf(ctx, "onServerLogin succeed. appid:%v, group:%v, name:%v", auth.AppId, auth.Group, auth.Name)
+ conn.Send(ctx, res)
+}
+
+// onServerHeartbeat 处理客户端心跳
+func (s *sTCPServer) onServerHeartbeat(ctx context.Context, req *tcp.ServerHeartbeatReq) {
+ var (
+ conn = tcp.ConnFromCtx(ctx)
+ res = new(tcp.ServerHeartbeatRes)
+ )
+
+ if conn == nil {
+ g.Log().Warningf(ctx, "conn is nil.")
+ return
+ }
+
+ client := s.serv.GetClient(conn.Conn)
+ if client == nil {
+ res.SetError(gerror.New("登录异常,请重新登录"))
+ conn.Send(ctx, res)
+ return
+ }
+
+ // 更新心跳
+ client.Heartbeat = gtime.Timestamp()
+
+ // 更新活跃时间
+ update := g.Map{
+ dao.SysServeLicense.Columns().LastActiveAt: gtime.Now(),
+ }
+ if _, err := dao.SysServeLicense.Ctx(ctx).Where(dao.SysServeLicense.Columns().Appid, client.Auth.AppId).Data(update).Update(); err != nil {
+ res.SetError(err)
+ conn.Send(ctx, res)
+ return
+ }
+
+ conn.Send(ctx, res)
+}
diff --git a/server/internal/logic/tcpserver/server_interceptor.go b/server/internal/logic/tcpserver/server_interceptor.go
new file mode 100644
index 0000000..40f9cd6
--- /dev/null
+++ b/server/internal/logic/tcpserver/server_interceptor.go
@@ -0,0 +1,75 @@
+// Package tcpserver
+// @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 tcpserver
+
+import (
+ "context"
+ "github.com/gogf/gf/v2/errors/gcode"
+ "github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/os/gtime"
+ "hotgo/internal/library/network/tcp"
+ "hotgo/utility/validate"
+)
+
+// 免登录路由
+var noLoginRouter = map[string]struct{}{
+ "ServerLoginReq": {}, // 服务登录
+}
+
+// 免验证路由
+var noVerifyRouter = map[string]struct{}{
+ "ServerHeartbeatReq": {}, // 心跳
+}
+
+func (s *sTCPServer) isNoLoginRouter(router string) bool {
+ _, ok := noLoginRouter[router]
+ return ok
+}
+
+func (s *sTCPServer) isNoVerifyRouter(router string) bool {
+ _, ok := noVerifyRouter[router]
+ return ok
+}
+
+// DefaultInterceptor 默认拦截器
+func (s *sTCPServer) DefaultInterceptor(ctx context.Context, msg *tcp.Message) (err error) {
+ conn := tcp.ConnFromCtx(ctx)
+ //g.Log().Debugf(ctx, "DefaultInterceptor msg:%+v, conn:%+v", msg, gjson.New(conn).String())
+
+ // 免登录
+ if s.isNoLoginRouter(msg.Router) {
+ return
+ }
+
+ if conn.Auth == nil {
+ err = gerror.NewCode(gcode.CodeNotAuthorized, "未进行登录认证,请先登录")
+ return
+ }
+
+ // 检查授权有效期
+ if conn.Auth.EndAt.Before(gtime.Now()) {
+ err = gerror.NewCode(gcode.CodeNotAuthorized, "授权已过期")
+ return
+ }
+
+ // 免验证
+ if s.isNoVerifyRouter(msg.Router) {
+ return
+ }
+
+ // 验证路由权限
+ if len(conn.Auth.Routes) > 0 && !validate.InSlice(conn.Auth.Routes, msg.Router) {
+ err = gerror.NewCodef(gcode.CodeNotAuthorized, "没有授权路由访问权限:%v", msg.Router)
+ return
+ }
+ return
+}
+
+// PreFilterInterceptor 预处理
+func (s *sTCPServer) PreFilterInterceptor(ctx context.Context, msg *tcp.Message) (err error) {
+ //g.Log().Debug(ctx, "PreFilterInterceptor...")
+ return
+}
diff --git a/server/internal/model/do/addon_hgexample_table.go b/server/internal/model/do/addon_hgexample_table.go
index 96cdc69..b543bb3 100644
--- a/server/internal/model/do/addon_hgexample_table.go
+++ b/server/internal/model/do/addon_hgexample_table.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_cash.go b/server/internal/model/do/admin_cash.go
index f2d4d6f..e3e3a16 100644
--- a/server/internal/model/do/admin_cash.go
+++ b/server/internal/model/do/admin_cash.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_credits_log.go b/server/internal/model/do/admin_credits_log.go
index 7aed38a..f334b6b 100644
--- a/server/internal/model/do/admin_credits_log.go
+++ b/server/internal/model/do/admin_credits_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_dept.go b/server/internal/model/do/admin_dept.go
index 9d9e520..a4d2b26 100644
--- a/server/internal/model/do/admin_dept.go
+++ b/server/internal/model/do/admin_dept.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_member.go b/server/internal/model/do/admin_member.go
index 5b281d8..e9082e2 100644
--- a/server/internal/model/do/admin_member.go
+++ b/server/internal/model/do/admin_member.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_member_post.go b/server/internal/model/do/admin_member_post.go
index 9bc52b4..6e5796c 100644
--- a/server/internal/model/do/admin_member_post.go
+++ b/server/internal/model/do/admin_member_post.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_member_role.go b/server/internal/model/do/admin_member_role.go
index 290da60..f96c297 100644
--- a/server/internal/model/do/admin_member_role.go
+++ b/server/internal/model/do/admin_member_role.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_menu.go b/server/internal/model/do/admin_menu.go
index 771db51..fbbc02f 100644
--- a/server/internal/model/do/admin_menu.go
+++ b/server/internal/model/do/admin_menu.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_notice.go b/server/internal/model/do/admin_notice.go
index cb6e97f..e5b05f3 100644
--- a/server/internal/model/do/admin_notice.go
+++ b/server/internal/model/do/admin_notice.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_notice_read.go b/server/internal/model/do/admin_notice_read.go
index f8d204a..876691d 100644
--- a/server/internal/model/do/admin_notice_read.go
+++ b/server/internal/model/do/admin_notice_read.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_oauth.go b/server/internal/model/do/admin_oauth.go
index 0e857ee..94b4e13 100644
--- a/server/internal/model/do/admin_oauth.go
+++ b/server/internal/model/do/admin_oauth.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_order.go b/server/internal/model/do/admin_order.go
index d27777b..6eaec0e 100644
--- a/server/internal/model/do/admin_order.go
+++ b/server/internal/model/do/admin_order.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_post.go b/server/internal/model/do/admin_post.go
index 10363b9..2d9c010 100644
--- a/server/internal/model/do/admin_post.go
+++ b/server/internal/model/do/admin_post.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
@@ -16,7 +16,7 @@ type AdminPost struct {
Code interface{} // 岗位编码
Name interface{} // 岗位名称
Remark interface{} // 备注
- Sort interface{} // 显示顺序
+ Sort interface{} // 排序
Status interface{} // 状态
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
diff --git a/server/internal/model/do/admin_role.go b/server/internal/model/do/admin_role.go
index 99f6d1b..684e08d 100644
--- a/server/internal/model/do/admin_role.go
+++ b/server/internal/model/do/admin_role.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_role_casbin.go b/server/internal/model/do/admin_role_casbin.go
index 03a8da2..1d21a6e 100644
--- a/server/internal/model/do/admin_role_casbin.go
+++ b/server/internal/model/do/admin_role_casbin.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/admin_role_menu.go b/server/internal/model/do/admin_role_menu.go
index d2722df..2357bad 100644
--- a/server/internal/model/do/admin_role_menu.go
+++ b/server/internal/model/do/admin_role_menu.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/pay_log.go b/server/internal/model/do/pay_log.go
index f09280f..58f2808 100644
--- a/server/internal/model/do/pay_log.go
+++ b/server/internal/model/do/pay_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/pay_refund.go b/server/internal/model/do/pay_refund.go
index cfec5af..a5eff41 100644
--- a/server/internal/model/do/pay_refund.go
+++ b/server/internal/model/do/pay_refund.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_addons_config.go b/server/internal/model/do/sys_addons_config.go
index c5d937d..37b50b5 100644
--- a/server/internal/model/do/sys_addons_config.go
+++ b/server/internal/model/do/sys_addons_config.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_attachment.go b/server/internal/model/do/sys_attachment.go
index 414a992..e488036 100644
--- a/server/internal/model/do/sys_attachment.go
+++ b/server/internal/model/do/sys_attachment.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
@@ -19,7 +19,7 @@ type SysAttachment struct {
Drive interface{} // 上传驱动
Name interface{} // 文件原始名
Kind interface{} // 上传类型
- MetaType interface{} // 文件类型
+ MimeType interface{} // 扩展类型
NaiveType interface{} // NaiveUI类型
Path interface{} // 本地路径
FileUrl interface{} // url
diff --git a/server/internal/model/do/sys_blacklist.go b/server/internal/model/do/sys_blacklist.go
index 49b673c..a389469 100644
--- a/server/internal/model/do/sys_blacklist.go
+++ b/server/internal/model/do/sys_blacklist.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_config.go b/server/internal/model/do/sys_config.go
index 1ee1a30..958658d 100644
--- a/server/internal/model/do/sys_config.go
+++ b/server/internal/model/do/sys_config.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_cron.go b/server/internal/model/do/sys_cron.go
index adc5e60..241711c 100644
--- a/server/internal/model/do/sys_cron.go
+++ b/server/internal/model/do/sys_cron.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_cron_group.go b/server/internal/model/do/sys_cron_group.go
index 0bbd892..a48f7eb 100644
--- a/server/internal/model/do/sys_cron_group.go
+++ b/server/internal/model/do/sys_cron_group.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_dict_data.go b/server/internal/model/do/sys_dict_data.go
index 1ef3568..98940f2 100644
--- a/server/internal/model/do/sys_dict_data.go
+++ b/server/internal/model/do/sys_dict_data.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_dict_type.go b/server/internal/model/do/sys_dict_type.go
index 3fe3775..66087bc 100644
--- a/server/internal/model/do/sys_dict_type.go
+++ b/server/internal/model/do/sys_dict_type.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_ems_log.go b/server/internal/model/do/sys_ems_log.go
index 4829920..99dc243 100644
--- a/server/internal/model/do/sys_ems_log.go
+++ b/server/internal/model/do/sys_ems_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_gen_codes.go b/server/internal/model/do/sys_gen_codes.go
index a190f92..b6d7a56 100644
--- a/server/internal/model/do/sys_gen_codes.go
+++ b/server/internal/model/do/sys_gen_codes.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_gen_curd_demo.go b/server/internal/model/do/sys_gen_curd_demo.go
index 82b6644..51b4661 100644
--- a/server/internal/model/do/sys_gen_curd_demo.go
+++ b/server/internal/model/do/sys_gen_curd_demo.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_log.go b/server/internal/model/do/sys_log.go
index 7212288..c8650c3 100644
--- a/server/internal/model/do/sys_log.go
+++ b/server/internal/model/do/sys_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_login_log.go b/server/internal/model/do/sys_login_log.go
index 30aeef7..80fbaba 100644
--- a/server/internal/model/do/sys_login_log.go
+++ b/server/internal/model/do/sys_login_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_provinces.go b/server/internal/model/do/sys_provinces.go
index f1ae90f..e559a67 100644
--- a/server/internal/model/do/sys_provinces.go
+++ b/server/internal/model/do/sys_provinces.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_serve_license.go b/server/internal/model/do/sys_serve_license.go
index c7cc423..062c7c1 100644
--- a/server/internal/model/do/sys_serve_license.go
+++ b/server/internal/model/do/sys_serve_license.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
@@ -18,16 +18,14 @@ type SysServeLicense struct {
Name interface{} // 许可名称
Appid interface{} // 应用ID
SecretKey interface{} // 应用秘钥
- Desc interface{} // 授权说明
RemoteAddr interface{} // 最后连接地址
- Online interface{} // 在线数量
- OnlineLimit interface{} // 在线数量限制,默认1
+ OnlineLimit interface{} // 在线限制
LoginTimes interface{} // 登录次数
LastLoginAt *gtime.Time // 最后登录时间
- LastActiveAt *gtime.Time // 最后活跃时间
+ LastActiveAt *gtime.Time // 最后心跳
Routes *gjson.Json // 路由表,空使用默认分组路由
- AllowedIps interface{} // 白名单,*代表所有,只有允许的IP才能连接到tcp服务
- EndAt *gtime.Time // 授权结束时间
+ AllowedIps interface{} // IP白名单
+ EndAt *gtime.Time // 授权有效期
Remark interface{} // 备注
Status interface{} // 状态
CreatedAt *gtime.Time // 创建时间
diff --git a/server/internal/model/do/sys_serve_log.go b/server/internal/model/do/sys_serve_log.go
index 2880214..4382997 100644
--- a/server/internal/model/do/sys_serve_log.go
+++ b/server/internal/model/do/sys_serve_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/sys_sms_log.go b/server/internal/model/do/sys_sms_log.go
index 4bc24ef..6b1daa4 100644
--- a/server/internal/model/do/sys_sms_log.go
+++ b/server/internal/model/do/sys_sms_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/do/test_category.go b/server/internal/model/do/test_category.go
index 54d606d..9488d11 100644
--- a/server/internal/model/do/test_category.go
+++ b/server/internal/model/do/test_category.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
diff --git a/server/internal/model/entity/addon_hgexample_table.go b/server/internal/model/entity/addon_hgexample_table.go
index 246b106..c0aeda7 100644
--- a/server/internal/model/entity/addon_hgexample_table.go
+++ b/server/internal/model/entity/addon_hgexample_table.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_cash.go b/server/internal/model/entity/admin_cash.go
index 9e4a838..8654d2f 100644
--- a/server/internal/model/entity/admin_cash.go
+++ b/server/internal/model/entity/admin_cash.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_credits_log.go b/server/internal/model/entity/admin_credits_log.go
index e00632a..9ae45d9 100644
--- a/server/internal/model/entity/admin_credits_log.go
+++ b/server/internal/model/entity/admin_credits_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_dept.go b/server/internal/model/entity/admin_dept.go
index f9e50a2..418d971 100644
--- a/server/internal/model/entity/admin_dept.go
+++ b/server/internal/model/entity/admin_dept.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_member.go b/server/internal/model/entity/admin_member.go
index ababd28..429da0b 100644
--- a/server/internal/model/entity/admin_member.go
+++ b/server/internal/model/entity/admin_member.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_member_post.go b/server/internal/model/entity/admin_member_post.go
index 442d31f..7283793 100644
--- a/server/internal/model/entity/admin_member_post.go
+++ b/server/internal/model/entity/admin_member_post.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_member_role.go b/server/internal/model/entity/admin_member_role.go
index 62af3d3..460cf09 100644
--- a/server/internal/model/entity/admin_member_role.go
+++ b/server/internal/model/entity/admin_member_role.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_menu.go b/server/internal/model/entity/admin_menu.go
index 5bb0cc9..83709eb 100644
--- a/server/internal/model/entity/admin_menu.go
+++ b/server/internal/model/entity/admin_menu.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_notice.go b/server/internal/model/entity/admin_notice.go
index 59486d8..483eed4 100644
--- a/server/internal/model/entity/admin_notice.go
+++ b/server/internal/model/entity/admin_notice.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_notice_read.go b/server/internal/model/entity/admin_notice_read.go
index 4bfb40e..ac61f59 100644
--- a/server/internal/model/entity/admin_notice_read.go
+++ b/server/internal/model/entity/admin_notice_read.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_oauth.go b/server/internal/model/entity/admin_oauth.go
index 43afb6f..13ea625 100644
--- a/server/internal/model/entity/admin_oauth.go
+++ b/server/internal/model/entity/admin_oauth.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_order.go b/server/internal/model/entity/admin_order.go
index 40f4389..66543d9 100644
--- a/server/internal/model/entity/admin_order.go
+++ b/server/internal/model/entity/admin_order.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_post.go b/server/internal/model/entity/admin_post.go
index c3f0eb8..4e9d2bd 100644
--- a/server/internal/model/entity/admin_post.go
+++ b/server/internal/model/entity/admin_post.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
@@ -14,7 +14,7 @@ type AdminPost struct {
Code string `json:"code" description:"岗位编码"`
Name string `json:"name" description:"岗位名称"`
Remark string `json:"remark" description:"备注"`
- Sort int `json:"sort" description:"显示顺序"`
+ Sort int `json:"sort" description:"排序"`
Status int `json:"status" description:"状态"`
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"`
diff --git a/server/internal/model/entity/admin_role.go b/server/internal/model/entity/admin_role.go
index cd3fe6e..62fa101 100644
--- a/server/internal/model/entity/admin_role.go
+++ b/server/internal/model/entity/admin_role.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_role_casbin.go b/server/internal/model/entity/admin_role_casbin.go
index 319a15f..3794d48 100644
--- a/server/internal/model/entity/admin_role_casbin.go
+++ b/server/internal/model/entity/admin_role_casbin.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/admin_role_menu.go b/server/internal/model/entity/admin_role_menu.go
index 6a12fdb..472bb56 100644
--- a/server/internal/model/entity/admin_role_menu.go
+++ b/server/internal/model/entity/admin_role_menu.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/pay_log.go b/server/internal/model/entity/pay_log.go
index 1a75a80..4d6a1cc 100644
--- a/server/internal/model/entity/pay_log.go
+++ b/server/internal/model/entity/pay_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/pay_refund.go b/server/internal/model/entity/pay_refund.go
index 83ab800..379b7f7 100644
--- a/server/internal/model/entity/pay_refund.go
+++ b/server/internal/model/entity/pay_refund.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_addons_config.go b/server/internal/model/entity/sys_addons_config.go
index 9260bce..021586d 100644
--- a/server/internal/model/entity/sys_addons_config.go
+++ b/server/internal/model/entity/sys_addons_config.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_attachment.go b/server/internal/model/entity/sys_attachment.go
index 3ca7fd3..26a693e 100644
--- a/server/internal/model/entity/sys_attachment.go
+++ b/server/internal/model/entity/sys_attachment.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
@@ -17,7 +17,7 @@ type SysAttachment struct {
Drive string `json:"drive" description:"上传驱动"`
Name string `json:"name" description:"文件原始名"`
Kind string `json:"kind" description:"上传类型"`
- MetaType string `json:"metaType" description:"文件类型"`
+ MimeType string `json:"mimeType" description:"扩展类型"`
NaiveType string `json:"naiveType" description:"NaiveUI类型"`
Path string `json:"path" description:"本地路径"`
FileUrl string `json:"fileUrl" description:"url"`
diff --git a/server/internal/model/entity/sys_blacklist.go b/server/internal/model/entity/sys_blacklist.go
index b307c36..1857e9d 100644
--- a/server/internal/model/entity/sys_blacklist.go
+++ b/server/internal/model/entity/sys_blacklist.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_config.go b/server/internal/model/entity/sys_config.go
index 62b3486..1e0f5f6 100644
--- a/server/internal/model/entity/sys_config.go
+++ b/server/internal/model/entity/sys_config.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_cron.go b/server/internal/model/entity/sys_cron.go
index bed11b2..5db59d0 100644
--- a/server/internal/model/entity/sys_cron.go
+++ b/server/internal/model/entity/sys_cron.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_cron_group.go b/server/internal/model/entity/sys_cron_group.go
index 7d16811..7f25513 100644
--- a/server/internal/model/entity/sys_cron_group.go
+++ b/server/internal/model/entity/sys_cron_group.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_dict_data.go b/server/internal/model/entity/sys_dict_data.go
index c917438..3127986 100644
--- a/server/internal/model/entity/sys_dict_data.go
+++ b/server/internal/model/entity/sys_dict_data.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_dict_type.go b/server/internal/model/entity/sys_dict_type.go
index b43032b..d6f50e0 100644
--- a/server/internal/model/entity/sys_dict_type.go
+++ b/server/internal/model/entity/sys_dict_type.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_ems_log.go b/server/internal/model/entity/sys_ems_log.go
index 79734de..a037cdf 100644
--- a/server/internal/model/entity/sys_ems_log.go
+++ b/server/internal/model/entity/sys_ems_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_gen_codes.go b/server/internal/model/entity/sys_gen_codes.go
index fa4daa2..ca63046 100644
--- a/server/internal/model/entity/sys_gen_codes.go
+++ b/server/internal/model/entity/sys_gen_codes.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_gen_curd_demo.go b/server/internal/model/entity/sys_gen_curd_demo.go
index 27c737a..2cfc42e 100644
--- a/server/internal/model/entity/sys_gen_curd_demo.go
+++ b/server/internal/model/entity/sys_gen_curd_demo.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_log.go b/server/internal/model/entity/sys_log.go
index 0c00078..1ca871a 100644
--- a/server/internal/model/entity/sys_log.go
+++ b/server/internal/model/entity/sys_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_login_log.go b/server/internal/model/entity/sys_login_log.go
index f652464..b37c2bd 100644
--- a/server/internal/model/entity/sys_login_log.go
+++ b/server/internal/model/entity/sys_login_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_provinces.go b/server/internal/model/entity/sys_provinces.go
index 797f9c9..beef421 100644
--- a/server/internal/model/entity/sys_provinces.go
+++ b/server/internal/model/entity/sys_provinces.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_serve_license.go b/server/internal/model/entity/sys_serve_license.go
index 0492f97..ee9f18d 100644
--- a/server/internal/model/entity/sys_serve_license.go
+++ b/server/internal/model/entity/sys_serve_license.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
@@ -16,16 +16,14 @@ type SysServeLicense struct {
Name string `json:"name" description:"许可名称"`
Appid string `json:"appid" description:"应用ID"`
SecretKey string `json:"secretKey" description:"应用秘钥"`
- Desc string `json:"desc" description:"授权说明"`
RemoteAddr string `json:"remoteAddr" description:"最后连接地址"`
- Online int `json:"online" description:"在线数量"`
- OnlineLimit int `json:"onlineLimit" description:"在线数量限制,默认1"`
+ OnlineLimit int `json:"onlineLimit" description:"在线限制"`
LoginTimes int64 `json:"loginTimes" description:"登录次数"`
LastLoginAt *gtime.Time `json:"lastLoginAt" description:"最后登录时间"`
- LastActiveAt *gtime.Time `json:"lastActiveAt" description:"最后活跃时间"`
+ LastActiveAt *gtime.Time `json:"lastActiveAt" description:"最后心跳"`
Routes *gjson.Json `json:"routes" description:"路由表,空使用默认分组路由"`
- AllowedIps string `json:"allowedIps" description:"白名单,*代表所有,只有允许的IP才能连接到tcp服务"`
- EndAt *gtime.Time `json:"endAt" description:"授权结束时间"`
+ AllowedIps string `json:"allowedIps" description:"IP白名单"`
+ EndAt *gtime.Time `json:"endAt" description:"授权有效期"`
Remark string `json:"remark" description:"备注"`
Status int `json:"status" description:"状态"`
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
diff --git a/server/internal/model/entity/sys_serve_log.go b/server/internal/model/entity/sys_serve_log.go
index 23d39ae..6c01f58 100644
--- a/server/internal/model/entity/sys_serve_log.go
+++ b/server/internal/model/entity/sys_serve_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/sys_sms_log.go b/server/internal/model/entity/sys_sms_log.go
index 6e1570c..ef108b3 100644
--- a/server/internal/model/entity/sys_sms_log.go
+++ b/server/internal/model/entity/sys_sms_log.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/entity/test_category.go b/server/internal/model/entity/test_category.go
index 50acca9..27ece9f 100644
--- a/server/internal/model/entity/test_category.go
+++ b/server/internal/model/entity/test_category.go
@@ -1,5 +1,5 @@
// =================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
diff --git a/server/internal/model/input/adminin/cash.go b/server/internal/model/input/adminin/cash.go
index affd223..4b7e25d 100644
--- a/server/internal/model/input/adminin/cash.go
+++ b/server/internal/model/input/adminin/cash.go
@@ -23,7 +23,6 @@ type CashViewModel struct {
// CashListInp 获取列表
type CashListInp struct {
form.PageReq
- form.RangeDateReq
form.StatusReq
MemberId int64 `json:"memberId"`
CreatedAt []int64 `json:"created_at"`
diff --git a/server/internal/model/input/adminin/credits_log.go b/server/internal/model/input/adminin/credits_log.go
index 1a87a98..ef13558 100644
--- a/server/internal/model/input/adminin/credits_log.go
+++ b/server/internal/model/input/adminin/credits_log.go
@@ -23,10 +23,10 @@ import (
type CreditsLogSaveBalanceInp struct {
MemberId int64 `json:"memberId" dc:"管理员ID"`
AppId string `json:"appId" dc:"应用id"`
- AddonsName string `json:"addonsName" description:"插件名称"`
+ AddonsName string `json:"addonsName" dc:"插件名称"`
CreditGroup string `json:"creditGroup" dc:"变动的组别"`
Num float64 `json:"num" dc:"变动数据"`
- Ip string `json:"ip" description:"操作人IP"`
+ Ip string `json:"ip" dc:"操作人IP"`
MapId int64 `json:"mapId" dc:"关联ID"`
Remark string `json:"remark" dc:"备注"`
}
@@ -51,7 +51,6 @@ func (in *CreditsLogSaveBalanceInp) Filter(ctx context.Context) (err error) {
if in.Ip == "" {
in.Ip = location.GetClientIp(ghttp.RequestFromCtx(ctx))
}
-
return
}
@@ -62,10 +61,10 @@ type CreditsLogSaveBalanceModel struct {
type CreditsLogSaveIntegralInp struct {
MemberId int64 `json:"memberId" dc:"管理员ID"`
AppId string `json:"appId" dc:"应用id"`
- AddonsName string `json:"addonsName" description:"插件名称"`
+ AddonsName string `json:"addonsName" dc:"插件名称"`
CreditGroup string `json:"creditGroup" dc:"变动的组别"`
Num float64 `json:"num" dc:"变动数据"`
- Ip string `json:"ip" description:"操作人IP"`
+ Ip string `json:"ip" dc:"操作人IP"`
MapId int64 `json:"mapId" dc:"关联ID"`
Remark string `json:"remark" dc:"备注"`
}
@@ -90,7 +89,6 @@ func (in *CreditsLogSaveIntegralInp) Filter(ctx context.Context) (err error) {
if in.Ip == "" {
in.Ip = location.GetClientIp(ghttp.RequestFromCtx(ctx))
}
-
return
}
diff --git a/server/internal/model/input/adminin/dept.go b/server/internal/model/input/adminin/dept.go
index bd71abe..9cb718f 100644
--- a/server/internal/model/input/adminin/dept.go
+++ b/server/internal/model/input/adminin/dept.go
@@ -8,6 +8,7 @@ package adminin
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/os/gtime"
"hotgo/internal/consts"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
@@ -16,7 +17,7 @@ import (
// DeptMaxSortInp 最大排序
type DeptMaxSortInp struct {
- Id int64
+ Id int64 `json:"id" dc:"部门ID"`
}
type DeptMaxSortModel struct {
@@ -77,13 +78,13 @@ type DeptInsertFields struct {
// DeptDeleteInp 删除部门类型
type DeptDeleteInp struct {
- Id interface{}
+ Id interface{} `json:"id" v:"required#部门ID不能为空" dc:"部门ID"`
}
type DeptDeleteModel struct{}
// DeptViewInp 获取信息
type DeptViewInp struct {
- Id int64
+ Id int64 `json:"id" v:"required#部门ID不能为空" dc:"部门ID"`
}
type DeptViewModel struct {
@@ -92,8 +93,14 @@ type DeptViewModel struct {
// DeptListInp 获取列表
type DeptListInp struct {
- Name string
- Code string
+ Name string `json:"name" dc:"部门名称"`
+ Code string `json:"code" dc:"部门编码"`
+ Leader string `json:"leader" dc:"负责人"`
+ CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
+}
+
+func (in *DeptListInp) Filter(ctx context.Context) (err error) {
+ return
}
// DeptTree 树
diff --git a/server/internal/model/input/adminin/member.go b/server/internal/model/input/adminin/member.go
index 61906c3..7533220 100644
--- a/server/internal/model/input/adminin/member.go
+++ b/server/internal/model/input/adminin/member.go
@@ -72,7 +72,7 @@ type MemberUpdateProfileInp struct {
// MemberUpdatePwdInp 修改登录密码
type MemberUpdatePwdInp struct {
- Id int64
+ Id int64 `json:"id" dc:"用户ID"`
OldPassword string `json:"oldPassword" v:"required#原密码不能为空" dc:"原密码"`
NewPassword string `json:"newPassword" v:"required|length:6,16#新密码不能为空#新密码需在6~16之间" dc:"新密码"`
}
@@ -134,7 +134,7 @@ type MemberEditInp struct {
}
type MemberAddInp struct {
- MemberEditInp
+ *MemberEditInp
Salt string `json:"salt" dc:"密码盐"`
Pid int64 `json:"pid" dc:"上级ID"`
Level int `json:"level" dc:"等级"`
@@ -182,7 +182,6 @@ type MemberViewModel struct {
// MemberListInp 获取列表
type MemberListInp struct {
form.PageReq
- form.RangeDateReq
form.StatusReq
RoleId int `json:"roleId" dc:"角色ID"`
DeptId int `json:"deptId" dc:"部门ID"`
@@ -250,13 +249,13 @@ type MemberAddBalanceInp struct {
Id int64 `json:"id" v:"required#用户ID不能为空" dc:"管理员ID"`
OperateMode int64 `json:"operateMode" v:"in:1,2#输入的操作方式是无效的" dc:"操作方式"`
Num float64 `json:"num" dc:"操作数量"`
- AppId string `json:"-"`
- AddonsName string `json:"-"`
- SelfNum float64 `json:"-"`
- SelfCreditGroup string `json:"-"`
- OtherNum float64 `json:"-"`
- OtherCreditGroup string `json:"-"`
- Remark string `json:"-"`
+ AppId string `json:"appId"`
+ AddonsName string `json:"addonsName"`
+ SelfNum float64 `json:"selfNum"`
+ SelfCreditGroup string `json:"selfCreditGroup"`
+ OtherNum float64 `json:"otherNum"`
+ OtherCreditGroup string `json:"otherCreditGroup"`
+ Remark string `json:"remark"`
}
func (in *MemberAddBalanceInp) Filter(ctx context.Context) (err error) {
@@ -293,13 +292,13 @@ type MemberAddIntegralInp struct {
Id int64 `json:"id" v:"required#用户ID不能为空" dc:"管理员ID"`
OperateMode int64 `json:"operateMode" dc:"操作方式"`
Num float64 `json:"num" dc:"操作数量"`
- AppId string `json:"-"`
- AddonsName string `json:"-"`
- SelfNum float64 `json:"-"`
- SelfCreditGroup string `json:"-"`
- OtherNum float64 `json:"-"`
- OtherCreditGroup string `json:"-"`
- Remark string `json:"-"`
+ AppId string `json:"appId"`
+ AddonsName string `json:"addonsName"`
+ SelfNum float64 `json:"selfNum"`
+ SelfCreditGroup string `json:"selfCreditGroup"`
+ OtherNum float64 `json:"otherNum"`
+ OtherCreditGroup string `json:"otherCreditGroup"`
+ Remark string `json:"remark"`
}
func (in *MemberAddIntegralInp) Filter(ctx context.Context) (err error) {
diff --git a/server/internal/model/input/adminin/menu.go b/server/internal/model/input/adminin/menu.go
index 5a08978..d562ba8 100644
--- a/server/internal/model/input/adminin/menu.go
+++ b/server/internal/model/input/adminin/menu.go
@@ -103,16 +103,45 @@ type MenuRouteMeta struct {
}
type MenuRoute struct {
- Name string `json:"name"`
- Path string `json:"path"`
- Redirect string `json:"redirect"`
- Component string `json:"component"`
- Meta MenuRouteMeta `json:"meta"`
- Children []MenuRoute `json:"children,omitempty" dc:"子路由"`
+ Name string `json:"name"`
+ Path string `json:"path"`
+ Redirect string `json:"redirect"`
+ Component string `json:"component"`
+ Meta *MenuRouteMeta `json:"meta"`
+ Children []*MenuRoute `json:"children,omitempty" dc:"子路由"`
}
// MenuRouteSummary 菜单树结构
type MenuRouteSummary struct {
entity.AdminMenu
- Children []MenuRouteSummary
+ Children []*MenuRouteSummary
+}
+
+// DynamicMeta 动态路由元数据
+type DynamicMeta struct {
+ Title string `json:"title" description:"菜单标题"`
+ Icon string `json:"icon" description:"菜单图标"`
+ NoCache bool `json:"noCache" description:"是否缓存"`
+ Remark string `json:"remark" description:"备注"`
+}
+
+// DynamicBase 动态路由
+type DynamicBase struct {
+ Id int64 `json:"id" description:"菜单ID"`
+ Pid int64 `json:"pid" description:"父ID"`
+ Name string `json:"name" description:"菜单名称"`
+ Code string `json:"code" description:"菜单编码"`
+ Path string `json:"path" description:"路由地址"`
+ Hidden bool `json:"hidden" description:"是否隐藏"`
+ Redirect string `json:"redirect" description:"重定向"`
+ Component string `json:"component" description:"组件路径"`
+ AlwaysShow bool `json:"alwaysShow" description:"暂时不知道干啥"`
+ IsFrame string `json:"isFrame" description:"是否为外链(0是 1否)"`
+ Meta *DynamicMeta `json:"meta" description:"配置数据集"`
+}
+
+// DynamicMenu 动态路由菜单
+type DynamicMenu struct {
+ DynamicBase
+ Children []*DynamicBase `json:"children" description:"子菜单"`
}
diff --git a/server/internal/model/input/adminin/notice.go b/server/internal/model/input/adminin/notice.go
index 506d637..5d4b0c6 100644
--- a/server/internal/model/input/adminin/notice.go
+++ b/server/internal/model/input/adminin/notice.go
@@ -3,10 +3,10 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package adminin
import (
+ "context"
"github.com/gogf/gf/v2/os/gtime"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
@@ -47,7 +47,6 @@ type NoticeViewModel struct {
// NoticeListInp 获取列表
type NoticeListInp struct {
form.PageReq
- form.RangeDateReq
form.StatusReq
Title string
Content string
@@ -81,6 +80,13 @@ type PullMessagesInp struct {
Limit int `json:"limit" dc:"拉取最大数量限制"`
}
+func (in *PullMessagesInp) Filter(ctx context.Context) (err error) {
+ if in.Limit == 0 {
+ in.Limit = 100
+ }
+ return
+}
+
type PullMessagesRow struct {
Id int64 `json:"id" dc:"消息ID"`
Type int64 `json:"type" dc:"消息类型"`
diff --git a/server/internal/model/input/adminin/post.go b/server/internal/model/input/adminin/post.go
index 959dd2d..34f2b88 100644
--- a/server/internal/model/input/adminin/post.go
+++ b/server/internal/model/input/adminin/post.go
@@ -3,21 +3,29 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package adminin
import (
+ "context"
+ "github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/os/gtime"
+ "hotgo/internal/consts"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
+ "hotgo/utility/validate"
)
// PostListInp 获取列表
type PostListInp struct {
form.PageReq
- form.RangeDateReq
form.StatusReq
- Name string
- Code string
+ Name string `json:"name" dc:"岗位名称"`
+ Code string `json:"code" dc:"岗位编码"`
+ CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
+}
+
+func (in *PostListInp) Filter(ctx context.Context) (err error) {
+ return
}
type PostListModel struct {
@@ -26,56 +34,69 @@ type PostListModel struct {
// PostViewInp 获取信息
type PostViewInp struct {
- Id string
+ Id string `json:"id" v:"required#岗位ID不能为空" description:"岗位ID"`
}
type PostViewModel struct {
entity.AdminPost
}
-// PostCodeUniqueInp 编码是否唯一
-type PostCodeUniqueInp struct {
- Code string
- Id int64
-}
-
-type PostCodeUniqueModel struct {
- IsUnique bool
-}
-
-// PostNameUniqueInp 名称是否唯一
-type PostNameUniqueInp struct {
- Name string
- Id int64
-}
-
-type PostNameUniqueModel struct {
- IsUnique bool
-}
-
// PostMaxSortInp 最大排序
type PostMaxSortInp struct {
- Id int64
+ Id int64 `json:"id" description:"岗位ID"`
}
type PostMaxSortModel struct {
- Sort int
+ Sort int `json:"sort" description:"排序"`
}
// PostEditInp 修改/新增字典数据
type PostEditInp struct {
entity.AdminPost
}
+
+func (in *PostEditInp) Filter(ctx context.Context) (err error) {
+ if in.Name == "" {
+ err = gerror.New("名称不能为空")
+ return
+ }
+ if in.Code == "" {
+ err = gerror.New("编码不能为空")
+ return
+ }
+ return
+}
+
type PostEditModel struct{}
// PostDeleteInp 删除字典类型
type PostDeleteInp struct {
- Id interface{}
+ Id interface{} `json:"id" v:"required#岗位ID不能为空" description:"岗位ID"`
}
+
type PostDeleteModel struct{}
// PostStatusInp 更新状态
type PostStatusInp struct {
entity.AdminPost
}
+
+func (in *PostStatusInp) Filter(ctx context.Context) (err error) {
+ if in.Id <= 0 {
+ err = gerror.New("ID不能为空")
+ return
+ }
+
+ if in.Status <= 0 {
+ err = gerror.New("状态不能为空")
+ return
+ }
+
+ if !validate.InSlice(consts.StatusSlice, in.Status) {
+ err = gerror.New("状态不正确")
+ return
+ }
+ return
+}
+
type PostStatusModel struct{}
diff --git a/server/internal/model/input/adminin/role.go b/server/internal/model/input/adminin/role.go
index eb9ff81..0cd324a 100644
--- a/server/internal/model/input/adminin/role.go
+++ b/server/internal/model/input/adminin/role.go
@@ -115,7 +115,7 @@ type RoleListModel struct {
// RoleMemberListInp 查询列表
type RoleMemberListInp struct {
form.PageReq
- form.RangeDateReq
+
form.StatusReq
Role int `json:"role" dc:"角色ID"`
DeptId int `json:"deptId" dc:"部门ID"`
diff --git a/server/internal/model/input/form/base.go b/server/internal/model/input/form/base.go
index df6b642..05ff217 100644
--- a/server/internal/model/input/form/base.go
+++ b/server/internal/model/input/form/base.go
@@ -5,60 +5,11 @@
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package form
-import (
- "context"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/util/gconv"
-)
-
-var (
- page int
- pageSize int
-)
-
-// DefaultPageSize 列表分页默认加载页码
-func DefaultPageSize(ctx context.Context) int {
- if pageSize > 0 {
- return pageSize
- }
- pageSize = g.Cfg().MustGet(ctx, "hotgo.admin.defaultPageSize", 10).Int()
- if pageSize <= 0 {
- pageSize = 10
- }
- return pageSize
-}
-
-// DefaultPage 列表分页默认加载数量
-func DefaultPage(ctx context.Context) int {
- if page > 0 {
- return page
- }
- page = g.Cfg().MustGet(ctx, "hotgo.admin.defaultPage", 1).Int()
- if page <= 0 {
- page = 1
- }
- return page
-}
-
-// PageReq 分页
-type PageReq struct {
- Page int `json:"page" example:"10" d:"1" v:"min:1#页码最小值不能低于1" dc:"当前页码"`
- PerPage int `json:"pageSize" example:"1" d:"10" v:"min:1|max:200#每页数量最小值不能低于1|最大值不能大于200" dc:"每页数量"`
-}
-type PageRes struct {
- PageReq
- PageCount int `json:"pageCount" example:"0" dc:"全部数据量"`
-}
-
-// RangeDateReq 时间范围查询
-type RangeDateReq struct {
- StartTime string `json:"start_time" v:"date#开始日期格式不正确" dc:"开始日期"`
- EndTime string `json:"end_time" v:"date#结束日期格式不正确" dc:"结束日期"`
-}
+import "hotgo/internal/consts"
// StatusReq 通用状态查询
type StatusReq struct {
- Status int `json:"status" v:"in:-1,0,1,2,3#输入的状态是无效的" dc:"状态"`
+ Status int `json:"status" v:"in:-1,0,1,2,3#输入的状态是无效的" dc:"状态"`
}
// SwitchReq 更新开关状态
@@ -67,62 +18,13 @@ type SwitchReq struct {
Value int `json:"value" v:"in:1,2#输入的开关值是无效的" dc:"更新值"`
}
-// CalPage 解析分页
-func CalPage(ctx context.Context, page, perPage int) (newPage, newPerPage int, offset int) {
- if page <= 0 {
- newPage = DefaultPage(ctx)
- } else {
- newPage = page
- }
- if perPage <= 0 {
- newPerPage = DefaultPageSize(ctx)
- } else {
- newPerPage = perPage
- }
-
- offset = (newPage - 1) * newPerPage
- return
-}
-
-func CalPageCount(totalCount int, perPage int) int {
- return (totalCount + perPage - 1) / perPage
-}
-
-// Selects 选项
-type Selects []*Select
-
-type Select struct {
- Value interface{} `json:"value"`
- Label string `json:"label"`
- Name string `json:"name"`
-}
-
-func (p Selects) Len() int {
- return len(p)
-}
-
-func (p Selects) Swap(i, j int) {
- p[i], p[j] = p[j], p[i]
-}
-
-func (p Selects) Less(i, j int) bool {
- return gconv.Int64(p[j].Value) > gconv.Int64(p[i].Value)
-}
-
-type SelectInt64s []*SelectInt64
-type SelectInt64 struct {
- Value int64 `json:"value"`
- Label string `json:"label"`
- Name string `json:"name"`
-}
-
-// DefaultMaxSort 默认最大排序
-func DefaultMaxSort(ctx context.Context, baseSort int) int {
- return baseSort + g.Cfg().MustGet(ctx, "hotgo.admin.maxSortIncrement", 10).Int()
-}
-
// AvatarGroup 头像组
type AvatarGroup struct {
Name string `json:"name" dc:"姓名"`
Src string `json:"src" dc:"头像地址"`
}
+
+// DefaultMaxSort 默认最大排序
+func DefaultMaxSort(baseSort int) int {
+ return baseSort + consts.MaxSortIncr
+}
diff --git a/server/internal/model/input/form/page.go b/server/internal/model/input/form/page.go
new file mode 100644
index 0000000..a5ed967
--- /dev/null
+++ b/server/internal/model/input/form/page.go
@@ -0,0 +1,60 @@
+package form
+
+import (
+ "hotgo/internal/consts"
+)
+
+type ReqPageFunc interface {
+ GetPage() int
+ GetPerPage() int
+}
+
+// PageReq 分页请求
+type PageReq struct {
+ Page int `json:"page" example:"10" d:"1" v:"min:1#页码最小值不能低于1" dc:"当前页码"`
+ PerPage int `json:"pageSize" example:"1" d:"10" v:"min:1|max:200#每页数量最小值不能低于1|最大值不能大于200" dc:"每页数量"`
+}
+
+// GetPage 获取当前页码
+func (req *PageReq) GetPage() int {
+ return req.Page
+}
+
+// GetPerPage 获取每页数量
+func (req *PageReq) GetPerPage() int {
+ return req.PerPage
+}
+
+// PageRes 分页响应
+type PageRes struct {
+ PageReq
+ PageCount int `json:"pageCount" example:"0" dc:"全部数据量"`
+}
+
+// Pack 打包分页数据
+func (res *PageRes) Pack(req ReqPageFunc, totalCount int) {
+ res.PageCount = CalPageCount(totalCount, req.GetPerPage())
+ res.Page = req.GetPage()
+ res.PerPage = req.GetPerPage()
+}
+
+func CalPageCount(totalCount int, perPage int) int {
+ return (totalCount + perPage - 1) / perPage
+}
+
+// CalPage 计算分页偏移量
+func CalPage(page, perPage int) (newPage, newPerPage int, offset int) {
+ if page <= 0 {
+ newPage = consts.DefaultPage
+ } else {
+ newPage = page
+ }
+ if perPage <= 0 {
+ newPerPage = consts.DefaultPageSize
+ } else {
+ newPerPage = perPage
+ }
+
+ offset = (newPage - 1) * newPerPage
+ return
+}
diff --git a/server/internal/model/input/form/select.go b/server/internal/model/input/form/select.go
new file mode 100644
index 0000000..0a07d3a
--- /dev/null
+++ b/server/internal/model/input/form/select.go
@@ -0,0 +1,25 @@
+package form
+
+import "github.com/gogf/gf/v2/util/gconv"
+
+// Selects 选项
+type Selects []*Select
+
+type Select struct {
+ Value interface{} `json:"value"`
+ Label string `json:"label"`
+ Name string `json:"name"`
+ Disabled bool `json:"disabled"`
+}
+
+func (p Selects) Len() int {
+ return len(p)
+}
+
+func (p Selects) Swap(i, j int) {
+ p[i], p[j] = p[j], p[i]
+}
+
+func (p Selects) Less(i, j int) bool {
+ return gconv.Int64(p[j].Value) > gconv.Int64(p[i].Value)
+}
diff --git a/server/internal/model/input/msgin/auth.go b/server/internal/model/input/msgin/auth.go
deleted file mode 100644
index f2d04dc..0000000
--- a/server/internal/model/input/msgin/auth.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package msgin
-
-import "github.com/gogf/gf/v2/os/gtime"
-
-// AuthSummary 授权摘要
-type AuthSummary struct {
- RpcMsg
-}
-
-// ResponseAuthSummary 响应授权摘要
-type ResponseAuthSummary struct {
- Response
- Data *AuthSummaryData `json:"data,omitempty" description:"数据集"`
-}
-
-type AuthSummaryData struct {
- EndAt *gtime.Time `json:"end_at" description:"授权过期时间"`
- Online int `json:"online" description:"在线人数"`
-}
diff --git a/server/internal/model/input/msgin/common.go b/server/internal/model/input/msgin/common.go
deleted file mode 100644
index 03b8c3f..0000000
--- a/server/internal/model/input/msgin/common.go
+++ /dev/null
@@ -1,102 +0,0 @@
-package msgin
-
-import (
- "fmt"
- "github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/os/gtime"
- "hotgo/internal/consts"
- "hotgo/utility/encrypt"
-)
-
-type RpcMsg struct {
- AppId string `json:"appID" v:"0" example:"10001" description:"应用ID"`
- TraceID string `json:"traceID" v:"0" example:"d0bb93048bc5c9164cdee845dcb7f820" description:"链路ID"`
- Timestamp int64 `json:"timestamp" example:"1640966400" description:"服务器时间戳"`
- Sign string `json:"sign" example:"d0bb93048bc5c9164cdee845dcb7f820" description:"签名"`
-}
-
-func (i *RpcMsg) SetSign(appId, secretKey string) *RpcMsg {
- i.AppId = appId
- i.Timestamp = gtime.Timestamp()
- i.Sign = i.GetSign(secretKey)
- return i
-}
-
-func (i *RpcMsg) GetSign(secretKey string) string {
- return encrypt.Md5ToString(fmt.Sprintf("%v%v%v%v", i.AppId, i.TraceID, i.Timestamp, secretKey))
-}
-
-func (i *RpcMsg) GetTraceID() string {
- return i.TraceID
-}
-
-func (i *RpcMsg) SetTraceID(traceID string) {
- i.TraceID = traceID
-}
-
-type Response struct {
- RpcMsg
- Code int `json:"code" example:"2000" description:"状态码"`
- Message string `json:"message,omitempty" example:"操作成功" description:"提示消息"`
-}
-
-// PkgResponse 打包响应消息
-func (m *Response) PkgResponse() {
- m.SetCode()
- // ...
-}
-
-// SetCode 设置状态码
-func (m *Response) SetCode(code ...int) {
- if len(code) > 0 {
- m.Code = code[0]
- return
- }
-
- // 默认值,转为成功的状态码
- if m.Code == 0 {
- m.Code = consts.TCPMsgCodeSuccess
- }
-}
-
-// GetError 获取响应中的错误
-func (m *Response) GetError() (err error) {
- if m.Code != consts.TCPMsgCodeSuccess {
- if m.Message == "" {
- m.Message = "操作失败"
- }
- err = gerror.New(m.Message)
- }
- return
-}
-
-// ServerHeartbeat 心跳
-type ServerHeartbeat struct {
-}
-
-// ResponseServerHeartbeat 响应心跳
-type ResponseServerHeartbeat struct {
- Response
-}
-
-// ServerLogin 服务登录
-type ServerLogin struct {
- RpcMsg
- Group string `json:"group" description:"分组"`
- Name string `json:"name" description:"名称"`
-}
-
-// ResponseServerLogin 响应服务登录
-type ResponseServerLogin struct {
- Response
-}
-
-// ServerOffline 服务离线
-type ServerOffline struct {
- RpcMsg
-}
-
-// ResponseServerOffline 响应服务离线
-type ResponseServerOffline struct {
- Response
-}
diff --git a/server/internal/model/input/msgin/cron.go b/server/internal/model/input/msgin/cron.go
deleted file mode 100644
index 486dccd..0000000
--- a/server/internal/model/input/msgin/cron.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package msgin
-
-import (
- "hotgo/internal/model/input/sysin"
-)
-
-// CronDelete 删除任务
-type CronDelete struct {
- RpcMsg
- sysin.CronDeleteInp
-}
-
-type ResponseCronDelete struct {
- Response
- sysin.CronDeleteModel
-}
-
-// CronEdit 编辑任务
-type CronEdit struct {
- RpcMsg
- sysin.CronEditInp
-}
-
-type ResponseCronEdit struct {
- Response
- sysin.CronEditModel
-}
-
-// CronStatus 修改任务状态
-type CronStatus struct {
- RpcMsg
- sysin.CronStatusInp
-}
-
-type ResponseCronStatus struct {
- Response
- sysin.CronStatusModel
-}
-
-// CronOnlineExec 在线执行
-type CronOnlineExec struct {
- RpcMsg
- sysin.OnlineExecInp
-}
-
-type ResponseCronOnlineExec struct {
- Response
- sysin.OnlineExecModel
-}
diff --git a/server/internal/model/input/servmsgin/auth.go b/server/internal/model/input/servmsgin/auth.go
new file mode 100644
index 0000000..05295cc
--- /dev/null
+++ b/server/internal/model/input/servmsgin/auth.go
@@ -0,0 +1,11 @@
+package servmsgin
+
+import "github.com/gogf/gf/v2/os/gtime"
+
+// AuthSummaryModel 授权信息
+type AuthSummaryModel struct {
+ EndAt *gtime.Time `json:"end_at" description:"授权过期时间"`
+ Online int `json:"online" description:"在线人数"`
+ // 请填充你的授权数据
+ // ...
+}
diff --git a/server/internal/model/input/servmsgin/example.go b/server/internal/model/input/servmsgin/example.go
new file mode 100644
index 0000000..e064025
--- /dev/null
+++ b/server/internal/model/input/servmsgin/example.go
@@ -0,0 +1,9 @@
+package servmsgin
+
+import "github.com/gogf/gf/v2/os/gtime"
+
+// ExampleHelloModel 授权信息
+type ExampleHelloModel struct {
+ Desc string `json:"desc" description:"描述信息"`
+ Timestamp *gtime.Time `json:"timestamp" description:"服务器时间"`
+}
diff --git a/server/internal/model/input/sysin/addons.go b/server/internal/model/input/sysin/addons.go
index f59e00d..05a0556 100644
--- a/server/internal/model/input/sysin/addons.go
+++ b/server/internal/model/input/sysin/addons.go
@@ -16,25 +16,26 @@ import (
// AddonsListInp 获取列表
type AddonsListInp struct {
form.PageReq
- Name string `json:"name"`
- Group int `json:"group"`
- Status int `json:"status"`
+ Name string `json:"name" dc:"插件名称"`
+ Group int `json:"group" dc:"分组"`
+ Status int `json:"status" dc:"安装状态"`
}
type AddonsListModel struct {
addons.Skeleton
- GroupName string `json:"groupName" dc:"分组名称"`
- InstallVersion string `json:"installVersion" dc:"安装版本"`
- InstallStatus int `json:"installStatus" dc:"安装状态"`
- CanSave bool `json:"canSave" dc:"是否可以更新"`
+ GroupName string `json:"groupName" dc:"分组名称"`
+ InstallVersion string `json:"installVersion" dc:"安装版本"`
+ InstallStatus int `json:"installStatus" dc:"安装状态"`
+ CanSave bool `json:"canSave" dc:"是否可以更新"`
}
// AddonsSelectsInp 选项
type AddonsSelectsInp struct {
}
+
type AddonsSelectsModel struct {
GroupType form.Selects `json:"groupType" dc:"分组类型"`
- Status form.Selects `json:"status" dc:"安装状态"`
+ Status form.Selects `json:"status" dc:"安装状态"`
}
// AddonsBuildInp 提交生成
@@ -52,7 +53,6 @@ func (in *AddonsBuildInp) Filter(ctx context.Context) (err error) {
err = gerror.New("插件名称格式不正确,字母开头,只能包含字母、数字和下划线,长度在2~24之间")
return
}
-
return
}
diff --git a/server/internal/model/input/sysin/attachment.go b/server/internal/model/input/sysin/attachment.go
index 11577f9..88e3c6c 100644
--- a/server/internal/model/input/sysin/attachment.go
+++ b/server/internal/model/input/sysin/attachment.go
@@ -6,35 +6,74 @@
package sysin
import (
+ "context"
+ "github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/os/gtime"
+ "hotgo/internal/library/storager"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
+ "hotgo/utility/validate"
)
// AttachmentDeleteInp 删除附件
type AttachmentDeleteInp struct {
- Id interface{}
+ Id interface{} `json:"id" v:"required#附件ID不能为空" dc:"附件ID"`
}
+
type AttachmentDeleteModel struct{}
// AttachmentViewInp 获取附件信息
type AttachmentViewInp struct {
- Id int64
+ Id int64 `json:"id" v:"required#附件ID不能为空" dc:"附件ID"`
}
type AttachmentViewModel struct {
entity.SysAttachment
}
+// AttachmentClearKindInp 清空上传类型
+type AttachmentClearKindInp struct {
+ Kind string `json:"kind" v:"required#上传类型不能为空" dc:"上传类型"`
+}
+
+func (in *AttachmentClearKindInp) Filter(ctx context.Context) (err error) {
+ if !validate.InSlice(storager.KindSlice, in.Kind) {
+ err = gerror.New("上传类型是无效的")
+ return
+ }
+ return
+}
+
// AttachmentListInp 获取附件列表
type AttachmentListInp struct {
form.PageReq
- form.RangeDateReq
form.StatusReq
- MemberId int64
- Drive string
+ MemberId int64 `json:"member_id" dc:"用户ID"`
+ Name string `json:"name" dc:"文件名称"`
+ Drive string `json:"drive" dc:"驱动"`
+ Kind string `json:"kind" dc:"上传类型"`
+ UpdatedAt []*gtime.Time `json:"updatedAt" dc:"更新时间"`
}
type AttachmentListModel struct {
entity.SysAttachment
- SizeFormat string `json:"sizeFormat" description:"长度"`
+ SizeFormat string `json:"sizeFormat" dc:"大小"`
+}
+
+// AttachmentChooserListInp 获取附件列表
+type AttachmentChooserListInp struct {
+ form.PageReq
+ Drive string `json:"drive" dc:"驱动"`
+ Kind string `json:"kind" dc:"上传类型"`
+ UpdatedAt []int64 `json:"updatedAt" dc:"更新时间"`
+}
+
+type AttachmentChooserListModel struct {
+ entity.SysAttachment
+ SizeFormat string `json:"sizeFormat" dc:"大小"`
+}
+
+// AttachmentClearInp 清空分类
+type AttachmentClearInp struct {
+ Kind string `json:"kind" dc:"上传类型"`
}
diff --git a/server/internal/model/input/sysin/blacklist.go b/server/internal/model/input/sysin/blacklist.go
index 22127f9..73fd4de 100644
--- a/server/internal/model/input/sysin/blacklist.go
+++ b/server/internal/model/input/sysin/blacklist.go
@@ -3,38 +3,34 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sysin
import (
+ "context"
+ "github.com/gogf/gf/v2/errors/gerror"
+ "hotgo/internal/consts"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
+ "hotgo/utility/validate"
)
-// BlacklistMaxSortInp 最大排序
-type BlacklistMaxSortInp struct {
- Id int64
-}
-
-type BlacklistMaxSortModel struct {
- Sort int
-}
-
-// BlacklistEditInp 修改/新增字典数据
+// BlacklistEditInp 修改/新增黑名单数据
type BlacklistEditInp struct {
entity.SysBlacklist
}
+
type BlacklistEditModel struct{}
-// BlacklistDeleteInp 删除字典类型
+// BlacklistDeleteInp 删除黑名单类型
type BlacklistDeleteInp struct {
- Id interface{}
+ Id interface{} `json:"id" v:"required#黑名单ID不能为空" dc:"黑名单ID"`
}
+
type BlacklistDeleteModel struct{}
// BlacklistViewInp 获取信息
type BlacklistViewInp struct {
- Id int64
+ Id int64 `json:"id" v:"required#黑名单ID不能为空" dc:"黑名单ID"`
}
type BlacklistViewModel struct {
@@ -44,9 +40,15 @@ type BlacklistViewModel struct {
// BlacklistListInp 获取列表
type BlacklistListInp struct {
form.PageReq
- form.RangeDateReq
+
form.StatusReq
- Ip string
+ Ip string `json:"ip" dc:"IP"`
+ Remark string `json:"remark" dc:"备注"`
+ CreatedAt []int64 `json:"createdAt" dc:"创建时间"`
+}
+
+func (in *BlacklistListInp) Filter(ctx context.Context) (err error) {
+ return
}
type BlacklistListModel struct {
@@ -57,4 +59,23 @@ type BlacklistListModel struct {
type BlacklistStatusInp struct {
entity.SysBlacklist
}
+
+func (in *BlacklistStatusInp) Filter(ctx context.Context) (err error) {
+ if in.Id <= 0 {
+ err = gerror.New("ID不能为空")
+ return
+ }
+
+ if in.Status <= 0 {
+ err = gerror.New("状态不能为空")
+ return
+ }
+
+ if !validate.InSlice(consts.StatusSlice, in.Status) {
+ err = gerror.New("状态不正确")
+ return
+ }
+ return
+}
+
type BlacklistStatusModel struct{}
diff --git a/server/internal/model/input/sysin/config.go b/server/internal/model/input/sysin/config.go
index 8e36ecf..d659641 100644
--- a/server/internal/model/input/sysin/config.go
+++ b/server/internal/model/input/sysin/config.go
@@ -3,20 +3,12 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sysin
import (
"github.com/gogf/gf/v2/frame/g"
- "hotgo/internal/model/entity"
- "hotgo/internal/model/input/form"
)
-type GetConfigItem struct {
- Key string `json:"key"`
- Value string `json:"value"`
-}
-
// UpdateConfigInp 更新指定分组的配置
type UpdateConfigInp struct {
Group string `json:"group"`
@@ -27,75 +19,7 @@ type UpdateConfigInp struct {
type GetConfigInp struct {
Group string `json:"group"`
}
+
type GetConfigModel struct {
List g.Map `json:"list"`
}
-
-// ConfigGetValueInp 获取指定配置键的值
-type ConfigGetValueInp struct {
- Key string
-}
-type ConfigGetValueModel struct {
- Value string
-}
-
-// ConfigNameUniqueInp 名称是否唯一
-type ConfigNameUniqueInp struct {
- Name string
- Id int64
-}
-
-type ConfigNameUniqueModel struct {
- IsUnique bool
-}
-
-// ConfigMaxSortInp 最大排序
-type ConfigMaxSortInp struct {
- Id int64
-}
-
-type ConfigMaxSortModel struct {
- Sort int
-}
-
-// ConfigEditInp 修改/新增字典数据
-type ConfigEditInp struct {
- entity.SysConfig
-}
-type ConfigEditModel struct{}
-
-// ConfigDeleteInp 删除字典类型
-type ConfigDeleteInp struct {
- Id interface{}
-}
-type ConfigDeleteModel struct{}
-
-// ConfigViewInp 获取信息
-type ConfigViewInp struct {
- Id string
-}
-
-type ConfigViewModel struct {
- entity.SysConfig
-}
-
-// ConfigListInp 获取列表
-type ConfigListInp struct {
- form.PageReq
- form.RangeDateReq
- form.StatusReq
- Name string
- Code string
- DeptId int
- Mobile int
- Username string
- Realname string
- StartTime string
- EndTime string
-}
-
-type ConfigListModel struct {
- entity.SysConfig
- DeptName string `json:"deptName"`
- RoleName string `json:"roleName"`
-}
diff --git a/server/internal/model/input/sysin/cron.go b/server/internal/model/input/sysin/cron.go
index 4bf6f4d..91f21bb 100644
--- a/server/internal/model/input/sysin/cron.go
+++ b/server/internal/model/input/sysin/cron.go
@@ -43,7 +43,7 @@ type CronViewModel struct {
// CronListInp 获取列表
type CronListInp struct {
form.PageReq
- form.RangeDateReq
+
form.StatusReq
Name string
}
diff --git a/server/internal/model/input/sysin/cron_group.go b/server/internal/model/input/sysin/cron_group.go
index a94fbc9..3eedb3e 100644
--- a/server/internal/model/input/sysin/cron_group.go
+++ b/server/internal/model/input/sysin/cron_group.go
@@ -38,7 +38,6 @@ func (in *CronGroupEditInp) Filter(ctx context.Context) (err error) {
err = gerror.New("上级分组不能是自己")
return
}
-
return
}
@@ -83,7 +82,7 @@ type CronGroupViewModel struct {
// CronGroupListInp 获取列表
type CronGroupListInp struct {
form.PageReq
- form.RangeDateReq
+
form.StatusReq
Name string
}
@@ -112,7 +111,6 @@ func (in *CronGroupStatusInp) Filter(ctx context.Context) (err error) {
err = gerror.New("状态不正确")
return
}
-
return
}
diff --git a/server/internal/model/input/sysin/curd_demo.go b/server/internal/model/input/sysin/curd_demo.go
index f203dfb..3810004 100644
--- a/server/internal/model/input/sysin/curd_demo.go
+++ b/server/internal/model/input/sysin/curd_demo.go
@@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-// @AutoGenerate Version 2.7.3
+// @AutoGenerate Version 2.7.6
package sysin
import (
diff --git a/server/internal/model/input/sysin/dict_data.go b/server/internal/model/input/sysin/dict_data.go
index 5dac434..3dfa179 100644
--- a/server/internal/model/input/sysin/dict_data.go
+++ b/server/internal/model/input/sysin/dict_data.go
@@ -15,7 +15,7 @@ import (
// DictDataEditInp 修改/新增字典数据
type DictDataEditInp struct {
entity.SysDictData
- TypeID int64
+ TypeID int64 `json:"typeID" dc:"字典类型ID"`
}
func (in *DictDataEditInp) Filter(ctx context.Context) (err error) {
@@ -28,7 +28,6 @@ func (in *DictDataEditInp) Filter(ctx context.Context) (err error) {
err = gerror.New("字典类型不能为空")
return
}
-
return
}
@@ -63,18 +62,19 @@ type DictDataInsertFields struct {
// DictDataDeleteInp 删除字典数据
type DictDataDeleteInp struct {
- Id interface{}
+ Id interface{} `json:"id" v:"required#字典数据ID不能为空" dc:"字典数据ID"`
}
+
type DictDataDeleteModel struct{}
// DictDataListInp 获取列表
type DictDataListInp struct {
form.PageReq
- form.RangeDateReq
+
form.StatusReq
- TypeID int64
- Type string
- Label string
+ TypeID int64 `json:"typeId" v:"required#字典类型ID不能为空" dc:"字典类型ID"`
+ Type string `json:"type"`
+ Label string `json:"label"`
}
type DictDataListModel struct {
@@ -85,7 +85,7 @@ type DictDataListModel struct {
// DataSelectInp 获取指定字典选项
type DataSelectInp struct {
- Type string
+ Type string `in:"path" v:"required#字典类型不能为空" dc:"字典类型"`
}
type DataSelectModel []*SelectData
diff --git a/server/internal/model/input/sysin/dict_type.go b/server/internal/model/input/sysin/dict_type.go
index 57780ae..4e54da5 100644
--- a/server/internal/model/input/sysin/dict_type.go
+++ b/server/internal/model/input/sysin/dict_type.go
@@ -27,7 +27,6 @@ func (in *DictTypeEditInp) Filter(ctx context.Context) (err error) {
err = gerror.New("上级字典不能是自己")
return
}
-
return
}
@@ -56,8 +55,9 @@ type DictTypeInsertFields struct {
// DictTypeDeleteInp 删除字典类型
type DictTypeDeleteInp struct {
- Id interface{}
+ Id interface{} `json:"id" v:"required#字典类型ID不能为空" dc:"字典类型ID"`
}
+
type DictTypeDeleteModel struct{}
// DictTreeSelectInp 获取类型关系树选项
diff --git a/server/internal/model/input/sysin/ems_log.go b/server/internal/model/input/sysin/ems_log.go
index 5cc95b9..83bd017 100644
--- a/server/internal/model/input/sysin/ems_log.go
+++ b/server/internal/model/input/sysin/ems_log.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sysin
import (
@@ -16,12 +15,14 @@ import (
type EmsLogEditInp struct {
entity.SysEmsLog
}
+
type EmsLogEditModel struct{}
// EmsLogDeleteInp 删除
type EmsLogDeleteInp struct {
Id interface{} `json:"id" v:"required#邮件记录ID不能为空" dc:"邮件记录ID"`
}
+
type EmsLogDeleteModel struct{}
// EmsLogViewInp 获取信息
@@ -36,7 +37,7 @@ type EmsLogViewModel struct {
// EmsLogListInp 获取列表
type EmsLogListInp struct {
form.PageReq
- form.RangeDateReq
+
form.StatusReq
Title string `json:"title"`
Content string `json:"content"`
@@ -50,6 +51,7 @@ type EmsLogListModel struct {
type EmsLogStatusInp struct {
entity.SysSmsLog
}
+
type EmsLogStatusModel struct{}
// SendEmsInp 发送邮件
diff --git a/server/internal/model/input/sysin/gen_codes.go b/server/internal/model/input/sysin/gen_codes.go
index 297f512..4b79187 100644
--- a/server/internal/model/input/sysin/gen_codes.go
+++ b/server/internal/model/input/sysin/gen_codes.go
@@ -18,11 +18,11 @@ import (
// GenCodesMaxSortInp 最大排序
type GenCodesMaxSortInp struct {
- Id int64
+ Id int64 `json:"id" dc:"生成代码ID"`
}
type GenCodesMaxSortModel struct {
- Sort int
+ Sort int `json:"sort" dc:"排序"`
}
// GenCodesEditInp 修改/新增数据
@@ -40,13 +40,14 @@ type GenCodesEditModel struct {
// GenCodesDeleteInp 删除
type GenCodesDeleteInp struct {
- Id interface{}
+ Id interface{} `json:"id" v:"required#生成代码ID不能为空" dc:"生成代码ID"`
}
+
type GenCodesDeleteModel struct{}
// GenCodesViewInp 获取信息
type GenCodesViewInp struct {
- Id int64
+ Id int64 `json:"id" v:"required#生成代码ID不能为空" dc:"生成代码ID"`
}
type GenCodesViewModel struct {
@@ -57,8 +58,8 @@ type GenCodesViewModel struct {
type GenCodesListInp struct {
form.PageReq
form.StatusReq
- GenType int `json:"genType"`
- VarName string `json:"varName"`
+ GenType int `json:"genType" dc:"生成类型"`
+ VarName string `json:"varName" dc:"实体"`
}
type GenCodesListModel struct {
@@ -76,6 +77,7 @@ type GenCodesStatusModel struct{}
// GenCodesSelectsInp 选项
type GenCodesSelectsInp struct {
}
+
type GenCodesSelectsModel struct {
GenType GenTypeSelects `json:"genType" dc:"生成类型"`
Db form.Selects `json:"db" dc:"数据库选项"`
@@ -100,6 +102,7 @@ type GenTypeSelect struct {
}
type GenTemplateSelects []*GenTemplateSelect
+
type GenTemplateSelect struct {
Value interface{} `json:"value"`
Label string `json:"label"`
@@ -110,9 +113,11 @@ type GenTemplateSelect struct {
func (p GenTemplateSelects) Len() int {
return len(p)
}
+
func (p GenTemplateSelects) Swap(i, j int) {
p[i], p[j] = p[j], p[i]
}
+
func (p GenTemplateSelects) Less(i, j int) bool {
return gconv.Int64(p[j].Value) > gconv.Int64(p[i].Value)
}
@@ -120,9 +125,11 @@ func (p GenTemplateSelects) Less(i, j int) bool {
func (p GenTypeSelects) Len() int {
return len(p)
}
+
func (p GenTypeSelects) Swap(i, j int) {
p[i], p[j] = p[j], p[i]
}
+
func (p GenTypeSelects) Less(i, j int) bool {
return gconv.Int64(p[j].Value) > gconv.Int64(p[i].Value)
}
@@ -131,6 +138,7 @@ func (p GenTypeSelects) Less(i, j int) bool {
type GenCodesTableSelectInp struct {
Name string `json:"name" dc:"数据库配置名称"`
}
+
type GenCodesTableSelectModel struct {
Value string `json:"value"`
Label string `json:"label"`
@@ -146,6 +154,7 @@ type GenCodesColumnSelectInp struct {
Name string `json:"name" dc:"数据库配置名称"`
Table string `json:"table" dc:"表名称"`
}
+
type GenCodesColumnSelectModel struct {
Value string `json:"value"`
Label string `json:"label"`
@@ -159,6 +168,7 @@ type GenCodesColumnListInp struct {
IsLink int64 `json:"isLink" dc:"是否是关联表"`
Alias string `json:"alias" dc:"关联表别名"`
}
+
type GenCodesColumnListModel struct {
model.GenCodesColumn
}
diff --git a/server/internal/model/input/sysin/log.go b/server/internal/model/input/sysin/log.go
index b8320a9..35dc6b0 100644
--- a/server/internal/model/input/sysin/log.go
+++ b/server/internal/model/input/sysin/log.go
@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package sysin
import (
@@ -14,18 +13,15 @@ import (
// LogListInp 获取菜单列表
type LogListInp struct {
form.PageReq
- form.RangeDateReq
form.StatusReq
- Module string
- MemberId int
- TakeUpTime int
- Method string
- Url string
- Ip string
- ErrorCode string
- StartTime string
- EndTime string
- CreatedAt []int64
+ Module string `json:"module" dc:"应用端口"`
+ MemberId int `json:"member_id" dc:"用户ID"`
+ TakeUpTime int `json:"take_up_time" dc:"请求耗时"`
+ Method string `json:"method" dc:"请求方式"`
+ Url string `json:"url" dc:"请求路径"`
+ Ip string `json:"ip" dc:"访问IP"`
+ ErrorCode string `json:"error_code" dc:"状态码"`
+ CreatedAt []int64 `json:"created_at" dc:"创建时间"`
}
type LogListModel struct {
@@ -36,7 +32,7 @@ type LogListModel struct {
// LogViewInp 获取信息
type LogViewInp struct {
- Id string
+ Id string `json:"id" v:"required#日志ID不能为空" description:"日志ID"`
}
type LogViewModel struct {
@@ -46,6 +42,7 @@ type LogViewModel struct {
// LogDeleteInp 删除
type LogDeleteInp struct {
- Id interface{}
+ Id interface{} `json:"id" v:"required#日志ID不能为空" description:"日志ID"`
}
+
type LogDeleteModel struct{}
diff --git a/server/internal/model/input/sysin/provinces.go b/server/internal/model/input/sysin/provinces.go
index 5ccb259..f6ded8c 100644
--- a/server/internal/model/input/sysin/provinces.go
+++ b/server/internal/model/input/sysin/provinces.go
@@ -74,6 +74,7 @@ type ProvincesInsertFields struct {
type ProvincesDeleteInp struct {
Id interface{} `json:"id" v:"required#省市区ID不能为空" dc:"省市区ID"`
}
+
type ProvincesDeleteModel struct{}
// ProvincesViewInp 获取信息
@@ -82,16 +83,16 @@ type ProvincesViewInp struct {
}
type ProvincesViewModel struct {
- entity.SysProvinces
+ Id int64 `json:"id" v:"required#省市区ID不能为空" dc:"省市区ID"`
}
// ProvincesListInp 获取列表
type ProvincesListInp struct {
form.PageReq
- form.RangeDateReq
+
form.StatusReq
- Title string
- Content string
+ Title string `json:"title"`
+ Content string `json:"content"`
}
type ProvincesListModel struct {
diff --git a/server/internal/model/input/sysin/serve_license.go b/server/internal/model/input/sysin/serve_license.go
new file mode 100644
index 0000000..bba177a
--- /dev/null
+++ b/server/internal/model/input/sysin/serve_license.go
@@ -0,0 +1,190 @@
+// Package sysin
+// @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
+// @AutoGenerate Version 2.7.6
+package sysin
+
+import (
+ "context"
+ "github.com/gogf/gf/v2/encoding/gjson"
+ "github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gtime"
+ "hotgo/internal/consts"
+ "hotgo/internal/model/entity"
+ "hotgo/internal/model/input/form"
+ "hotgo/utility/validate"
+)
+
+// ServeLicenseUpdateFields 修改服务许可证字段过滤
+type ServeLicenseUpdateFields struct {
+ Group string `json:"group" dc:"分组"`
+ Name string `json:"name" dc:"许可名称"`
+ Appid string `json:"appid" dc:"应用ID"`
+ SecretKey string `json:"secretKey" dc:"应用秘钥"`
+ OnlineLimit int `json:"onlineLimit" dc:"在线数量限制,默认1"`
+ //Routes *gjson.Json `json:"routes" dc:"路由表,空使用默认分组路由"`
+ AllowedIps string `json:"allowedIps" dc:"白名单,*代表所有,只有允许的IP才能连接到tcp服务"`
+ EndAt *gtime.Time `json:"endAt" dc:"授权结束时间"`
+ Remark string `json:"remark" dc:"备注"`
+ Status int `json:"status" dc:"状态"`
+}
+
+// ServeLicenseInsertFields 新增服务许可证字段过滤
+type ServeLicenseInsertFields struct {
+ Group string `json:"group" dc:"分组"`
+ Name string `json:"name" dc:"许可名称"`
+ Appid string `json:"appid" dc:"应用ID"`
+ SecretKey string `json:"secretKey" dc:"应用秘钥"`
+ OnlineLimit int `json:"onlineLimit" dc:"在线数量限制,默认1"`
+ //Routes *gjson.Json `json:"routes" dc:"路由表,空使用默认分组路由"`
+ AllowedIps string `json:"allowedIps" dc:"白名单,*代表所有,只有允许的IP才能连接到tcp服务"`
+ EndAt *gtime.Time `json:"endAt" dc:"授权结束时间"`
+ Remark string `json:"remark" dc:"备注"`
+ Status int `json:"status" dc:"状态"`
+}
+
+// ServeLicenseEditInp 修改/新增服务许可证
+type ServeLicenseEditInp struct {
+ entity.SysServeLicense
+}
+
+func (in *ServeLicenseEditInp) Filter(ctx context.Context) (err error) {
+ // 验证分组
+ if err := g.Validator().Rules("required").Data(in.Group).Messages("分组不能为空").Run(ctx); err != nil {
+ return err.Current()
+ }
+
+ // 验证许可名称
+ if err := g.Validator().Rules("required").Data(in.Name).Messages("许可名称不能为空").Run(ctx); err != nil {
+ return err.Current()
+ }
+
+ // 验证应用ID
+ if err := g.Validator().Rules("required").Data(in.Appid).Messages("应用ID不能为空").Run(ctx); err != nil {
+ return err.Current()
+ }
+
+ // 验证授权结束时间
+ if err := g.Validator().Rules("required").Data(in.EndAt).Messages("授权结束时间不能为空").Run(ctx); err != nil {
+ return err.Current()
+ }
+
+ return
+}
+
+type ServeLicenseEditModel struct{}
+
+// ServeLicenseDeleteInp 删除服务许可证
+type ServeLicenseDeleteInp struct {
+ Id interface{} `json:"id" v:"required#许可ID不能为空" dc:"许可ID"`
+}
+
+func (in *ServeLicenseDeleteInp) Filter(ctx context.Context) (err error) {
+ return
+}
+
+type ServeLicenseDeleteModel struct{}
+
+// ServeLicenseViewInp 获取指定服务许可证信息
+type ServeLicenseViewInp struct {
+ Id int64 `json:"id" v:"required#许可ID不能为空" dc:"许可ID"`
+}
+
+func (in *ServeLicenseViewInp) Filter(ctx context.Context) (err error) {
+ return
+}
+
+type ServeLicenseViewModel struct {
+ entity.SysServeLicense
+}
+
+// ServeLicenseListInp 获取服务许可证列表
+type ServeLicenseListInp struct {
+ form.PageReq
+ Id int64 `json:"id" dc:"许可ID"`
+ Group string `json:"group" dc:"分组"`
+ Name string `json:"name" dc:"许可名称"`
+ Appid string `json:"appid" dc:"应用ID"`
+ EndAt []*gtime.Time `json:"endAt" dc:"授权结束时间"`
+ Status int `json:"status" dc:"状态"`
+ CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
+}
+
+func (in *ServeLicenseListInp) Filter(ctx context.Context) (err error) {
+ return
+}
+
+type ServeLicenseListModel struct {
+ Id int64 `json:"id" dc:"许可ID"`
+ Group string `json:"group" dc:"分组"`
+ Name string `json:"name" dc:"许可名称"`
+ Appid string `json:"appid" dc:"应用ID"`
+ SecretKey string `json:"secretKey" dc:"应用秘钥"`
+ RemoteAddr string `json:"remoteAddr" dc:"最后连接地址"`
+ OnlineLimit int `json:"onlineLimit" dc:"在线数量限制,默认1"`
+ LoginTimes int64 `json:"loginTimes" dc:"登录次数"`
+ LastLoginAt *gtime.Time `json:"lastLoginAt" dc:"最后登录时间"`
+ LastActiveAt *gtime.Time `json:"lastActiveAt" dc:"最后活跃时间"`
+ EndAt *gtime.Time `json:"endAt" dc:"授权结束时间"`
+ Routes *gjson.Json `json:"routes" dc:"路由表,空使用默认分组路由"`
+ Status int `json:"status" dc:"状态"`
+ CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
+ UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"`
+ Online int `json:"online" dc:"在线"`
+}
+
+// ServeLicenseExportModel 导出服务许可证
+type ServeLicenseExportModel struct {
+ Id int64 `json:"id" dc:"许可ID"`
+ Group string `json:"group" dc:"分组"`
+ Name string `json:"name" dc:"许可名称"`
+ Appid string `json:"appid" dc:"应用ID"`
+ SecretKey string `json:"secretKey" dc:"应用秘钥"`
+ RemoteAddr string `json:"remoteAddr" dc:"最后连接地址"`
+ OnlineLimit int `json:"onlineLimit" dc:"在线数量限制,默认1"`
+ LoginTimes int64 `json:"loginTimes" dc:"登录次数"`
+ LastLoginAt *gtime.Time `json:"lastLoginAt" dc:"最后登录时间"`
+ LastActiveAt *gtime.Time `json:"lastActiveAt" dc:"最后活跃时间"`
+ EndAt *gtime.Time `json:"endAt" dc:"授权结束时间"`
+ Status int `json:"status" dc:"状态"`
+ CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
+ UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"`
+}
+
+// ServeLicenseStatusInp 更新服务许可证状态
+type ServeLicenseStatusInp struct {
+ Id int64 `json:"id" v:"required#许可ID不能为空" dc:"许可ID"`
+ Status int `json:"status" dc:"状态"`
+}
+
+func (in *ServeLicenseStatusInp) Filter(ctx context.Context) (err error) {
+ if in.Id <= 0 {
+ err = gerror.New("许可ID不能为空")
+ return
+ }
+
+ if in.Status <= 0 {
+ err = gerror.New("状态不能为空")
+ return
+ }
+
+ if !validate.InSlice(consts.StatusSlice, in.Status) {
+ err = gerror.New("状态不正确")
+ return
+ }
+ return
+}
+
+type ServeLicenseStatusModel struct{}
+
+type ServeLicenseAssignRouterInp struct {
+ Id int64 `json:"id" v:"required#许可ID不能为空" dc:"许可ID"`
+ Routes *gjson.Json `json:"routes" dc:"路由表,空使用默认分组路由"`
+}
+
+func (in *ServeLicenseAssignRouterInp) Filter(ctx context.Context) (err error) {
+ return
+}
diff --git a/server/internal/model/input/sysin/sms_log.go b/server/internal/model/input/sysin/sms_log.go
index d1e2003..52708bf 100644
--- a/server/internal/model/input/sysin/sms_log.go
+++ b/server/internal/model/input/sysin/sms_log.go
@@ -8,35 +8,29 @@ package sysin
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
+ "github.com/gogf/gf/v2/os/gtime"
"hotgo/internal/consts"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
)
-// SmsLogMaxSortInp 最大排序
-type SmsLogMaxSortInp struct {
- Id int64
-}
-
-type SmsLogMaxSortModel struct {
- Sort int
-}
-
// SmsLogEditInp 修改/新增数据
type SmsLogEditInp struct {
entity.SysSmsLog
}
+
type SmsLogEditModel struct{}
// SmsLogDeleteInp 删除
type SmsLogDeleteInp struct {
- Id interface{}
+ Id interface{} `json:"id" v:"required#短信记录ID不能为空" dc:"短信记录ID"`
}
+
type SmsLogDeleteModel struct{}
// SmsLogViewInp 获取信息
type SmsLogViewInp struct {
- Id int64
+ Id int64 `json:"id" v:"required#短信记录ID不能为空" dc:"短信记录ID"`
}
type SmsLogViewModel struct {
@@ -46,11 +40,11 @@ type SmsLogViewModel struct {
// SmsLogListInp 获取列表
type SmsLogListInp struct {
form.PageReq
- form.RangeDateReq
form.StatusReq
- Mobile string
- Ip string
- Event string
+ Mobile string `json:"mobile" dc:"手机号"`
+ Ip string `json:"ip" dc:"IP"`
+ Event string `json:"event" dc:"事件"`
+ CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
}
func (in *SmsLogListInp) Filter(ctx context.Context) (err error) {
@@ -71,6 +65,7 @@ type SmsLogListModel struct {
type SmsLogStatusInp struct {
entity.SysSmsLog
}
+
type SmsLogStatusModel struct{}
// SendCodeInp 发送验证码
diff --git a/server/internal/model/input/websocketin/send.go b/server/internal/model/input/websocketin/send.go
index ea54cbd..9a43844 100644
--- a/server/internal/model/input/websocketin/send.go
+++ b/server/internal/model/input/websocketin/send.go
@@ -3,15 +3,14 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package websocketin
import (
"hotgo/internal/websocket"
)
-// SendToTagInput 发送标签消息
-type SendToTagInput struct {
+// SendToTagInp 发送标签消息
+type SendToTagInp struct {
Tag string `json:"tag" v:"required#tag不能为空" description:"标签"`
Response websocket.WResponse `json:"response" v:"required#response不能为空" description:"响应内容"`
}
diff --git a/server/internal/queues/serve_log.go b/server/internal/queues/serve_log.go
index 3592aa1..60b7059 100644
--- a/server/internal/queues/serve_log.go
+++ b/server/internal/queues/serve_log.go
@@ -8,6 +8,7 @@ package queues
import (
"context"
"encoding/json"
+ "github.com/gogf/gf/v2/frame/g"
"hotgo/internal/consts"
"hotgo/internal/library/queue"
"hotgo/internal/model/entity"
@@ -32,12 +33,13 @@ func (q *qServeLog) GetTopic() string {
func (q *qServeLog) Handle(ctx context.Context, mqMsg queue.MqMsg) error {
var data entity.SysServeLog
if err := json.Unmarshal(mqMsg.Body, &data); err != nil {
- queue.Logger().Infof(ctx, "ServeLog Handle Unmarshal err:%+v", err)
+ g.Dump("ServeLog Handle Unmarshal err:%+v", err)
return nil
}
if err := service.SysServeLog().RealWrite(ctx, data); err != nil {
- queue.Logger().Infof(ctx, "ServeLog Handle Write err:%+v", err)
+ g.Dump("ServeLog Handle Write err:%+v", err)
+ return nil
}
return nil
}
diff --git a/server/internal/router/admin.go b/server/internal/router/admin.go
index 4c5c27c..5cd8a67 100644
--- a/server/internal/router/admin.go
+++ b/server/internal/router/admin.go
@@ -47,6 +47,7 @@ func Admin(ctx context.Context, group *ghttp.RouterGroup) {
sys.LoginLog, // 登录日志
sys.ServeLog, // 服务日志
sys.SmsLog, // 短信记录
+ sys.ServeLicense, // 服务许可证
admin.Member, // 用户
admin.Monitor, // 监控
admin.Role, // 路由
diff --git a/server/internal/router/genrouter/curd_demo.go b/server/internal/router/genrouter/curd_demo.go
index b5577ad..32f52ea 100644
--- a/server/internal/router/genrouter/curd_demo.go
+++ b/server/internal/router/genrouter/curd_demo.go
@@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-// @AutoGenerate Version 2.7.3
+// @AutoGenerate Version 2.7.6
package genrouter
import "hotgo/internal/controller/admin/sys"
diff --git a/server/internal/service/admin.go b/server/internal/service/admin.go
index 0847c61..230472c 100644
--- a/server/internal/service/admin.go
+++ b/server/internal/service/admin.go
@@ -18,148 +18,160 @@ import (
)
type (
- IAdminPost interface {
- Delete(ctx context.Context, in adminin.PostDeleteInp) (err error)
- Edit(ctx context.Context, in adminin.PostEditInp) (err error)
- MaxSort(ctx context.Context, in adminin.PostMaxSortInp) (res *adminin.PostMaxSortModel, err error)
- NameUnique(ctx context.Context, in adminin.PostNameUniqueInp) (res *adminin.PostNameUniqueModel, err error)
- CodeUnique(ctx context.Context, in adminin.PostCodeUniqueInp) (res *adminin.PostCodeUniqueModel, err error)
- View(ctx context.Context, in adminin.PostViewInp) (res *adminin.PostViewModel, err error)
- List(ctx context.Context, in adminin.PostListInp) (list []*adminin.PostListModel, totalCount int, err error)
- GetMemberByStartName(ctx context.Context, memberId int64) (name string, err error)
- Status(ctx context.Context, in adminin.PostStatusInp) (err error)
+ IAdminNotice interface {
+ Model(ctx context.Context, option ...*handler.Option) *gdb.Model
+ Delete(ctx context.Context, in *adminin.NoticeDeleteInp) (err error)
+ Edit(ctx context.Context, in *adminin.NoticeEditInp) (err error)
+ Status(ctx context.Context, in *adminin.NoticeStatusInp) (err error)
+ MaxSort(ctx context.Context, in *adminin.NoticeMaxSortInp) (res *adminin.NoticeMaxSortModel, err error)
+ View(ctx context.Context, in *adminin.NoticeViewInp) (res *adminin.NoticeViewModel, err error)
+ List(ctx context.Context, in *adminin.NoticeListInp) (list []*adminin.NoticeListModel, totalCount int, err error)
+ PullMessages(ctx context.Context, in *adminin.PullMessagesInp) (res *adminin.PullMessagesModel, err error)
+ UnreadCount(ctx context.Context, in *adminin.NoticeUnreadCountInp) (res *adminin.NoticeUnreadCountModel, err error)
+ UpRead(ctx context.Context, in *adminin.NoticeUpReadInp) (err error)
+ ReadAll(ctx context.Context, in *adminin.NoticeReadAllInp) (err error)
+ MessageList(ctx context.Context, in *adminin.NoticeMessageListInp) (list []*adminin.NoticeMessageListModel, totalCount int, err error)
+ }
+ IAdminOrder interface {
+ Model(ctx context.Context, option ...*handler.Option) *gdb.Model
+ AcceptRefund(ctx context.Context, in *adminin.OrderAcceptRefundInp) (err error)
+ ApplyRefund(ctx context.Context, in *adminin.OrderApplyRefundInp) (err error)
+ PayNotify(ctx context.Context, in *payin.NotifyCallFuncInp) (err error)
+ Create(ctx context.Context, in *adminin.OrderCreateInp) (res *adminin.OrderCreateModel, err error)
+ List(ctx context.Context, in *adminin.OrderListInp) (list []*adminin.OrderListModel, totalCount int, err error)
+ Export(ctx context.Context, in *adminin.OrderListInp) (err error)
+ Edit(ctx context.Context, in *adminin.OrderEditInp) (err error)
+ Delete(ctx context.Context, in *adminin.OrderDeleteInp) (err error)
+ View(ctx context.Context, in *adminin.OrderViewInp) (res *adminin.OrderViewModel, err error)
+ Status(ctx context.Context, in *adminin.OrderStatusInp) (err error)
}
IAdminRole interface {
Verify(ctx context.Context, path, method string) bool
- List(ctx context.Context, in adminin.RoleListInp) (res *adminin.RoleListModel, totalCount int, err error)
+ List(ctx context.Context, in *adminin.RoleListInp) (res *adminin.RoleListModel, totalCount int, err error)
GetName(ctx context.Context, id int64) (name string, err error)
GetMemberList(ctx context.Context, id int64) (list []*adminin.RoleListModel, err error)
- GetPermissions(ctx context.Context, in adminin.GetPermissionsInp) (res *adminin.GetPermissionsModel, err error)
- UpdatePermissions(ctx context.Context, in adminin.UpdatePermissionsInp) (err error)
- Edit(ctx context.Context, in adminin.RoleEditInp) (err error)
- Delete(ctx context.Context, in adminin.RoleDeleteInp) (err error)
+ GetPermissions(ctx context.Context, in *adminin.GetPermissionsInp) (res *adminin.GetPermissionsModel, err error)
+ UpdatePermissions(ctx context.Context, in *adminin.UpdatePermissionsInp) (err error)
+ Edit(ctx context.Context, in *adminin.RoleEditInp) (err error)
+ Delete(ctx context.Context, in *adminin.RoleDeleteInp) (err error)
DataScopeSelect() (res form.Selects)
DataScopeEdit(ctx context.Context, in *adminin.DataScopeEditInp) (err error)
}
IAdminCreditsLog interface {
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
- SaveBalance(ctx context.Context, in adminin.CreditsLogSaveBalanceInp) (res *adminin.CreditsLogSaveBalanceModel, err error)
- SaveIntegral(ctx context.Context, in adminin.CreditsLogSaveIntegralInp) (res *adminin.CreditsLogSaveIntegralModel, err error)
- List(ctx context.Context, in adminin.CreditsLogListInp) (list []*adminin.CreditsLogListModel, totalCount int, err error)
- Export(ctx context.Context, in adminin.CreditsLogListInp) (err error)
+ SaveBalance(ctx context.Context, in *adminin.CreditsLogSaveBalanceInp) (res *adminin.CreditsLogSaveBalanceModel, err error)
+ SaveIntegral(ctx context.Context, in *adminin.CreditsLogSaveIntegralInp) (res *adminin.CreditsLogSaveIntegralModel, err error)
+ List(ctx context.Context, in *adminin.CreditsLogListInp) (list []*adminin.CreditsLogListModel, totalCount int, err error)
+ Export(ctx context.Context, in *adminin.CreditsLogListInp) (err error)
}
- IAdminDept interface {
- Delete(ctx context.Context, in adminin.DeptDeleteInp) (err error)
- Edit(ctx context.Context, in adminin.DeptEditInp) (err error)
- Status(ctx context.Context, in adminin.DeptStatusInp) (err error)
- MaxSort(ctx context.Context, in adminin.DeptMaxSortInp) (res *adminin.DeptMaxSortModel, err error)
- View(ctx context.Context, in adminin.DeptViewInp) (res *adminin.DeptViewModel, err error)
- Option(ctx context.Context, in adminin.DeptOptionInp) (res *adminin.DeptOptionModel, totalCount int, err error)
- List(ctx context.Context, in adminin.DeptListInp) (res *adminin.DeptListModel, err error)
- GetName(ctx context.Context, id int64) (name string, err error)
+ IAdminMenu interface {
+ Delete(ctx context.Context, in *adminin.MenuDeleteInp) (err error)
+ VerifyUnique(ctx context.Context, in *adminin.VerifyUniqueInp) (err error)
+ Edit(ctx context.Context, in *adminin.MenuEditInp) (err error)
+ List(ctx context.Context, in *adminin.MenuListInp) (res *adminin.MenuListModel, err error)
+ GetMenuList(ctx context.Context, memberId int64) (res *role.DynamicRes, err error)
+ LoginPermissions(ctx context.Context, memberId int64) (lists adminin.MemberLoginPermissions, err error)
}
IAdminMember interface {
- AddBalance(ctx context.Context, in adminin.MemberAddBalanceInp) (err error)
- AddIntegral(ctx context.Context, in adminin.MemberAddIntegralInp) (err error)
- UpdateCash(ctx context.Context, in adminin.MemberUpdateCashInp) (err error)
- UpdateEmail(ctx context.Context, in adminin.MemberUpdateEmailInp) (err error)
- UpdateMobile(ctx context.Context, in adminin.MemberUpdateMobileInp) (err error)
- UpdateProfile(ctx context.Context, in adminin.MemberUpdateProfileInp) (err error)
- UpdatePwd(ctx context.Context, in adminin.MemberUpdatePwdInp) (err error)
- ResetPwd(ctx context.Context, in adminin.MemberResetPwdInp) (err error)
- VerifyUnique(ctx context.Context, in adminin.VerifyUniqueInp) (err error)
- Delete(ctx context.Context, in adminin.MemberDeleteInp) (err error)
- Edit(ctx context.Context, in adminin.MemberEditInp) (err error)
- View(ctx context.Context, in adminin.MemberViewInp) (res *adminin.MemberViewModel, err error)
- List(ctx context.Context, in adminin.MemberListInp) (list []*adminin.MemberListModel, totalCount int, err error)
- Status(ctx context.Context, in adminin.MemberStatusInp) (err error)
+ AddBalance(ctx context.Context, in *adminin.MemberAddBalanceInp) (err error)
+ AddIntegral(ctx context.Context, in *adminin.MemberAddIntegralInp) (err error)
+ UpdateCash(ctx context.Context, in *adminin.MemberUpdateCashInp) (err error)
+ UpdateEmail(ctx context.Context, in *adminin.MemberUpdateEmailInp) (err error)
+ UpdateMobile(ctx context.Context, in *adminin.MemberUpdateMobileInp) (err error)
+ UpdateProfile(ctx context.Context, in *adminin.MemberUpdateProfileInp) (err error)
+ UpdatePwd(ctx context.Context, in *adminin.MemberUpdatePwdInp) (err error)
+ ResetPwd(ctx context.Context, in *adminin.MemberResetPwdInp) (err error)
+ VerifyUnique(ctx context.Context, in *adminin.VerifyUniqueInp) (err error)
+ Delete(ctx context.Context, in *adminin.MemberDeleteInp) (err error)
+ Edit(ctx context.Context, in *adminin.MemberEditInp) (err error)
+ View(ctx context.Context, in *adminin.MemberViewInp) (res *adminin.MemberViewModel, err error)
+ List(ctx context.Context, in *adminin.MemberListInp) (list []*adminin.MemberListModel, totalCount int, err error)
+ Status(ctx context.Context, in *adminin.MemberStatusInp) (err error)
GenTree(ctx context.Context, pid int64) (level int, newTree string, err error)
LoginMemberInfo(ctx context.Context) (res *adminin.LoginMemberInfoModel, err error)
- MemberLoginStat(ctx context.Context, in adminin.MemberLoginStatInp) (res *adminin.MemberLoginStatModel, err error)
- GetIdByCode(ctx context.Context, in adminin.GetIdByCodeInp) (res *adminin.GetIdByCodeModel, err error)
- Select(ctx context.Context, in adminin.MemberSelectInp) (res []*adminin.MemberSelectModel, err error)
+ MemberLoginStat(ctx context.Context, in *adminin.MemberLoginStatInp) (res *adminin.MemberLoginStatModel, err error)
+ GetIdByCode(ctx context.Context, in *adminin.GetIdByCodeInp) (res *adminin.GetIdByCodeModel, err error)
+ Select(ctx context.Context, in *adminin.MemberSelectInp) (res []*adminin.MemberSelectModel, err error)
VerifySuperId(ctx context.Context, verifyId int64) bool
+ LoadSuperAdmin(ctx context.Context)
FilterAuthModel(ctx context.Context, memberId int64) *gdb.Model
}
IAdminMemberPost interface {
UpdatePostIds(ctx context.Context, memberId int64, postIds []int64) (err error)
}
- IAdminMenu interface {
- Delete(ctx context.Context, in adminin.MenuDeleteInp) (err error)
- VerifyUnique(ctx context.Context, in adminin.VerifyUniqueInp) (err error)
- Edit(ctx context.Context, in adminin.MenuEditInp) (err error)
- List(ctx context.Context, in adminin.MenuListInp) (res *adminin.MenuListModel, err error)
- GetMenuList(ctx context.Context, memberId int64) (res *role.DynamicRes, err error)
- LoginPermissions(ctx context.Context, memberId int64) (lists adminin.MemberLoginPermissions, err error)
- }
IAdminMonitor interface {
StartMonitor(ctx context.Context)
GetMeta(ctx context.Context) *model.MonitorData
}
- IAdminNotice interface {
- Model(ctx context.Context, option ...*handler.Option) *gdb.Model
- Delete(ctx context.Context, in adminin.NoticeDeleteInp) (err error)
- Edit(ctx context.Context, in adminin.NoticeEditInp) (err error)
- Status(ctx context.Context, in adminin.NoticeStatusInp) (err error)
- MaxSort(ctx context.Context, in adminin.NoticeMaxSortInp) (res *adminin.NoticeMaxSortModel, err error)
- View(ctx context.Context, in adminin.NoticeViewInp) (res *adminin.NoticeViewModel, err error)
- List(ctx context.Context, in adminin.NoticeListInp) (list []*adminin.NoticeListModel, totalCount int, err error)
- PullMessages(ctx context.Context, in adminin.PullMessagesInp) (res *adminin.PullMessagesModel, err error)
- UnreadCount(ctx context.Context, in adminin.NoticeUnreadCountInp) (res *adminin.NoticeUnreadCountModel, err error)
- UpRead(ctx context.Context, in adminin.NoticeUpReadInp) (err error)
- ReadAll(ctx context.Context, in adminin.NoticeReadAllInp) (err error)
- MessageList(ctx context.Context, in adminin.NoticeMessageListInp) (list []*adminin.NoticeMessageListModel, totalCount int, err error)
- }
- IAdminOrder interface {
- Model(ctx context.Context, option ...*handler.Option) *gdb.Model
- AcceptRefund(ctx context.Context, in adminin.OrderAcceptRefundInp) (err error)
- ApplyRefund(ctx context.Context, in adminin.OrderApplyRefundInp) (err error)
- PayNotify(ctx context.Context, in payin.NotifyCallFuncInp) (err error)
- Create(ctx context.Context, in adminin.OrderCreateInp) (res *adminin.OrderCreateModel, err error)
- List(ctx context.Context, in adminin.OrderListInp) (list []*adminin.OrderListModel, totalCount int, err error)
- Export(ctx context.Context, in adminin.OrderListInp) (err error)
- Edit(ctx context.Context, in adminin.OrderEditInp) (err error)
- Delete(ctx context.Context, in adminin.OrderDeleteInp) (err error)
- View(ctx context.Context, in adminin.OrderViewInp) (res *adminin.OrderViewModel, err error)
- Status(ctx context.Context, in adminin.OrderStatusInp) (err error)
- }
- IAdminCash interface {
- View(ctx context.Context, in adminin.CashViewInp) (res *adminin.CashViewModel, err error)
- List(ctx context.Context, in adminin.CashListInp) (list []*adminin.CashListModel, totalCount int, err error)
- Apply(ctx context.Context, in adminin.CashApplyInp) (err error)
- Payment(ctx context.Context, in adminin.CashPaymentInp) (err error)
+ IAdminPost interface {
+ Delete(ctx context.Context, in *adminin.PostDeleteInp) (err error)
+ VerifyUnique(ctx context.Context, in *adminin.VerifyUniqueInp) (err error)
+ Edit(ctx context.Context, in *adminin.PostEditInp) (err error)
+ MaxSort(ctx context.Context, in *adminin.PostMaxSortInp) (res *adminin.PostMaxSortModel, err error)
+ View(ctx context.Context, in *adminin.PostViewInp) (res *adminin.PostViewModel, err error)
+ List(ctx context.Context, in *adminin.PostListInp) (list []*adminin.PostListModel, totalCount int, err error)
+ GetMemberByStartName(ctx context.Context, memberId int64) (name string, err error)
+ Status(ctx context.Context, in *adminin.PostStatusInp) (err error)
}
IAdminSite interface {
- Register(ctx context.Context, in adminin.RegisterInp) (err error)
- AccountLogin(ctx context.Context, in adminin.AccountLoginInp) (res *adminin.LoginModel, err error)
- MobileLogin(ctx context.Context, in adminin.MobileLoginInp) (res *adminin.LoginModel, err error)
+ Register(ctx context.Context, in *adminin.RegisterInp) (err error)
+ AccountLogin(ctx context.Context, in *adminin.AccountLoginInp) (res *adminin.LoginModel, err error)
+ MobileLogin(ctx context.Context, in *adminin.MobileLoginInp) (res *adminin.LoginModel, err error)
+ }
+ IAdminCash interface {
+ View(ctx context.Context, in *adminin.CashViewInp) (res *adminin.CashViewModel, err error)
+ List(ctx context.Context, in *adminin.CashListInp) (list []*adminin.CashListModel, totalCount int, err error)
+ Apply(ctx context.Context, in *adminin.CashApplyInp) (err error)
+ Payment(ctx context.Context, in *adminin.CashPaymentInp) (err error)
+ }
+ IAdminDept interface {
+ Delete(ctx context.Context, in *adminin.DeptDeleteInp) (err error)
+ VerifyUnique(ctx context.Context, in *adminin.VerifyUniqueInp) (err error)
+ Edit(ctx context.Context, in *adminin.DeptEditInp) (err error)
+ Status(ctx context.Context, in *adminin.DeptStatusInp) (err error)
+ MaxSort(ctx context.Context, in *adminin.DeptMaxSortInp) (res *adminin.DeptMaxSortModel, err error)
+ View(ctx context.Context, in *adminin.DeptViewInp) (res *adminin.DeptViewModel, err error)
+ Option(ctx context.Context, in *adminin.DeptOptionInp) (res *adminin.DeptOptionModel, totalCount int, err error)
+ List(ctx context.Context, in *adminin.DeptListInp) (res *adminin.DeptListModel, err error)
+ GetName(ctx context.Context, id int64) (name string, err error)
}
)
var (
+ localAdminCreditsLog IAdminCreditsLog
+ localAdminMenu IAdminMenu
+ localAdminNotice IAdminNotice
+ localAdminOrder IAdminOrder
+ localAdminRole IAdminRole
+ localAdminCash IAdminCash
localAdminDept IAdminDept
localAdminMember IAdminMember
localAdminMemberPost IAdminMemberPost
- localAdminMenu IAdminMenu
localAdminMonitor IAdminMonitor
- localAdminNotice IAdminNotice
- localAdminOrder IAdminOrder
- localAdminCash IAdminCash
- localAdminSite IAdminSite
localAdminPost IAdminPost
- localAdminRole IAdminRole
- localAdminCreditsLog IAdminCreditsLog
+ localAdminSite IAdminSite
)
-func AdminMonitor() IAdminMonitor {
- if localAdminMonitor == nil {
- panic("implement not found for interface IAdminMonitor, forgot register?")
+func AdminCreditsLog() IAdminCreditsLog {
+ if localAdminCreditsLog == nil {
+ panic("implement not found for interface IAdminCreditsLog, forgot register?")
}
- return localAdminMonitor
+ return localAdminCreditsLog
}
-func RegisterAdminMonitor(i IAdminMonitor) {
- localAdminMonitor = i
+func RegisterAdminCreditsLog(i IAdminCreditsLog) {
+ localAdminCreditsLog = i
+}
+
+func AdminMenu() IAdminMenu {
+ if localAdminMenu == nil {
+ panic("implement not found for interface IAdminMenu, forgot register?")
+ }
+ return localAdminMenu
+}
+
+func RegisterAdminMenu(i IAdminMenu) {
+ localAdminMenu = i
}
func AdminNotice() IAdminNotice {
@@ -184,6 +196,17 @@ func RegisterAdminOrder(i IAdminOrder) {
localAdminOrder = i
}
+func AdminRole() IAdminRole {
+ if localAdminRole == nil {
+ panic("implement not found for interface IAdminRole, forgot register?")
+ }
+ return localAdminRole
+}
+
+func RegisterAdminRole(i IAdminRole) {
+ localAdminRole = i
+}
+
func AdminCash() IAdminCash {
if localAdminCash == nil {
panic("implement not found for interface IAdminCash, forgot register?")
@@ -228,37 +251,15 @@ func RegisterAdminMemberPost(i IAdminMemberPost) {
localAdminMemberPost = i
}
-func AdminMenu() IAdminMenu {
- if localAdminMenu == nil {
- panic("implement not found for interface IAdminMenu, forgot register?")
+func AdminMonitor() IAdminMonitor {
+ if localAdminMonitor == nil {
+ panic("implement not found for interface IAdminMonitor, forgot register?")
}
- return localAdminMenu
+ return localAdminMonitor
}
-func RegisterAdminMenu(i IAdminMenu) {
- localAdminMenu = i
-}
-
-func AdminSite() IAdminSite {
- if localAdminSite == nil {
- panic("implement not found for interface IAdminSite, forgot register?")
- }
- return localAdminSite
-}
-
-func RegisterAdminSite(i IAdminSite) {
- localAdminSite = i
-}
-
-func AdminCreditsLog() IAdminCreditsLog {
- if localAdminCreditsLog == nil {
- panic("implement not found for interface IAdminCreditsLog, forgot register?")
- }
- return localAdminCreditsLog
-}
-
-func RegisterAdminCreditsLog(i IAdminCreditsLog) {
- localAdminCreditsLog = i
+func RegisterAdminMonitor(i IAdminMonitor) {
+ localAdminMonitor = i
}
func AdminPost() IAdminPost {
@@ -272,13 +273,13 @@ func RegisterAdminPost(i IAdminPost) {
localAdminPost = i
}
-func AdminRole() IAdminRole {
- if localAdminRole == nil {
- panic("implement not found for interface IAdminRole, forgot register?")
+func AdminSite() IAdminSite {
+ if localAdminSite == nil {
+ panic("implement not found for interface IAdminSite, forgot register?")
}
- return localAdminRole
+ return localAdminSite
}
-func RegisterAdminRole(i IAdminRole) {
- localAdminRole = i
+func RegisterAdminSite(i IAdminSite) {
+ localAdminSite = i
}
diff --git a/server/internal/service/common.go b/server/internal/service/common.go
index e2b18f1..c3a099f 100644
--- a/server/internal/service/common.go
+++ b/server/internal/service/common.go
@@ -1,5 +1,5 @@
// ================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
@@ -15,14 +15,17 @@ import (
type (
ICommonUpload interface {
- UploadFile(ctx context.Context, file *ghttp.UploadFile) (res *sysin.AttachmentListModel, err error)
- UploadImage(ctx context.Context, file *ghttp.UploadFile) (res *sysin.AttachmentListModel, err error)
+ // UploadFile 上传文件
+ UploadFile(ctx context.Context, uploadType string, file *ghttp.UploadFile) (res *sysin.AttachmentListModel, err error)
}
ICommonWechat interface {
- Authorize(ctx context.Context, in commonin.WechatAuthorizeInp) (res *commonin.WechatAuthorizeModel, err error)
- AuthorizeCall(ctx context.Context, in commonin.WechatAuthorizeCallInp) (res *commonin.WechatAuthorizeCallModel, err error)
+ // Authorize 微信用户授权
+ Authorize(ctx context.Context, in *commonin.WechatAuthorizeInp) (res *commonin.WechatAuthorizeModel, err error)
+ AuthorizeCall(ctx context.Context, in *commonin.WechatAuthorizeCallInp) (res *commonin.WechatAuthorizeCallModel, err error)
+ // GetOpenId 从缓存中获取临时openid
GetOpenId(ctx context.Context) (openId string, err error)
GetCacheKey(typ, ak string) string
+ // CleanTempMap 清理临时map
CleanTempMap(ctx context.Context)
}
)
diff --git a/server/internal/service/middleware.go b/server/internal/service/middleware.go
index e739453..7e05e6c 100644
--- a/server/internal/service/middleware.go
+++ b/server/internal/service/middleware.go
@@ -25,6 +25,9 @@ type (
IsExceptLogin(ctx context.Context, appName, path string) bool
Blacklist(r *ghttp.Request)
Develop(r *ghttp.Request)
+ GetFilterRoutes(r *ghttp.Request) map[string]ghttp.RouterItem
+ GenFilterRouteKey(router *ghttp.Router) string
+ PreFilter(r *ghttp.Request)
ResponseHandler(r *ghttp.Request)
WebSocketAuth(r *ghttp.Request)
}
diff --git a/server/internal/service/pay.go b/server/internal/service/pay.go
index ae0a693..6006066 100644
--- a/server/internal/service/pay.go
+++ b/server/internal/service/pay.go
@@ -14,16 +14,10 @@ import (
)
type (
- IPayRefund interface {
- Model(ctx context.Context, option ...*handler.Option) *gdb.Model
- Refund(ctx context.Context, in payin.PayRefundInp) (res *payin.PayRefundModel, err error)
- List(ctx context.Context, in payin.PayRefundListInp) (list []*payin.PayRefundListModel, totalCount int, err error)
- Export(ctx context.Context, in payin.PayRefundListInp) (err error)
- }
IPay interface {
Create(ctx context.Context, in payin.PayCreateInp) (res *payin.PayCreateModel, err error)
GenNotifyURL(ctx context.Context, in payin.PayCreateInp) (notifyURL string, err error)
- Notify(ctx context.Context, in payin.PayNotifyInp) (res *payin.PayNotifyModel, err error)
+ Notify(ctx context.Context, in *payin.PayNotifyInp) (res *payin.PayNotifyModel, err error)
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
List(ctx context.Context, in payin.PayListInp) (list []*payin.PayListModel, totalCount int, err error)
Export(ctx context.Context, in payin.PayListInp) (err error)
@@ -32,6 +26,12 @@ type (
View(ctx context.Context, in payin.PayViewInp) (res *payin.PayViewModel, err error)
Status(ctx context.Context, in payin.PayStatusInp) (err error)
}
+ IPayRefund interface {
+ Model(ctx context.Context, option ...*handler.Option) *gdb.Model
+ Refund(ctx context.Context, in *payin.PayRefundInp) (res *payin.PayRefundModel, err error)
+ List(ctx context.Context, in *payin.PayRefundListInp) (list []*payin.PayRefundListModel, totalCount int, err error)
+ Export(ctx context.Context, in *payin.PayRefundListInp) (err error)
+ }
)
var (
diff --git a/server/internal/service/sys.go b/server/internal/service/sys.go
index 0baa832..ddf539b 100644
--- a/server/internal/service/sys.go
+++ b/server/internal/service/sys.go
@@ -1,5 +1,5 @@
// ================================================================================
-// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
@@ -16,249 +16,342 @@ import (
)
type (
- ISysDictType interface {
- Tree(ctx context.Context) (list []*sysin.DictTypeTree, err error)
- Delete(ctx context.Context, in sysin.DictTypeDeleteInp) (err error)
- Edit(ctx context.Context, in sysin.DictTypeEditInp) (err error)
- TreeSelect(ctx context.Context, in sysin.DictTreeSelectInp) (list []*sysin.DictTypeTree, err error)
- }
- ISysEmsLog interface {
- Delete(ctx context.Context, in sysin.EmsLogDeleteInp) (err error)
- Edit(ctx context.Context, in sysin.EmsLogEditInp) (err error)
- Status(ctx context.Context, in sysin.EmsLogStatusInp) (err error)
- View(ctx context.Context, in sysin.EmsLogViewInp) (res *sysin.EmsLogViewModel, err error)
- List(ctx context.Context, in sysin.EmsLogListInp) (list []*sysin.EmsLogListModel, totalCount int, err error)
- Send(ctx context.Context, in sysin.SendEmsInp) (err error)
- GetTemplate(ctx context.Context, template string, config *model.EmailConfig) (val string, err error)
- AllowSend(ctx context.Context, models *entity.SysEmsLog, config *model.EmailConfig) (err error)
- VerifyCode(ctx context.Context, in sysin.VerifyEmsCodeInp) (err error)
- }
- ISysProvinces interface {
- Tree(ctx context.Context) (list []*sysin.ProvincesTree, err error)
- Delete(ctx context.Context, in sysin.ProvincesDeleteInp) (err error)
- Edit(ctx context.Context, in sysin.ProvincesEditInp) (err error)
- Status(ctx context.Context, in sysin.ProvincesStatusInp) (err error)
- MaxSort(ctx context.Context, in sysin.ProvincesMaxSortInp) (res *sysin.ProvincesMaxSortModel, err error)
- View(ctx context.Context, in sysin.ProvincesViewInp) (res *sysin.ProvincesViewModel, err error)
- List(ctx context.Context, in sysin.ProvincesListInp) (list []*sysin.ProvincesListModel, totalCount int, err error)
- ChildrenList(ctx context.Context, in sysin.ProvincesChildrenListInp) (list []*sysin.ProvincesChildrenListModel, totalCount int, err error)
- UniqueId(ctx context.Context, in sysin.ProvincesUniqueIdInp) (res *sysin.ProvincesUniqueIdModel, err error)
- Select(ctx context.Context, in sysin.ProvincesSelectInp) (res *sysin.ProvincesSelectModel, err error)
- }
- ISysSmsLog interface {
- Delete(ctx context.Context, in sysin.SmsLogDeleteInp) (err error)
- Edit(ctx context.Context, in sysin.SmsLogEditInp) (err error)
- Status(ctx context.Context, in sysin.SmsLogStatusInp) (err error)
- MaxSort(ctx context.Context, in sysin.SmsLogMaxSortInp) (res *sysin.SmsLogMaxSortModel, err error)
- View(ctx context.Context, in sysin.SmsLogViewInp) (res *sysin.SmsLogViewModel, err error)
- List(ctx context.Context, in sysin.SmsLogListInp) (list []*sysin.SmsLogListModel, totalCount int, err error)
- SendCode(ctx context.Context, in sysin.SendCodeInp) (err error)
- GetTemplate(ctx context.Context, template string, config *model.SmsConfig) (val string, err error)
- AllowSend(ctx context.Context, models *entity.SysSmsLog, config *model.SmsConfig) (err error)
- VerifyCode(ctx context.Context, in sysin.VerifyCodeInp) (err error)
- }
- ISysAddons interface {
- List(ctx context.Context, in sysin.AddonsListInp) (list []*sysin.AddonsListModel, totalCount int, err error)
- Selects(ctx context.Context, in sysin.AddonsSelectsInp) (res *sysin.AddonsSelectsModel, err error)
- Build(ctx context.Context, in sysin.AddonsBuildInp) (err error)
- Install(ctx context.Context, in sysin.AddonsInstallInp) (err error)
- Upgrade(ctx context.Context, in sysin.AddonsUpgradeInp) (err error)
- UnInstall(ctx context.Context, in sysin.AddonsUnInstallInp) (err error)
- }
- ISysAttachment interface {
- Model(ctx context.Context, option ...*handler.Option) *gdb.Model
- Delete(ctx context.Context, in sysin.AttachmentDeleteInp) (err error)
- View(ctx context.Context, in sysin.AttachmentViewInp) (res *sysin.AttachmentViewModel, err error)
- List(ctx context.Context, in sysin.AttachmentListInp) (list []*sysin.AttachmentListModel, totalCount int, err error)
- }
- ISysBlacklist interface {
- Delete(ctx context.Context, in sysin.BlacklistDeleteInp) (err error)
- Edit(ctx context.Context, in sysin.BlacklistEditInp) (err error)
- Status(ctx context.Context, in sysin.BlacklistStatusInp) (err error)
- MaxSort(ctx context.Context, in sysin.BlacklistMaxSortInp) (res *sysin.BlacklistMaxSortModel, err error)
- View(ctx context.Context, in sysin.BlacklistViewInp) (res *sysin.BlacklistViewModel, err error)
- List(ctx context.Context, in sysin.BlacklistListInp) (list []*sysin.BlacklistListModel, totalCount int, err error)
- VariableLoad(ctx context.Context, err error)
- Load(ctx context.Context)
- }
- ISysCurdDemo interface {
- Model(ctx context.Context, option ...*handler.Option) *gdb.Model
- List(ctx context.Context, in sysin.CurdDemoListInp) (list []*sysin.CurdDemoListModel, totalCount int, err error)
- Export(ctx context.Context, in sysin.CurdDemoListInp) (err error)
- Edit(ctx context.Context, in sysin.CurdDemoEditInp) (err error)
- Delete(ctx context.Context, in sysin.CurdDemoDeleteInp) (err error)
- MaxSort(ctx context.Context, in sysin.CurdDemoMaxSortInp) (res *sysin.CurdDemoMaxSortModel, err error)
- View(ctx context.Context, in sysin.CurdDemoViewInp) (res *sysin.CurdDemoViewModel, err error)
- Status(ctx context.Context, in sysin.CurdDemoStatusInp) (err error)
- Switch(ctx context.Context, in sysin.CurdDemoSwitchInp) (err error)
- }
- ISysLoginLog interface {
- Model(ctx context.Context) *gdb.Model
- List(ctx context.Context, in sysin.LoginLogListInp) (list []*sysin.LoginLogListModel, totalCount int, err error)
- Export(ctx context.Context, in sysin.LoginLogListInp) (err error)
- Delete(ctx context.Context, in sysin.LoginLogDeleteInp) (err error)
- View(ctx context.Context, in sysin.LoginLogViewInp) (res *sysin.LoginLogViewModel, err error)
- Push(ctx context.Context, in sysin.LoginLogPushInp)
- RealWrite(ctx context.Context, models entity.SysLoginLog) (err error)
- }
- ISysAddonsConfig interface {
- GetConfigByGroup(ctx context.Context, in sysin.GetAddonsConfigInp) (res *sysin.GetAddonsConfigModel, err error)
- ConversionType(ctx context.Context, models *entity.SysAddonsConfig) (value interface{}, err error)
- UpdateConfigByGroup(ctx context.Context, in sysin.UpdateAddonsConfigInp) (err error)
+ ISysConfig interface {
+ // InitConfig 初始化一些系统启动就需要用到的配置
+ InitConfig(ctx context.Context)
+ // GetLogin 获取登录配置
+ GetLogin(ctx context.Context) (conf *model.LoginConfig, err error)
+ // GetWechat 获取微信配置
+ GetWechat(ctx context.Context) (conf *model.WechatConfig, err error)
+ // GetPay 获取支付配置
+ GetPay(ctx context.Context) (conf *model.PayConfig, err error)
+ // GetSms 获取短信配置
+ GetSms(ctx context.Context) (conf *model.SmsConfig, err error)
+ // GetGeo 获取地理配置
+ GetGeo(ctx context.Context) (conf *model.GeoConfig, err error)
+ // GetUpload 获取上传配置
+ GetUpload(ctx context.Context) (conf *model.UploadConfig, err error)
+ // GetSmtp 获取邮件配置
+ GetSmtp(ctx context.Context) (conf *model.EmailConfig, err error)
+ // GetBasic 获取基础配置
+ GetBasic(ctx context.Context) (conf *model.BasicConfig, err error)
+ // GetLoadTCP 获取本地tcp配置
+ GetLoadTCP(ctx context.Context) (conf *model.TCPConfig, err error)
+ // GetLoadCache 获取本地缓存配置
+ GetLoadCache(ctx context.Context) (conf *model.CacheConfig, err error)
+ // GetLoadGenerate 获取本地生成配置
+ GetLoadGenerate(ctx context.Context) (conf *model.GenerateConfig, err error)
+ // GetLoadToken 获取本地token配置
+ GetLoadToken(ctx context.Context) (conf *model.TokenConfig, err error)
+ // GetLoadLog 获取本地日志配置
+ GetLoadLog(ctx context.Context) (conf *model.LogConfig, err error)
+ // GetLoadServeLog 获取本地服务日志配置
+ GetLoadServeLog(ctx context.Context) (conf *model.ServeLogConfig, err error)
+ // GetConfigByGroup 获取指定分组的配置
+ GetConfigByGroup(ctx context.Context, in *sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
+ // ConversionType 转换类型
+ ConversionType(ctx context.Context, models *entity.SysConfig) (value interface{}, err error)
+ // UpdateConfigByGroup 更新指定分组的配置
+ UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateConfigInp) (err error)
}
ISysServeLog interface {
+ // Model 服务日志Orm模型
Model(ctx context.Context) *gdb.Model
- List(ctx context.Context, in sysin.ServeLogListInp) (list []*sysin.ServeLogListModel, totalCount int, err error)
- Export(ctx context.Context, in sysin.ServeLogListInp) (err error)
- Delete(ctx context.Context, in sysin.ServeLogDeleteInp) (err error)
- View(ctx context.Context, in sysin.ServeLogViewInp) (res *sysin.ServeLogViewModel, err error)
+ // List 获取服务日志列表
+ List(ctx context.Context, in *sysin.ServeLogListInp) (list []*sysin.ServeLogListModel, totalCount int, err error)
+ // Export 导出服务日志
+ Export(ctx context.Context, in *sysin.ServeLogListInp) (err error)
+ // Delete 删除服务日志
+ Delete(ctx context.Context, in *sysin.ServeLogDeleteInp) (err error)
+ // View 获取服务日志指定信息
+ View(ctx context.Context, in *sysin.ServeLogViewInp) (res *sysin.ServeLogViewModel, err error)
+ // RealWrite 真实写入
RealWrite(ctx context.Context, models entity.SysServeLog) (err error)
}
- ISysLog interface {
- Export(ctx context.Context, in sysin.LogListInp) (err error)
- RealWrite(ctx context.Context, log entity.SysLog) (err error)
- AutoLog(ctx context.Context) error
- AnalysisLog(ctx context.Context) entity.SysLog
- View(ctx context.Context, in sysin.LogViewInp) (res *sysin.LogViewModel, err error)
- Delete(ctx context.Context, in sysin.LogDeleteInp) (err error)
- List(ctx context.Context, in sysin.LogListInp) (list []*sysin.LogListModel, totalCount int, err error)
+ ISysAddons interface {
+ // List 获取列表
+ List(ctx context.Context, in *sysin.AddonsListInp) (list []*sysin.AddonsListModel, totalCount int, err error)
+ // Selects 选项
+ Selects(ctx context.Context, in *sysin.AddonsSelectsInp) (res *sysin.AddonsSelectsModel, err error)
+ // Build 提交生成
+ Build(ctx context.Context, in *sysin.AddonsBuildInp) (err error)
+ // Install 安装模块
+ Install(ctx context.Context, in *sysin.AddonsInstallInp) (err error)
+ // Upgrade 更新模块
+ Upgrade(ctx context.Context, in *sysin.AddonsUpgradeInp) (err error)
+ // UnInstall 卸载模块
+ UnInstall(ctx context.Context, in *sysin.AddonsUnInstallInp) (err error)
}
- ISysConfig interface {
- InitConfig(ctx context.Context)
- GetLogin(ctx context.Context) (conf *model.LoginConfig, err error)
- GetWechat(ctx context.Context) (conf *model.WechatConfig, err error)
- GetPay(ctx context.Context) (conf *model.PayConfig, err error)
- GetSms(ctx context.Context) (conf *model.SmsConfig, err error)
- GetGeo(ctx context.Context) (conf *model.GeoConfig, err error)
- GetUpload(ctx context.Context) (conf *model.UploadConfig, err error)
- GetSmtp(ctx context.Context) (conf *model.EmailConfig, err error)
- GetBasic(ctx context.Context) (conf *model.BasicConfig, err error)
- GetLoadTCP(ctx context.Context) (conf *model.TCPConfig, err error)
- GetLoadCache(ctx context.Context) (conf *model.CacheConfig, err error)
- GetLoadGenerate(ctx context.Context) (conf *model.GenerateConfig, err error)
- GetLoadToken(ctx context.Context) (conf *model.TokenConfig, err error)
- GetLoadLog(ctx context.Context) (conf *model.LogConfig, err error)
- GetLoadServeLog(ctx context.Context) (conf *model.ServeLogConfig, err error)
- GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
- ConversionType(ctx context.Context, models *entity.SysConfig) (value interface{}, err error)
- UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) (err error)
+ ISysAttachment interface {
+ // Model ORM模型
+ Model(ctx context.Context, option ...*handler.Option) *gdb.Model
+ // Delete 删除附件
+ Delete(ctx context.Context, in *sysin.AttachmentDeleteInp) (err error)
+ // View 获取附件信息
+ View(ctx context.Context, in *sysin.AttachmentViewInp) (res *sysin.AttachmentViewModel, err error)
+ // List 获取附件列表
+ List(ctx context.Context, in *sysin.AttachmentListInp) (list []*sysin.AttachmentListModel, totalCount int, err error)
+ // ClearKind 清空上传类型
+ ClearKind(ctx context.Context, in *sysin.AttachmentClearKindInp) (err error)
+ }
+ ISysLog interface {
+ // Export 导出
+ Export(ctx context.Context, in *sysin.LogListInp) (err error)
+ // RealWrite 真实写入
+ RealWrite(ctx context.Context, log entity.SysLog) (err error)
+ // AutoLog 根据配置自动记录请求日志
+ AutoLog(ctx context.Context) error
+ // AnalysisLog 解析日志数据
+ AnalysisLog(ctx context.Context) entity.SysLog
+ // View 获取指定字典类型信息
+ View(ctx context.Context, in *sysin.LogViewInp) (res *sysin.LogViewModel, err error)
+ // Delete 删除
+ Delete(ctx context.Context, in *sysin.LogDeleteInp) (err error)
+ // List 列表
+ List(ctx context.Context, in *sysin.LogListInp) (list []*sysin.LogListModel, totalCount int, err error)
+ }
+ ISysLoginLog interface {
+ // Model 登录日志Orm模型
+ Model(ctx context.Context) *gdb.Model
+ // List 获取登录日志列表
+ List(ctx context.Context, in *sysin.LoginLogListInp) (list []*sysin.LoginLogListModel, totalCount int, err error)
+ // Export 导出登录日志
+ Export(ctx context.Context, in *sysin.LoginLogListInp) (err error)
+ // Delete 删除登录日志
+ Delete(ctx context.Context, in *sysin.LoginLogDeleteInp) (err error)
+ // View 获取登录日志指定信息
+ View(ctx context.Context, in *sysin.LoginLogViewInp) (res *sysin.LoginLogViewModel, err error)
+ // Push 推送登录日志
+ Push(ctx context.Context, in *sysin.LoginLogPushInp)
+ // RealWrite 真实写入
+ RealWrite(ctx context.Context, models entity.SysLoginLog) (err error)
}
ISysCron interface {
StartCron(ctx context.Context)
- Delete(ctx context.Context, in sysin.CronDeleteInp) (err error)
- Edit(ctx context.Context, in sysin.CronEditInp) (err error)
- Status(ctx context.Context, in sysin.CronStatusInp) (err error)
- MaxSort(ctx context.Context, in sysin.CronMaxSortInp) (res *sysin.CronMaxSortModel, err error)
- View(ctx context.Context, in sysin.CronViewInp) (res *sysin.CronViewModel, err error)
- List(ctx context.Context, in sysin.CronListInp) (list []*sysin.CronListModel, totalCount int, err error)
- OnlineExec(ctx context.Context, in sysin.OnlineExecInp) (err error)
- }
- ISysCronGroup interface {
- Delete(ctx context.Context, in sysin.CronGroupDeleteInp) (err error)
- Edit(ctx context.Context, in sysin.CronGroupEditInp) (err error)
- Status(ctx context.Context, in sysin.CronGroupStatusInp) (err error)
- MaxSort(ctx context.Context, in sysin.CronGroupMaxSortInp) (res *sysin.CronGroupMaxSortModel, err error)
- View(ctx context.Context, in sysin.CronGroupViewInp) (res *sysin.CronGroupViewModel, err error)
- List(ctx context.Context, in sysin.CronGroupListInp) (list []*sysin.CronGroupListModel, totalCount int, err error)
- Select(ctx context.Context, in sysin.CronGroupSelectInp) (res *sysin.CronGroupSelectModel, err error)
- }
- ISysDictData interface {
- Delete(ctx context.Context, in sysin.DictDataDeleteInp) error
- Edit(ctx context.Context, in sysin.DictDataEditInp) (err error)
- List(ctx context.Context, in sysin.DictDataListInp) (list []*sysin.DictDataListModel, totalCount int, err error)
- Select(ctx context.Context, in sysin.DataSelectInp) (list sysin.DataSelectModel, err error)
+ // Delete 删除
+ Delete(ctx context.Context, in *sysin.CronDeleteInp) (err error)
+ // Edit 修改/新增
+ Edit(ctx context.Context, in *sysin.CronEditInp) (err error)
+ // Status 更新状态
+ Status(ctx context.Context, in *sysin.CronStatusInp) (err error)
+ // MaxSort 最大排序
+ MaxSort(ctx context.Context, in *sysin.CronMaxSortInp) (res *sysin.CronMaxSortModel, err error)
+ // View 获取指定信息
+ View(ctx context.Context, in *sysin.CronViewInp) (res *sysin.CronViewModel, err error)
+ // List 获取列表
+ List(ctx context.Context, in *sysin.CronListInp) (list []*sysin.CronListModel, totalCount int, err error)
+ // OnlineExec 在线执行
+ OnlineExec(ctx context.Context, in *sysin.OnlineExecInp) (err error)
}
ISysGenCodes interface {
- Delete(ctx context.Context, in sysin.GenCodesDeleteInp) (err error)
- Edit(ctx context.Context, in sysin.GenCodesEditInp) (res *sysin.GenCodesEditModel, err error)
- Status(ctx context.Context, in sysin.GenCodesStatusInp) (err error)
- MaxSort(ctx context.Context, in sysin.GenCodesMaxSortInp) (res *sysin.GenCodesMaxSortModel, err error)
- View(ctx context.Context, in sysin.GenCodesViewInp) (res *sysin.GenCodesViewModel, err error)
- List(ctx context.Context, in sysin.GenCodesListInp) (list []*sysin.GenCodesListModel, totalCount int, err error)
- Selects(ctx context.Context, in sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error)
- TableSelect(ctx context.Context, in sysin.GenCodesTableSelectInp) (res []*sysin.GenCodesTableSelectModel, err error)
- ColumnSelect(ctx context.Context, in sysin.GenCodesColumnSelectInp) (res []*sysin.GenCodesColumnSelectModel, err error)
- ColumnList(ctx context.Context, in sysin.GenCodesColumnListInp) (res []*sysin.GenCodesColumnListModel, err error)
- Preview(ctx context.Context, in sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error)
- Build(ctx context.Context, in sysin.GenCodesBuildInp) (err error)
+ // Delete 删除
+ Delete(ctx context.Context, in *sysin.GenCodesDeleteInp) (err error)
+ // Edit 修改/新增
+ Edit(ctx context.Context, in *sysin.GenCodesEditInp) (res *sysin.GenCodesEditModel, err error)
+ // Status 更新部门状态
+ Status(ctx context.Context, in *sysin.GenCodesStatusInp) (err error)
+ // MaxSort 最大排序
+ MaxSort(ctx context.Context, in *sysin.GenCodesMaxSortInp) (res *sysin.GenCodesMaxSortModel, err error)
+ // View 获取指定字典类型信息
+ View(ctx context.Context, in *sysin.GenCodesViewInp) (res *sysin.GenCodesViewModel, err error)
+ // List 获取列表
+ List(ctx context.Context, in *sysin.GenCodesListInp) (list []*sysin.GenCodesListModel, totalCount int, err error)
+ // Selects 选项
+ Selects(ctx context.Context, in *sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error)
+ // TableSelect 表选项
+ TableSelect(ctx context.Context, in *sysin.GenCodesTableSelectInp) (res []*sysin.GenCodesTableSelectModel, err error)
+ // ColumnSelect 表字段选项
+ ColumnSelect(ctx context.Context, in *sysin.GenCodesColumnSelectInp) (res []*sysin.GenCodesColumnSelectModel, err error)
+ // ColumnList 表字段列表
+ ColumnList(ctx context.Context, in *sysin.GenCodesColumnListInp) (res []*sysin.GenCodesColumnListModel, err error)
+ // Preview 生成预览
+ Preview(ctx context.Context, in *sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error)
+ // Build 提交生成
+ Build(ctx context.Context, in *sysin.GenCodesBuildInp) (err error)
+ }
+ ISysCurdDemo interface {
+ // Model 生成演示ORM模型
+ Model(ctx context.Context, option ...*handler.Option) *gdb.Model
+ // List 获取生成演示列表
+ List(ctx context.Context, in *sysin.CurdDemoListInp) (list []*sysin.CurdDemoListModel, totalCount int, err error)
+ // Export 导出生成演示
+ Export(ctx context.Context, in *sysin.CurdDemoListInp) (err error)
+ // Edit 修改/新增生成演示
+ Edit(ctx context.Context, in *sysin.CurdDemoEditInp) (err error)
+ // Delete 删除生成演示
+ Delete(ctx context.Context, in *sysin.CurdDemoDeleteInp) (err error)
+ // MaxSort 获取生成演示最大排序
+ MaxSort(ctx context.Context, in *sysin.CurdDemoMaxSortInp) (res *sysin.CurdDemoMaxSortModel, err error)
+ // View 获取生成演示指定信息
+ View(ctx context.Context, in *sysin.CurdDemoViewInp) (res *sysin.CurdDemoViewModel, err error)
+ // Status 更新生成演示状态
+ Status(ctx context.Context, in *sysin.CurdDemoStatusInp) (err error)
+ // Switch 更新生成演示开关
+ Switch(ctx context.Context, in *sysin.CurdDemoSwitchInp) (err error)
+ }
+ ISysDictData interface {
+ // Delete 删除
+ Delete(ctx context.Context, in *sysin.DictDataDeleteInp) error
+ // Edit 修改/新增
+ Edit(ctx context.Context, in *sysin.DictDataEditInp) (err error)
+ // List 获取列表
+ List(ctx context.Context, in *sysin.DictDataListInp) (list []*sysin.DictDataListModel, totalCount int, err error)
+ // Select 获取列表
+ Select(ctx context.Context, in *sysin.DataSelectInp) (list sysin.DataSelectModel, err error)
+ }
+ ISysProvinces interface {
+ // Tree 关系树选项列表
+ Tree(ctx context.Context) (list []*sysin.ProvincesTree, err error)
+ // Delete 删除省市区数据
+ Delete(ctx context.Context, in *sysin.ProvincesDeleteInp) (err error)
+ // Edit 修改/新增省市区数据
+ Edit(ctx context.Context, in *sysin.ProvincesEditInp) (err error)
+ // Status 更新省市区状态
+ Status(ctx context.Context, in *sysin.ProvincesStatusInp) (err error)
+ // MaxSort 最大排序
+ MaxSort(ctx context.Context, in *sysin.ProvincesMaxSortInp) (res *sysin.ProvincesMaxSortModel, err error)
+ // View 获取省市区信息
+ View(ctx context.Context, in *sysin.ProvincesViewInp) (res *sysin.ProvincesViewModel, err error)
+ // List 获取列表
+ List(ctx context.Context, in *sysin.ProvincesListInp) (list []*sysin.ProvincesListModel, totalCount int, err error)
+ // ChildrenList 获取省市区下级列表
+ ChildrenList(ctx context.Context, in *sysin.ProvincesChildrenListInp) (list []*sysin.ProvincesChildrenListModel, totalCount int, err error)
+ // UniqueId 获取省市区下级列表
+ UniqueId(ctx context.Context, in *sysin.ProvincesUniqueIdInp) (res *sysin.ProvincesUniqueIdModel, err error)
+ // Select 省市区选项
+ Select(ctx context.Context, in *sysin.ProvincesSelectInp) (res *sysin.ProvincesSelectModel, err error)
+ }
+ ISysServeLicense interface {
+ // Model 服务许可证ORM模型
+ Model(ctx context.Context, option ...*handler.Option) *gdb.Model
+ // List 获取服务许可证列表
+ List(ctx context.Context, in *sysin.ServeLicenseListInp) (list []*sysin.ServeLicenseListModel, totalCount int, err error)
+ // Export 导出服务许可证
+ Export(ctx context.Context, in *sysin.ServeLicenseListInp) (err error)
+ // Edit 修改/新增服务许可证
+ Edit(ctx context.Context, in *sysin.ServeLicenseEditInp) (err error)
+ // Delete 删除服务许可证
+ Delete(ctx context.Context, in *sysin.ServeLicenseDeleteInp) (err error)
+ // View 获取服务许可证指定信息
+ View(ctx context.Context, in *sysin.ServeLicenseViewInp) (res *sysin.ServeLicenseViewModel, err error)
+ // Status 更新服务许可证状态
+ Status(ctx context.Context, in *sysin.ServeLicenseStatusInp) (err error)
+ // AssignRouter 分配服务许可证路由
+ AssignRouter(ctx context.Context, in *sysin.ServeLicenseAssignRouterInp) (err error)
+ }
+ ISysSmsLog interface {
+ // Delete 删除
+ Delete(ctx context.Context, in *sysin.SmsLogDeleteInp) (err error)
+ // Edit 修改/新增
+ Edit(ctx context.Context, in *sysin.SmsLogEditInp) (err error)
+ // Status 更新短信状态
+ Status(ctx context.Context, in *sysin.SmsLogStatusInp) (err error)
+ // View 获取指定字典类型信息
+ View(ctx context.Context, in *sysin.SmsLogViewInp) (res *sysin.SmsLogViewModel, err error)
+ // List 获取列表
+ List(ctx context.Context, in *sysin.SmsLogListInp) (list []*sysin.SmsLogListModel, totalCount int, err error)
+ // SendCode 发送验证码
+ SendCode(ctx context.Context, in *sysin.SendCodeInp) (err error)
+ // GetTemplate 获取指定短信模板
+ GetTemplate(ctx context.Context, template string, config *model.SmsConfig) (val string, err error)
+ // AllowSend 是否允许发送
+ AllowSend(ctx context.Context, models *entity.SysSmsLog, config *model.SmsConfig) (err error)
+ // VerifyCode 效验验证码
+ VerifyCode(ctx context.Context, in *sysin.VerifyCodeInp) (err error)
+ }
+ ISysBlacklist interface {
+ // Delete 删除
+ Delete(ctx context.Context, in *sysin.BlacklistDeleteInp) (err error)
+ // Edit 修改/新增
+ Edit(ctx context.Context, in *sysin.BlacklistEditInp) (err error)
+ // Status 更新部门状态
+ Status(ctx context.Context, in *sysin.BlacklistStatusInp) (err error)
+ // View 获取指定字典类型信息
+ View(ctx context.Context, in *sysin.BlacklistViewInp) (res *sysin.BlacklistViewModel, err error)
+ // List 获取列表
+ List(ctx context.Context, in *sysin.BlacklistListInp) (list []*sysin.BlacklistListModel, totalCount int, err error)
+ // VariableLoad 变化加载
+ VariableLoad(ctx context.Context, err error)
+ // Load 加载黑名单
+ Load(ctx context.Context)
+ }
+ ISysCronGroup interface {
+ // Delete 删除
+ Delete(ctx context.Context, in *sysin.CronGroupDeleteInp) (err error)
+ // Edit 修改/新增
+ Edit(ctx context.Context, in *sysin.CronGroupEditInp) (err error)
+ // Status 更新状态
+ Status(ctx context.Context, in *sysin.CronGroupStatusInp) (err error)
+ // MaxSort 最大排序
+ MaxSort(ctx context.Context, in *sysin.CronGroupMaxSortInp) (res *sysin.CronGroupMaxSortModel, err error)
+ // View 获取指定信息
+ View(ctx context.Context, in *sysin.CronGroupViewInp) (res *sysin.CronGroupViewModel, err error)
+ // List 获取列表
+ List(ctx context.Context, in *sysin.CronGroupListInp) (list []*sysin.CronGroupListModel, totalCount int, err error)
+ // Select 选项
+ Select(ctx context.Context, in *sysin.CronGroupSelectInp) (res *sysin.CronGroupSelectModel, err error)
+ }
+ ISysEmsLog interface {
+ // Delete 删除
+ Delete(ctx context.Context, in *sysin.EmsLogDeleteInp) (err error)
+ // Edit 修改/新增
+ Edit(ctx context.Context, in *sysin.EmsLogEditInp) (err error)
+ // Status 更新部门状态
+ Status(ctx context.Context, in *sysin.EmsLogStatusInp) (err error)
+ // View 获取指定字典类型信息
+ View(ctx context.Context, in *sysin.EmsLogViewInp) (res *sysin.EmsLogViewModel, err error)
+ // List 获取列表
+ List(ctx context.Context, in *sysin.EmsLogListInp) (list []*sysin.EmsLogListModel, totalCount int, err error)
+ // Send 发送邮件
+ Send(ctx context.Context, in *sysin.SendEmsInp) (err error)
+ // GetTemplate 获取指定邮件模板
+ GetTemplate(ctx context.Context, template string, config *model.EmailConfig) (val string, err error)
+ // AllowSend 是否允许发送
+ AllowSend(ctx context.Context, models *entity.SysEmsLog, config *model.EmailConfig) (err error)
+ // VerifyCode 效验验证码
+ VerifyCode(ctx context.Context, in *sysin.VerifyEmsCodeInp) (err error)
+ }
+ ISysAddonsConfig interface {
+ // GetConfigByGroup 获取指定分组的配置
+ GetConfigByGroup(ctx context.Context, in *sysin.GetAddonsConfigInp) (res *sysin.GetAddonsConfigModel, err error)
+ // ConversionType 转换类型
+ ConversionType(ctx context.Context, models *entity.SysAddonsConfig) (value interface{}, err error)
+ // UpdateConfigByGroup 更新指定分组的配置
+ UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateAddonsConfigInp) (err error)
+ }
+ ISysDictType interface {
+ // Tree 树
+ Tree(ctx context.Context) (list []*sysin.DictTypeTree, err error)
+ // Delete 删除
+ Delete(ctx context.Context, in *sysin.DictTypeDeleteInp) (err error)
+ // Edit 修改/新增
+ Edit(ctx context.Context, in *sysin.DictTypeEditInp) (err error)
+ // TreeSelect 获取类型关系树选项
+ TreeSelect(ctx context.Context, in *sysin.DictTreeSelectInp) (list []*sysin.DictTypeTree, err error)
}
)
var (
localSysAddonsConfig ISysAddonsConfig
- localSysServeLog ISysServeLog
- localSysLog ISysLog
- localSysConfig ISysConfig
- localSysCron ISysCron
- localSysCronGroup ISysCronGroup
- localSysDictData ISysDictData
- localSysGenCodes ISysGenCodes
localSysDictType ISysDictType
localSysEmsLog ISysEmsLog
- localSysProvinces ISysProvinces
- localSysSmsLog ISysSmsLog
localSysAddons ISysAddons
localSysAttachment ISysAttachment
- localSysBlacklist ISysBlacklist
- localSysCurdDemo ISysCurdDemo
+ localSysConfig ISysConfig
+ localSysServeLog ISysServeLog
+ localSysCron ISysCron
+ localSysGenCodes ISysGenCodes
+ localSysLog ISysLog
localSysLoginLog ISysLoginLog
+ localSysBlacklist ISysBlacklist
+ localSysCronGroup ISysCronGroup
+ localSysCurdDemo ISysCurdDemo
+ localSysDictData ISysDictData
+ localSysProvinces ISysProvinces
+ localSysServeLicense ISysServeLicense
+ localSysSmsLog ISysSmsLog
)
-func SysBlacklist() ISysBlacklist {
- if localSysBlacklist == nil {
- panic("implement not found for interface ISysBlacklist, forgot register?")
- }
- return localSysBlacklist
-}
-
-func RegisterSysBlacklist(i ISysBlacklist) {
- localSysBlacklist = i
-}
-
-func SysCurdDemo() ISysCurdDemo {
- if localSysCurdDemo == nil {
- panic("implement not found for interface ISysCurdDemo, forgot register?")
- }
- return localSysCurdDemo
-}
-
-func RegisterSysCurdDemo(i ISysCurdDemo) {
- localSysCurdDemo = i
-}
-
-func SysLoginLog() ISysLoginLog {
- if localSysLoginLog == nil {
- panic("implement not found for interface ISysLoginLog, forgot register?")
- }
- return localSysLoginLog
-}
-
-func RegisterSysLoginLog(i ISysLoginLog) {
- localSysLoginLog = i
-}
-
-func SysProvinces() ISysProvinces {
- if localSysProvinces == nil {
- panic("implement not found for interface ISysProvinces, forgot register?")
- }
- return localSysProvinces
-}
-
-func RegisterSysProvinces(i ISysProvinces) {
- localSysProvinces = i
-}
-
-func SysSmsLog() ISysSmsLog {
- if localSysSmsLog == nil {
- panic("implement not found for interface ISysSmsLog, forgot register?")
- }
- return localSysSmsLog
-}
-
-func RegisterSysSmsLog(i ISysSmsLog) {
- localSysSmsLog = i
-}
-
func SysAddons() ISysAddons {
if localSysAddons == nil {
panic("implement not found for interface ISysAddons, forgot register?")
@@ -281,15 +374,15 @@ func RegisterSysAttachment(i ISysAttachment) {
localSysAttachment = i
}
-func SysAddonsConfig() ISysAddonsConfig {
- if localSysAddonsConfig == nil {
- panic("implement not found for interface ISysAddonsConfig, forgot register?")
+func SysConfig() ISysConfig {
+ if localSysConfig == nil {
+ panic("implement not found for interface ISysConfig, forgot register?")
}
- return localSysAddonsConfig
+ return localSysConfig
}
-func RegisterSysAddonsConfig(i ISysAddonsConfig) {
- localSysAddonsConfig = i
+func RegisterSysConfig(i ISysConfig) {
+ localSysConfig = i
}
func SysServeLog() ISysServeLog {
@@ -303,26 +396,15 @@ func RegisterSysServeLog(i ISysServeLog) {
localSysServeLog = i
}
-func SysCronGroup() ISysCronGroup {
- if localSysCronGroup == nil {
- panic("implement not found for interface ISysCronGroup, forgot register?")
+func SysCron() ISysCron {
+ if localSysCron == nil {
+ panic("implement not found for interface ISysCron, forgot register?")
}
- return localSysCronGroup
+ return localSysCron
}
-func RegisterSysCronGroup(i ISysCronGroup) {
- localSysCronGroup = i
-}
-
-func SysDictData() ISysDictData {
- if localSysDictData == nil {
- panic("implement not found for interface ISysDictData, forgot register?")
- }
- return localSysDictData
-}
-
-func RegisterSysDictData(i ISysDictData) {
- localSysDictData = i
+func RegisterSysCron(i ISysCron) {
+ localSysCron = i
}
func SysGenCodes() ISysGenCodes {
@@ -347,26 +429,103 @@ func RegisterSysLog(i ISysLog) {
localSysLog = i
}
-func SysConfig() ISysConfig {
- if localSysConfig == nil {
- panic("implement not found for interface ISysConfig, forgot register?")
+func SysLoginLog() ISysLoginLog {
+ if localSysLoginLog == nil {
+ panic("implement not found for interface ISysLoginLog, forgot register?")
}
- return localSysConfig
+ return localSysLoginLog
}
-func RegisterSysConfig(i ISysConfig) {
- localSysConfig = i
+func RegisterSysLoginLog(i ISysLoginLog) {
+ localSysLoginLog = i
}
-func SysCron() ISysCron {
- if localSysCron == nil {
- panic("implement not found for interface ISysCron, forgot register?")
+func SysSmsLog() ISysSmsLog {
+ if localSysSmsLog == nil {
+ panic("implement not found for interface ISysSmsLog, forgot register?")
}
- return localSysCron
+ return localSysSmsLog
}
-func RegisterSysCron(i ISysCron) {
- localSysCron = i
+func RegisterSysSmsLog(i ISysSmsLog) {
+ localSysSmsLog = i
+}
+
+func SysBlacklist() ISysBlacklist {
+ if localSysBlacklist == nil {
+ panic("implement not found for interface ISysBlacklist, forgot register?")
+ }
+ return localSysBlacklist
+}
+
+func RegisterSysBlacklist(i ISysBlacklist) {
+ localSysBlacklist = i
+}
+
+func SysCronGroup() ISysCronGroup {
+ if localSysCronGroup == nil {
+ panic("implement not found for interface ISysCronGroup, forgot register?")
+ }
+ return localSysCronGroup
+}
+
+func RegisterSysCronGroup(i ISysCronGroup) {
+ localSysCronGroup = i
+}
+
+func SysCurdDemo() ISysCurdDemo {
+ if localSysCurdDemo == nil {
+ panic("implement not found for interface ISysCurdDemo, forgot register?")
+ }
+ return localSysCurdDemo
+}
+
+func RegisterSysCurdDemo(i ISysCurdDemo) {
+ localSysCurdDemo = i
+}
+
+func SysDictData() ISysDictData {
+ if localSysDictData == nil {
+ panic("implement not found for interface ISysDictData, forgot register?")
+ }
+ return localSysDictData
+}
+
+func RegisterSysDictData(i ISysDictData) {
+ localSysDictData = i
+}
+
+func SysProvinces() ISysProvinces {
+ if localSysProvinces == nil {
+ panic("implement not found for interface ISysProvinces, forgot register?")
+ }
+ return localSysProvinces
+}
+
+func RegisterSysProvinces(i ISysProvinces) {
+ localSysProvinces = i
+}
+
+func SysServeLicense() ISysServeLicense {
+ if localSysServeLicense == nil {
+ panic("implement not found for interface ISysServeLicense, forgot register?")
+ }
+ return localSysServeLicense
+}
+
+func RegisterSysServeLicense(i ISysServeLicense) {
+ localSysServeLicense = i
+}
+
+func SysAddonsConfig() ISysAddonsConfig {
+ if localSysAddonsConfig == nil {
+ panic("implement not found for interface ISysAddonsConfig, forgot register?")
+ }
+ return localSysAddonsConfig
+}
+
+func RegisterSysAddonsConfig(i ISysAddonsConfig) {
+ localSysAddonsConfig = i
}
func SysDictType() ISysDictType {
diff --git a/server/internal/service/tcpclient.go b/server/internal/service/tcpclient.go
index fd094fa..7f9d83e 100644
--- a/server/internal/service/tcpclient.go
+++ b/server/internal/service/tcpclient.go
@@ -7,42 +7,35 @@ package service
import (
"context"
+ "hotgo/api/servmsg"
+ "hotgo/internal/library/network/tcp"
)
type (
IAuthClient interface {
+ Instance() *tcp.Client
Start(ctx context.Context)
Stop(ctx context.Context)
- IsLogin() bool
- OnResponseAuthSummary(ctx context.Context, args ...interface{})
+ OnResponseAuthSummary(ctx context.Context, req *servmsg.AuthSummaryRes)
+ OnResponseExampleHello(ctx context.Context, req *servmsg.ExampleHelloRes)
}
ICronClient interface {
+ Instance() *tcp.Client
Start(ctx context.Context)
Stop(ctx context.Context)
- IsLogin() bool
- OnCronDelete(ctx context.Context, args ...interface{})
- OnCronEdit(ctx context.Context, args ...interface{})
- OnCronStatus(ctx context.Context, args ...interface{})
- OnCronOnlineExec(ctx context.Context, args ...interface{})
+ OnCronDelete(ctx context.Context, req *servmsg.CronDeleteReq) (res *servmsg.CronDeleteRes, err error)
+ OnCronEdit(ctx context.Context, req *servmsg.CronEditReq) (res *servmsg.CronEditRes, err error)
+ OnCronStatus(ctx context.Context, req *servmsg.CronStatusReq) (res *servmsg.CronStatusRes, err error)
+ OnCronOnlineExec(ctx context.Context, req *servmsg.CronOnlineExecReq) (res *servmsg.CronOnlineExecRes, err error)
+ DefaultInterceptor(ctx context.Context, msg *tcp.Message) (err error)
}
)
var (
- localCronClient ICronClient
localAuthClient IAuthClient
+ localCronClient ICronClient
)
-func AuthClient() IAuthClient {
- if localAuthClient == nil {
- panic("implement not found for interface IAuthClient, forgot register?")
- }
- return localAuthClient
-}
-
-func RegisterAuthClient(i IAuthClient) {
- localAuthClient = i
-}
-
func CronClient() ICronClient {
if localCronClient == nil {
panic("implement not found for interface ICronClient, forgot register?")
@@ -53,3 +46,14 @@ func CronClient() ICronClient {
func RegisterCronClient(i ICronClient) {
localCronClient = i
}
+
+func AuthClient() IAuthClient {
+ if localAuthClient == nil {
+ panic("implement not found for interface IAuthClient, forgot register?")
+ }
+ return localAuthClient
+}
+
+func RegisterAuthClient(i IAuthClient) {
+ localAuthClient = i
+}
diff --git a/server/internal/service/tcpserver.go b/server/internal/service/tcpserver.go
index 31f47db..aaa4657 100644
--- a/server/internal/service/tcpserver.go
+++ b/server/internal/service/tcpserver.go
@@ -7,18 +7,24 @@ package service
import (
"context"
- "hotgo/internal/model/input/msgin"
+ "hotgo/api/servmsg"
+ "hotgo/internal/library/network/tcp"
)
type (
ITCPServer interface {
- OnAuthSummary(ctx context.Context, args ...interface{})
- CronDelete(ctx context.Context, in *msgin.CronDelete) (err error)
- CronEdit(ctx context.Context, in *msgin.CronEdit) (err error)
- CronStatus(ctx context.Context, in *msgin.CronStatus) (err error)
- CronOnlineExec(ctx context.Context, in *msgin.CronOnlineExec) (err error)
+ OnAuthSummary(ctx context.Context, req *servmsg.AuthSummaryReq)
+ CronDelete(ctx context.Context, in *servmsg.CronDeleteReq) (err error)
+ CronEdit(ctx context.Context, in *servmsg.CronEditReq) (err error)
+ CronStatus(ctx context.Context, in *servmsg.CronStatusReq) (err error)
+ CronOnlineExec(ctx context.Context, in *servmsg.CronOnlineExecReq) (err error)
+ OnExampleHello(ctx context.Context, req *servmsg.ExampleHelloReq)
+ OnExampleRPCHello(ctx context.Context, req *servmsg.ExampleRPCHelloReq) (res *servmsg.ExampleRPCHelloRes, err error)
+ Instance() *tcp.Server
Start(ctx context.Context)
Stop(ctx context.Context)
+ DefaultInterceptor(ctx context.Context, msg *tcp.Message) (err error)
+ PreFilterInterceptor(ctx context.Context, msg *tcp.Message) (err error)
}
)
diff --git a/server/internal/websocket/client.go b/server/internal/websocket/client.go
index 022ed15..c5d4297 100644
--- a/server/internal/websocket/client.go
+++ b/server/internal/websocket/client.go
@@ -81,9 +81,7 @@ func (c *Client) read() {
}
}()
- defer func() {
- c.close()
- }()
+ defer c.close()
for {
_, message, err := c.Socket.ReadMessage()
diff --git a/server/internal/websocket/client_manager.go b/server/internal/websocket/client_manager.go
index 71fd1ba..d0b513a 100644
--- a/server/internal/websocket/client_manager.go
+++ b/server/internal/websocket/client_manager.go
@@ -286,7 +286,7 @@ func (manager *ClientManager) start() {
}
}
case <-manager.closeSignal:
- g.Log().Info(ctxManager, "websocket closeSignal quit..")
+ g.Log().Debug(ctxManager, "websocket closeSignal quit..")
return
}
}
diff --git a/server/internal/websocket/init.go b/server/internal/websocket/init.go
index 65233e6..e0296a3 100644
--- a/server/internal/websocket/init.go
+++ b/server/internal/websocket/init.go
@@ -19,14 +19,7 @@ var (
ctxManager context.Context // 主上下文
clientManager = NewClientManager() // 客户端管理
routers = make(map[string]EventHandler) // 消息路由
- msgGo = grpool.New(20)
- upGrader = websocket.Upgrader{
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- CheckOrigin: func(r *http.Request) bool {
- return true
- },
- }
+ msgGo = grpool.New(20) // 消息处理协程池
)
// Start 启动
@@ -44,6 +37,13 @@ func Stop() {
// WsPage ws入口
func WsPage(r *ghttp.Request) {
+ upGrader := websocket.Upgrader{
+ ReadBufferSize: 1024,
+ WriteBufferSize: 1024,
+ CheckOrigin: func(r *http.Request) bool {
+ return true
+ },
+ }
conn, err := upGrader.Upgrade(r.Response.ResponseWriter, r.Request, nil)
if err != nil {
return
diff --git a/server/manifest/config/config.example.yaml b/server/manifest/config/config.example.yaml
index 7d0ea14..ced6812 100644
--- a/server/manifest/config/config.example.yaml
+++ b/server/manifest/config/config.example.yaml
@@ -21,23 +21,16 @@ hotgo:
switch: true # 日志开关,默认为true
queue: true # 是否启用队列,启用时需要配置队列信息,默认为true
levelFormat: ["WARN", "ERRO", "FATA", "PANI"] # 需要记录的等级
- # admin
- admin:
- superIds: [ 1 ] # 后台超管账号ID,通过ID验证超管
- superRoleKey: "super" # 超管角色唯一标识符,通过角色验证超管
- defaultPage: 10 # 列表分页默认加载数量
- defaultPageSize: 1 # 列表分页默认加载页码
- maxSortIncrement: 10 # 最大排序值增量
-# gf配置
+# gf配置,配置参考:https://goframe.org/pages/viewpage.action?pageId=44449486
server:
- address: ":8000"
- openapiPath: "/api.json"
- swaggerPath: "/swagger"
- serverRoot: "resource/public"
- DumpRouterMap: false
- logPath: "logs/server"
+ address: ":8000" # 本地监听地址。默认":8000",多个地址以","号分隔。例如:"192.168.2.3:8000,10.0.3.10:8001"
+ openapiPath: "/api.json" # OpenAPI接口文档地址
+ swaggerPath: "/swagger" # 内置SwaggerUI展示地址
+ serverRoot: "resource/public" # 静态文件服务的目录根路径,配置时自动开启静态文件服务。
+ DumpRouterMap: false # 是否在Server启动时打印所有的路由列表。
+ logPath: "logs/server" # 服务日志保存路径
ErrorStack: true # 当Server捕获到异常时是否记录堆栈信息到日志中。默认为true
ErrorLogEnabled: true # 是否记录异常日志信息到日志中。默认为true
errorLogPattern: "error/{Y-m-d}.log" # 异常错误日志文件格式。默认为"error-{Ymd}.log"
@@ -45,7 +38,7 @@ server:
accessLogPattern: "access/{Y-m-d}.log" # 访问日志文件格式。默认为"access-{Ymd}.log"
maxHeaderBytes: "100KB" # 请求头大小限制,请求头包括客户端提交的Cookie数据,默认设置为100KB
clientMaxBodySize: "200MB" # 客户端提交的Body大小限制,同时也影响文件上传大小,默认设置为200MB
- serverAgent: "HG HTTP Server"
+ serverAgent: "HG HTTP Server" # 服务端Agent信息。默认为"HG HTTP Server"
# PProf配置
pprofEnabled: true # 是否开启PProf性能调试特性。默认为false
pprofPattern: "/pprof" # 开启PProf时有效,表示PProf特性的页面访问路径,对当前Server绑定的所有域名有效。
@@ -115,7 +108,7 @@ logger:
<<: *defaultLogger
-# 模板配置
+# Viewer. 配置参考:https://goframe.org/pages/viewpage.action?pageId=1114335
viewer:
paths: "resource/template"
defaultFile: "index.html"
@@ -204,9 +197,9 @@ queue:
segmentLimit: 3000 # 每个topic最大分片数据文件数量,超出部分将会丢弃
#redis,默认使用全局redis运行队列
redis:
- timeout: 0 # 队列超时时间(s) ,0为永不超时,当队列一直没有被消费到达超时时间则队列会被销毁
+ timeout: 0 # 队列超时时间以秒为单位,0表示永不超时。如果队列在设定的超时时间内没有被消费,则会被销毁
rocketmq:
- address: "127.0.0.1:9876" # brocker地址+端口
+ address: "127.0.0.1:9876" # broker地址+端口
logLevel: "all" # 系统日志级别,可选:all|close|debug|info|warn|error|fatal
kafka:
address: "127.0.0.1:9092" # kafka地址+端口
@@ -215,7 +208,7 @@ queue:
multiConsumer: true # 是否支持创建多个消费者
-# Redis
+# Redis. 配置参考:https://goframe.org/pages/viewpage.action?pageId=1114217
redis:
default:
address: "127.0.0.1:6379"
@@ -224,7 +217,7 @@ redis:
idleTimeout: "20"
-# Database.
+# Database. 配置参考:https://goframe.org/pages/viewpage.action?pageId=1114245
database:
logger:
level: "all"
@@ -237,8 +230,8 @@ database:
# 链路追踪
jaeger:
- switch: false # 链路追踪开关,默认为false
- endpoint: "127.0.0.1:6831" # jaeger-agent上报地址
+ switch: false # 链路追踪开关,可选:true|false,默认为false
+ endpoint: "127.0.0.1:6831" # jaeger-agent上报地址
# 生成代码
@@ -257,7 +250,7 @@ hggen:
isAddon: false # 是否为插件模板 false|true
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" # 主要业务生成路径
inputPath: "./internal/model/input/sysin" # 表单过滤器生成路径
@@ -271,7 +264,7 @@ hggen:
isAddon: true # 是否为插件模板 false|true
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" # 主要业务生成路径
inputPath: "./addons/{$name}/model/input/sysin" # 表单过滤器生成路径
diff --git a/server/resource/generate/default/addon/controller/admin/sys/config.go.template b/server/resource/generate/default/addon/controller/admin/sys/config.go.template
index bc6ebc4..25b4af7 100644
--- a/server/resource/generate/default/addon/controller/admin/sys/config.go.template
+++ b/server/resource/generate/default/addon/controller/admin/sys/config.go.template
@@ -7,11 +7,8 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
- "hotgo/addons/@{.name}/model/input/sysin"
+ "hotgo/addons/@{.name}/api/admin/config"
"hotgo/addons/@{.name}/service"
- "hotgo/api/admin/config"
- isysin "hotgo/internal/model/input/sysin"
)
var (
@@ -22,25 +19,15 @@ type cConfig struct{}
// GetConfig 获取指定分组的配置
func (c *cConfig) GetConfig(ctx context.Context, req *config.GetReq) (res *config.GetRes, err error) {
- var in sysin.GetConfigInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- data, err := service.SysConfig().GetConfigByGroup(ctx, in)
+ data, err := service.SysConfig().GetConfigByGroup(ctx, &req.GetConfigInp)
res = new(config.GetRes)
- res.GetConfigModel = (*isysin.GetConfigModel)(data)
+ res.GetConfigModel = data
return
}
// UpdateConfig 更新指定分组的配置
func (c *cConfig) UpdateConfig(ctx context.Context, req *config.UpdateReq) (res *config.UpdateRes, err error) {
- var in sysin.UpdateConfigInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- err = service.SysConfig().UpdateConfigByGroup(ctx, in)
+ err = service.SysConfig().UpdateConfigByGroup(ctx, &req.UpdateConfigInp)
return
}
diff --git a/server/resource/generate/default/addon/controller/admin/sys/index.go.template b/server/resource/generate/default/addon/controller/admin/sys/index.go.template
index 5ed3bed..ed5d9f2 100644
--- a/server/resource/generate/default/addon/controller/admin/sys/index.go.template
+++ b/server/resource/generate/default/addon/controller/admin/sys/index.go.template
@@ -7,11 +7,8 @@ package sys
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/@{.name}/api/admin/index"
- "hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
- "hotgo/utility/validate"
)
var (
@@ -22,16 +19,7 @@ type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
- var in sysin.IndexTestInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return nil, err
- }
-
- data, err := service.SysIndex().Test(ctx, in)
+ data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
diff --git a/server/resource/generate/default/addon/controller/api/index.go.template b/server/resource/generate/default/addon/controller/api/index.go.template
index dd422ec..1295fbd 100644
--- a/server/resource/generate/default/addon/controller/api/index.go.template
+++ b/server/resource/generate/default/addon/controller/api/index.go.template
@@ -7,11 +7,8 @@ package api
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/@{.name}/api/api/index"
- "hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
- "hotgo/utility/validate"
)
var (
@@ -22,16 +19,7 @@ type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
- var in sysin.IndexTestInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return nil, err
- }
-
- data, err := service.SysIndex().Test(ctx, in)
+ data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
@@ -40,3 +28,4 @@ func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestR
res.IndexTestModel = data
return
}
+
diff --git a/server/resource/generate/default/addon/controller/home/index.go.template b/server/resource/generate/default/addon/controller/home/index.go.template
index bc4240f..abd86cb 100644
--- a/server/resource/generate/default/addon/controller/home/index.go.template
+++ b/server/resource/generate/default/addon/controller/home/index.go.template
@@ -8,13 +8,10 @@ package home
import (
"context"
"github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/@{.name}/api/home/index"
- "hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
"hotgo/internal/model"
isc "hotgo/internal/service"
- "hotgo/utility/validate"
)
// Index 基础
@@ -23,16 +20,7 @@ var Index = cIndex{}
type cIndex struct{}
func (a *cIndex) Index(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
- var in sysin.IndexTestInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return nil, err
- }
-
- data, err := service.SysIndex().Test(ctx, in)
+ data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
diff --git a/server/resource/generate/default/addon/controller/websocket/index.go.template b/server/resource/generate/default/addon/controller/websocket/index.go.template
index cf0b955..0d3ed85 100644
--- a/server/resource/generate/default/addon/controller/websocket/index.go.template
+++ b/server/resource/generate/default/addon/controller/websocket/index.go.template
@@ -7,11 +7,8 @@ package websocket
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/@{.name}/api/websocket/index"
- "hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
- "hotgo/utility/validate"
)
var (
@@ -22,16 +19,7 @@ type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
- var in sysin.IndexTestInp
- if err = gconv.Scan(req, &in); err != nil {
- return nil, err
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return nil, err
- }
-
- data, err := service.SysIndex().Test(ctx, in)
+ data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
diff --git a/server/resource/generate/default/addon/crons/crons.go.template b/server/resource/generate/default/addon/crons/crons.go.template
index cbcbe05..e20bf6c 100644
--- a/server/resource/generate/default/addon/crons/crons.go.template
+++ b/server/resource/generate/default/addon/crons/crons.go.template
@@ -1,3 +1,8 @@
+// Package crons
+// @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 crons
// 定时任务.
diff --git a/server/resource/generate/default/addon/logic/sys/config.go.template b/server/resource/generate/default/addon/logic/sys/config.go.template
index 72775e8..8a3db25 100644
--- a/server/resource/generate/default/addon/logic/sys/config.go.template
+++ b/server/resource/generate/default/addon/logic/sys/config.go.template
@@ -12,7 +12,6 @@ import (
"hotgo/addons/@{.name}/model"
"hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
- isysin "hotgo/internal/model/input/sysin"
isc "hotgo/internal/service"
)
@@ -28,22 +27,22 @@ func init() {
// GetBasic 获取基础配置
func (s *sSysConfig) GetBasic(ctx context.Context) (conf *model.BasicConfig, err error) {
- var in = isysin.GetAddonsConfigInp{AddonName: global.GetSkeleton().Name, Group: "basic"}
- models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, in)
+ var in sysin.GetConfigInp
+ in.GetAddonsConfigInp.AddonName = global.GetSkeleton().Name
+ in.GetAddonsConfigInp.Group = "basic"
+ models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, &in.GetAddonsConfigInp)
if err != nil {
return
}
- if err = gconv.Struct(models.List, &conf); err != nil {
- return
- }
+ err = gconv.Struct(models.List, &conf)
return
}
// GetConfigByGroup 获取指定分组配置
-func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error) {
+func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in *sysin.GetConfigInp) (res *sysin.GetConfigModel, err error) {
in.GetAddonsConfigInp.AddonName = global.GetSkeleton().Name
- models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, in.GetAddonsConfigInp)
+ models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, &in.GetAddonsConfigInp)
if err != nil {
return
}
@@ -54,7 +53,7 @@ func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp
}
// UpdateConfigByGroup 更新指定分组的配置
-func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error {
+func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateConfigInp) error {
in.UpdateAddonsConfigInp.AddonName = global.GetSkeleton().Name
- return isc.SysAddonsConfig().UpdateConfigByGroup(ctx, in.UpdateAddonsConfigInp)
+ return isc.SysAddonsConfig().UpdateConfigByGroup(ctx, &in.UpdateAddonsConfigInp)
}
diff --git a/server/resource/generate/default/addon/logic/sys/index.go.template b/server/resource/generate/default/addon/logic/sys/index.go.template
index 577ed8a..3b585d9 100644
--- a/server/resource/generate/default/addon/logic/sys/index.go.template
+++ b/server/resource/generate/default/addon/logic/sys/index.go.template
@@ -26,7 +26,7 @@ func init() {
}
// Test 测试
-func (s *sSysIndex) Test(ctx context.Context, in sysin.IndexTestInp) (res *sysin.IndexTestModel, err error) {
+func (s *sSysIndex) Test(ctx context.Context, in *sysin.IndexTestInp) (res *sysin.IndexTestModel, err error) {
res = new(sysin.IndexTestModel)
res.Name = in.Name
res.Module = fmt.Sprintf("当前插件模块是:%s,当前应用模块是:%s", global.GetSkeleton().Name, contexts.Get(ctx).Module)
diff --git a/server/resource/generate/default/addon/queues/queues.go.template b/server/resource/generate/default/addon/queues/queues.go.template
index 892a3d2..9f2e7eb 100644
--- a/server/resource/generate/default/addon/queues/queues.go.template
+++ b/server/resource/generate/default/addon/queues/queues.go.template
@@ -1,3 +1,8 @@
+// Package queues
+// @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 queues
// 消息队列.
diff --git a/server/resource/generate/default/addon/service/sys.go.template b/server/resource/generate/default/addon/service/sys.go.template
index 844bce4..6266b34 100644
--- a/server/resource/generate/default/addon/service/sys.go.template
+++ b/server/resource/generate/default/addon/service/sys.go.template
@@ -14,11 +14,11 @@ import (
type (
ISysConfig interface {
GetBasic(ctx context.Context) (conf *model.BasicConfig, err error)
- GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
- UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error
+ GetConfigByGroup(ctx context.Context, in *sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
+ UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateConfigInp) error
}
ISysIndex interface {
- Test(ctx context.Context, in sysin.IndexTestInp) (res *sysin.IndexTestModel, err error)
+ Test(ctx context.Context, in *sysin.IndexTestInp) (res *sysin.IndexTestModel, err error)
}
)
diff --git a/server/resource/generate/default/curd/api.go.template b/server/resource/generate/default/curd/api.go.template
index 0074d0e..740d952 100644
--- a/server/resource/generate/default/curd/api.go.template
+++ b/server/resource/generate/default/curd/api.go.template
@@ -65,6 +65,7 @@ type DeleteRes struct{}
// MaxSortReq 获取@{.tableComment}最大排序
type MaxSortReq struct {
g.Meta `path:"/@{.varName | LcFirst}/maxSort" method:"get" tags:"@{.tableComment}" summary:"获取@{.tableComment}最大排序"`
+ @{.templateGroup}in.@{.varName}MaxSortInp
}
type MaxSortRes struct {
diff --git a/server/resource/generate/default/curd/controller.go.template b/server/resource/generate/default/curd/controller.go.template
index f4967e2..270f25c 100644
--- a/server/resource/generate/default/curd/controller.go.template
+++ b/server/resource/generate/default/curd/controller.go.template
@@ -9,9 +9,7 @@ package @{.templateGroup}
import (
"context"
- "github.com/gogf/gf/v2/util/gconv"
"@{.importApi}"
- "@{.importInput}"
"hotgo/internal/model/input/form"
"@{.importService}"
"hotgo/utility/validate"
@@ -25,63 +23,34 @@ type c@{.varName} struct{}
// List 查看@{.tableComment}列表
func (c *c@{.varName}) List(ctx context.Context, req *@{.varName | ToLower}.ListReq) (res *@{.varName | ToLower}.ListRes, err error) {
- var in @{.templateGroup}in.@{.varName}ListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- list, totalCount, err := service.@{.templateGroup | UcFirst}@{.varName}().List(ctx, in)
+ list, totalCount, err := service.@{.templateGroup | UcFirst}@{.varName}().List(ctx, &req.@{.varName}ListInp)
if err != nil {
return
}
res = new(@{.varName | ToLower}.ListRes)
res.List = list
- res.PageCount = form.CalPageCount(totalCount, req.PerPage)
- res.Page = req.Page
- res.PerPage = req.PerPage
+ res.PageRes.Pack(req, totalCount)
return
}
@{ if eq .options.Step.HasExport true }
// Export 导出@{.tableComment}列表
func (c *c@{.varName}) Export(ctx context.Context, req *@{.varName | ToLower}.ExportReq) (res *@{.varName | ToLower}.ExportRes, err error) {
- var in @{.templateGroup}in.@{.varName}ListInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.@{.templateGroup | UcFirst}@{.varName}().Export(ctx, in)
+ err = service.@{.templateGroup | UcFirst}@{.varName}().Export(ctx, &req.@{.varName}ListInp)
return
}
@{end}
@{ if eq .options.Step.HasEdit true }
// Edit 更新@{.tableComment}
func (c *c@{.varName}) Edit(ctx context.Context, req *@{.varName | ToLower}.EditReq) (res *@{.varName | ToLower}.EditRes, err error) {
- var in @{.templateGroup}in.@{.varName}EditInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.@{.templateGroup | UcFirst}@{.varName}().Edit(ctx, in)
+ err = service.@{.templateGroup | UcFirst}@{.varName}().Edit(ctx, &req.@{.varName}EditInp)
return
}
@{end}
@{ if and (eq .options.Step.HasEdit true) (eq .options.Step.HasMaxSort true) }
// MaxSort 获取@{.tableComment}最大排序
func (c *c@{.varName}) MaxSort(ctx context.Context, req *@{.varName | ToLower}.MaxSortReq) (res *@{.varName | ToLower}.MaxSortRes, err error) {
- data, err := service.@{.templateGroup | UcFirst}@{.varName}().MaxSort(ctx, sysin.@{.varName}MaxSortInp{})
+ data, err := service.@{.templateGroup | UcFirst}@{.varName}().MaxSort(ctx, &req.@{.varName}MaxSortInp)
if err != nil {
return
}
@@ -94,16 +63,7 @@ func (c *c@{.varName}) MaxSort(ctx context.Context, req *@{.varName | ToLower}.M
@{ if or (eq .options.Step.HasView true) (eq .options.Step.HasEdit true) }
// View 获取指定@{.tableComment}信息
func (c *c@{.varName}) View(ctx context.Context, req *@{.varName | ToLower}.ViewReq) (res *@{.varName | ToLower}.ViewRes, err error) {
- var in @{.templateGroup}in.@{.varName}ViewInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- data, err := service.@{.templateGroup | UcFirst}@{.varName}().View(ctx, in)
+ data, err := service.@{.templateGroup | UcFirst}@{.varName}().View(ctx, &req.@{.varName}ViewInp)
if err != nil {
return
}
@@ -116,48 +76,21 @@ func (c *c@{.varName}) View(ctx context.Context, req *@{.varName | ToLower}.View
@{ if eq .options.Step.HasDel true }
// Delete 删除@{.tableComment}
func (c *c@{.varName}) Delete(ctx context.Context, req *@{.varName | ToLower}.DeleteReq) (res *@{.varName | ToLower}.DeleteRes, err error) {
- var in @{.templateGroup}in.@{.varName}DeleteInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.@{.templateGroup | UcFirst}@{.varName}().Delete(ctx, in)
+ err = service.@{.templateGroup | UcFirst}@{.varName}().Delete(ctx, &req.@{.varName}DeleteInp)
return
}
@{end}
@{ if eq .options.Step.HasStatus true }
// Status 更新@{.tableComment}状态
func (c *c@{.varName}) Status(ctx context.Context, req *@{.varName | ToLower}.StatusReq) (res *@{.varName | ToLower}.StatusRes, err error) {
- var in @{.templateGroup}in.@{.varName}StatusInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.@{.templateGroup | UcFirst}@{.varName}().Status(ctx, in)
+ err = service.@{.templateGroup | UcFirst}@{.varName}().Status(ctx, &req.@{.varName}StatusInp)
return
}
@{end}
@{ if eq .options.Step.HasSwitch true }
// Switch 更新@{.tableComment}开关状态
func (c *c@{.varName}) Switch(ctx context.Context, req *@{.varName | ToLower}.SwitchReq) (res *@{.varName | ToLower}.SwitchRes, err error) {
- var in @{.templateGroup}in.@{.varName}SwitchInp
- if err = gconv.Scan(req, &in); err != nil {
- return
- }
-
- if err = validate.PreFilter(ctx, &in); err != nil {
- return
- }
-
- err = service.@{.templateGroup | UcFirst}@{.varName}().Switch(ctx, in)
+ err = service.@{.templateGroup | UcFirst}@{.varName}().Switch(ctx, &req.@{.varName}SwitchInp)
return
}
@{end}
diff --git a/server/resource/generate/default/curd/logic.go.template b/server/resource/generate/default/curd/logic.go.template
index 75ee9ec..9bad69a 100644
--- a/server/resource/generate/default/curd/logic.go.template
+++ b/server/resource/generate/default/curd/logic.go.template
@@ -44,7 +44,7 @@ func (s *s@{.servFunName}) Model(ctx context.Context, option ...*handler.Option)
}
// List 获取@{.tableComment}列表
-func (s *s@{.servFunName}) List(ctx context.Context, in @{.templateGroup}in.@{.varName}ListInp) (list []*@{.templateGroup}in.@{.varName}ListModel, totalCount int, err error) {
+func (s *s@{.servFunName}) List(ctx context.Context, in *@{.templateGroup}in.@{.varName}ListInp) (list []*@{.templateGroup}in.@{.varName}ListModel, totalCount int, err error) {
mod := s.Model(ctx@{ if eq .options.Step.HasNotFilterAuth true } ,&handler.Option{FilterAuth: false}@{end})
@{.listWhere}
@{.listJoin.link}
@@ -68,7 +68,7 @@ func (s *s@{.servFunName}) List(ctx context.Context, in @{.templateGroup}in.@{.v
}
@{ if eq .options.Step.HasExport true }
// Export 导出@{.tableComment}
-func (s *s@{.servFunName}) Export(ctx context.Context, in @{.templateGroup}in.@{.varName}ListInp) (err error) {
+func (s *s@{.servFunName}) Export(ctx context.Context, in *@{.templateGroup}in.@{.varName}ListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
@@ -95,9 +95,8 @@ func (s *s@{.servFunName}) Export(ctx context.Context, in @{.templateGroup}in.@{
}@{end}
@{ if eq .options.Step.HasEdit true }
// Edit 修改/新增@{.tableComment}
-func (s *s@{.servFunName}) Edit(ctx context.Context, in @{.templateGroup}in.@{.varName}EditInp) (err error) {
-@{.edit.unique}
- // 修改
+func (s *s@{.servFunName}) Edit(ctx context.Context, in *@{.templateGroup}in.@{.varName}EditInp) (err error) {
+@{.edit.unique} // 修改
if in.@{.pk.GoName} > 0 {
@{.edit.update}
}
@@ -109,7 +108,7 @@ func (s *s@{.servFunName}) Edit(ctx context.Context, in @{.templateGroup}in.@{.v
@{end}
@{ if eq .options.Step.HasDel true }
// Delete 删除@{.tableComment}
-func (s *s@{.servFunName}) Delete(ctx context.Context, in @{.templateGroup}in.@{.varName}DeleteInp) (err error) {
+func (s *s@{.servFunName}) Delete(ctx context.Context, in *@{.templateGroup}in.@{.varName}DeleteInp) (err error) {
if _, err = s.Model(ctx@{ if eq .options.Step.HasNotFilterAuth true } ,&handler.Option{FilterAuth: false}@{end}).WherePri(in.@{.pk.GoName}).Delete();err != nil {
err = gerror.Wrap(err, "删除@{.tableComment}失败,请稍后重试!")
return
@@ -118,7 +117,7 @@ func (s *s@{.servFunName}) Delete(ctx context.Context, in @{.templateGroup}in.@{
}@{end}
@{ if and (eq .options.Step.HasEdit true) (eq .options.Step.HasMaxSort true) }
// MaxSort 获取@{.tableComment}最大排序
-func (s *s@{.servFunName}) MaxSort(ctx context.Context, in @{.templateGroup}in.@{.varName}MaxSortInp) (res *@{.templateGroup}in.@{.varName}MaxSortModel, err error) {
+func (s *s@{.servFunName}) MaxSort(ctx context.Context, in *@{.templateGroup}in.@{.varName}MaxSortInp) (res *@{.templateGroup}in.@{.varName}MaxSortModel, err error) {
if err = dao.@{.daoName}.Ctx(ctx).Fields(dao.@{.daoName}.Columns().Sort).OrderDesc(dao.@{.daoName}.Columns().Sort).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取@{.tableComment}最大排序,请稍后重试!")
return
@@ -128,13 +127,13 @@ func (s *s@{.servFunName}) MaxSort(ctx context.Context, in @{.templateGroup}in.@
res = new(@{.templateGroup}in.@{.varName}MaxSortModel)
}
- res.Sort = form.DefaultMaxSort(ctx, res.Sort)
+ res.Sort = form.DefaultMaxSort(res.Sort)
return
}
@{end}
@{ if or (eq .options.Step.HasView true) (eq .options.Step.HasEdit true) }
// View 获取@{.tableComment}指定信息
-func (s *s@{.servFunName}) View(ctx context.Context, in @{.templateGroup}in.@{.varName}ViewInp) (res *@{.templateGroup}in.@{.varName}ViewModel, err error) {
+func (s *s@{.servFunName}) View(ctx context.Context, in *@{.templateGroup}in.@{.varName}ViewInp) (res *@{.templateGroup}in.@{.varName}ViewModel, err error) {
if err = s.Model(ctx@{ if eq .options.Step.HasNotFilterAuth true } ,&handler.Option{FilterAuth: false}@{end}).WherePri(in.@{.pk.GoName}).Scan(&res);err != nil {
err = gerror.Wrap(err, "获取@{.tableComment}信息,请稍后重试!")
return
@@ -143,7 +142,7 @@ func (s *s@{.servFunName}) View(ctx context.Context, in @{.templateGroup}in.@{.v
}@{end}
@{ if eq .options.Step.HasStatus true }
// Status 更新@{.tableComment}状态
-func (s *s@{.servFunName}) Status(ctx context.Context, in @{.templateGroup}in.@{.varName}StatusInp) (err error) {
+func (s *s@{.servFunName}) Status(ctx context.Context, in *@{.templateGroup}in.@{.varName}StatusInp) (err error) {
if _, err = s.Model(ctx@{ if eq .options.Step.HasNotFilterAuth true } ,&handler.Option{FilterAuth: false}@{end}).WherePri(in.@{.pk.GoName}).Data(@{.statusUpdate}).Update();err != nil {
err = gerror.Wrap(err, "更新@{.tableComment}状态失败,请稍后重试!")
return
@@ -153,7 +152,7 @@ func (s *s@{.servFunName}) Status(ctx context.Context, in @{.templateGroup}in.@{
@{end}
@{ if eq .options.Step.HasSwitch true }
// Switch 更新@{.tableComment}开关
-func (s *s@{.servFunName}) Switch(ctx context.Context, in @{.templateGroup}in.@{.varName}SwitchInp) (err error) {
+func (s *s@{.servFunName}) Switch(ctx context.Context, in *@{.templateGroup}in.@{.varName}SwitchInp) (err error) {
var fields = []string{
@{.switchFields}
// ...
diff --git a/server/storage/data/hotgo.sql b/server/storage/data/hotgo.sql
index 58c4332..a6b0f72 100644
--- a/server/storage/data/hotgo.sql
+++ b/server/storage/data/hotgo.sql
@@ -3,7 +3,7 @@
-- https://www.phpmyadmin.net/
--
-- 主机: localhost:3306
--- 生成日期: 2023-05-29 11:43:40
+-- 生成日期: 2023-07-20 17:57:22
-- 服务器版本: 5.7.38-log
-- PHP 版本: 5.6.40
@@ -73,7 +73,7 @@ CREATE TABLE `hg_addon_hgexample_table` (
--
INSERT INTO `hg_addon_hgexample_table` (`id`, `category_id`, `flag`, `title`, `description`, `content`, `image`, `images`, `attachfile`, `attachfiles`, `map`, `star`, `price`, `views`, `activity_at`, `start_at`, `end_at`, `switch`, `sort`, `avatar`, `sex`, `qq`, `email`, `mobile`, `hobby`, `channel`, `city_id`, `pid`, `level`, `tree`, `remark`, `status`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`) VALUES
-(1, 1, '[1, 2]', '测试标题', '描述', '
这是内容............
', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqamvhlq4w3ki6bl.webp', '[\"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqap5l9brk2lkavu.jpg\", \"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqaqua7fw8ukbbp5.jpg\"]', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqaup19k9oznyixz.doc', '[\"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqawg96ba4cuezvv.xlsx\", \"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqaup19k9oznyixz.doc\"]', '[{\"key\": \"qwe\", \"value\": \"123\"}, {\"key\": \"asd\", \"value\": \"456\"}]', '3.0', '88.00', 10, '2022-12-23', '2022-12-01 00:00:00', '2022-12-31 23:59:59', 1, 20, '', 15, '133814250', '133814250@qq.com', '15303830571', '[3, 2, 1]', 1, 140406, 0, 1, '', '备注!', 1, 1, 3, '2022-12-15 19:30:14', '2023-04-28 16:46:17', NULL),
+(1, 1, '[1, 2]', '测试标题', '描述', '这是内容............
', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqamvhlq4w3ki6bl.webp', '[\"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqap5l9brk2lkavu.jpg\", \"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqaqua7fw8ukbbp5.jpg\"]', 'http://localhost:8000/attachment/2023-07-18/cu54ama4z54oejf5xx.mp3', '[\"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqawg96ba4cuezvv.xlsx\", \"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqaup19k9oznyixz.doc\"]', '[{\"key\": \"qwe\", \"value\": \"123\"}, {\"key\": \"asd\", \"value\": \"456\"}]', '3.0', '88.00', 10, '2022-12-23', '2022-12-01 00:00:00', '2022-12-31 23:59:59', 1, 20, '', 15, '133814250', '133814250@qq.com', '15303830571', '[3, 2, 1]', 1, 140406, 0, 1, '', '备注!', 1, 1, 1, '2022-12-15 19:30:14', '2023-07-18 20:05:45', NULL),
(2, 0, '[1]', '测试2', '描述', '不知道写点啥!
', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqbmxmtaq06gbnqa.jpeg', '[\"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqborf529kf4cxbm.jpeg\"]', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqawg96ba4cuezvv.xlsx', '[\"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdqaup19k9oznyixz.doc\"]', '{}', '2.5', '10.00', 0, '2023-02-18', NULL, NULL, 2, 30, '', 0, '', '1561561@qq.com', '15303830571', '[2, 1]', 3, 140214, 0, 1, '', '', 1, 1, 1, '2023-02-06 14:17:11', '2023-02-23 13:59:01', NULL);
-- --------------------------------------------------------
@@ -95,6 +95,13 @@ CREATE TABLE `hg_admin_cash` (
`created_at` datetime NOT NULL COMMENT '申请时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='管理员_提现记录表';
+--
+-- 转存表中的数据 `hg_admin_cash`
+--
+
+INSERT INTO `hg_admin_cash` (`id`, `member_id`, `money`, `fee`, `last_money`, `ip`, `status`, `msg`, `handle_at`, `created_at`) VALUES
+(1, 1, '100.00', '3.00', '97.00', '127.0.0.1', 2, '', '2023-05-29 14:17:17', '2023-05-29 14:16:57');
+
-- --------------------------------------------------------
--
@@ -119,6 +126,15 @@ CREATE TABLE `hg_admin_credits_log` (
`updated_at` datetime DEFAULT NULL COMMENT '修改时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='管理员_资产变动表';
+--
+-- 转存表中的数据 `hg_admin_credits_log`
+--
+
+INSERT INTO `hg_admin_credits_log` (`id`, `member_id`, `app_id`, `addons_name`, `credit_type`, `credit_group`, `before_num`, `num`, `after_num`, `remark`, `ip`, `map_id`, `status`, `created_at`, `updated_at`) VALUES
+(1, 1, 'admin', '', 'balance', 'apply_cash', '99391.78', '-100.00', '99291.78', '后台申请提现', '127.0.0.1', 1, 0, '2023-05-29 14:16:57', '2023-05-29 14:16:57'),
+(2, 1, 'admin', '', 'balance', 'op_incr', '99291.78', '-1.00', '99290.78', '为后台用户:8 操作增加余额:1', '127.0.0.1', 0, 0, '2023-07-06 17:17:39', '2023-07-06 17:17:39'),
+(3, 8, 'admin', '', 'balance', 'incr', '3.22', '1.00', '4.22', '后台用户:1 为你操作增加余额:1', '127.0.0.1', 0, 0, '2023-07-06 17:17:39', '2023-07-06 17:17:39');
+
-- --------------------------------------------------------
--
@@ -147,15 +163,14 @@ CREATE TABLE `hg_admin_dept` (
--
INSERT INTO `hg_admin_dept` (`id`, `pid`, `name`, `code`, `type`, `leader`, `phone`, `email`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
-(100, 0, 'hotgo', 'hotgo', '', 'hotgo', '15303830571', '133814250@qq.com', 1, NULL, 0, 1, '2022-01-04 09:54:52', '2023-04-27 23:16:57'),
-(101, 100, '深圳总公司', 'shenzhen', 'company', 'hotgo', '15888888888', 'hotgo@qq.com', 2, 'tr_100 ', 1, 1, '2022-01-04 17:54:52', '2023-04-27 23:16:55'),
-(102, 100, '长沙分公司', 'chansgha', '', 'hotgo', '15888888888', 'hotgo@qq.com', 2, 'tr_100 ', 2, 1, '2022-01-04 01:54:52', '2023-04-27 23:17:01'),
-(103, 101, '研发部门', 'science', 'dept', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_101 ', 1, 1, '2022-01-04 17:54:52', '2023-01-24 21:17:38'),
-(105, 101, '测试部门', 'test', 'dept', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_101 ', 3, 1, '2022-01-04 17:54:52', '2023-01-24 21:17:31'),
-(106, 101, '财务部门', 'finance', 'dept', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_101 ', 4, 1, '2022-01-04 17:54:52', '2023-01-24 21:17:49'),
-(107, 101, '运维部门', 'maintain', '', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_101 ', 5, 1, '2022-01-04 09:54:52', '2023-01-24 21:17:34'),
-(108, 102, '市场部门', 'market', 'dept', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_102 ', 1, 1, '2022-01-04 17:54:52', '2023-01-24 21:18:04'),
-(112, 0, '测试', '测试', '', '', '', '', 1, NULL, 0, 1, '2022-08-14 19:38:54', '2023-02-26 00:26:35');
+(100, 0, 'hotgo', 'hotgo', '', 'mengshuai', '15303830571', '133814250@qq.com', 1, 'tr_100 ', 0, 1, '2022-01-04 09:54:52', '2023-05-29 15:08:32'),
+(101, 100, '深圳总公司', 'shenzhen', 'company', 'hotgo', '15888888888', 'hotgo@qq.com', 2, 'tr_100 tr_101 ', 1, 1, '2022-01-04 17:54:52', '2023-05-29 15:08:32'),
+(102, 100, '长沙分公司', 'chansgha', '', 'hotgo', '15888888888', 'hotgo@qq.com', 2, 'tr_100 tr_102 ', 2, 1, '2022-01-04 01:54:52', '2023-07-19 15:27:30'),
+(103, 101, '研发部门', 'science', 'dept', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_101 tr_103 ', 1, 1, '2022-01-04 17:54:52', '2023-05-29 15:08:32'),
+(105, 101, '测试部门', 'test', 'dept', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_101 tr_105 ', 3, 1, '2022-01-04 17:54:52', '2023-05-29 15:08:32'),
+(106, 101, '财务部门', 'finance', 'dept', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_101 tr_106 ', 4, 1, '2022-01-04 17:54:52', '2023-05-29 15:08:32'),
+(107, 101, '运维部门', 'maintain', '', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_101 tr_107 ', 5, 1, '2022-01-04 09:54:52', '2023-05-29 15:08:32'),
+(108, 102, '市场部门', 'market', 'dept', 'hotgo', '15888888888', 'hotgo@qq.com', 3, 'tr_100 tr_102 tr_108 ', 1, 1, '2022-01-04 17:54:52', '2023-05-29 15:08:32');
-- --------------------------------------------------------
@@ -199,9 +214,9 @@ CREATE TABLE `hg_admin_member` (
--
INSERT INTO `hg_admin_member` (`id`, `dept_id`, `role_id`, `real_name`, `username`, `password_hash`, `salt`, `password_reset_token`, `integral`, `balance`, `avatar`, `sex`, `qq`, `email`, `mobile`, `birthday`, `city_id`, `address`, `pid`, `level`, `tree`, `invite_code`, `cash`, `last_active_at`, `remark`, `status`, `created_at`, `updated_at`) VALUES
-(1, 100, 1, '孟帅', 'admin', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', '89.00', '99391.78', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '133814250', '133814250@qq.com', '15303830571', '2016-04-16', 410172, '莲花街001号', 0, 1, '', '111', '{\"name\": \"孟帅\", \"account\": \"15303830571\", \"payeeCode\": \"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8mqal5isvcb58g.jpg\"}', '2023-05-29 11:41:32', NULL, 1, '2021-02-12 17:59:45', '2023-05-29 11:41:32'),
+(1, 100, 1, '孟帅', 'admin', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', '89.00', '99290.78', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '133814250', '133814250@qq.com', '15303830571', '2016-04-16', 410172, '莲花街001号', 0, 1, '', '111', '{\"name\": \"孟帅\", \"account\": \"15303830571\", \"payeeCode\": \"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8mqal5isvcb58g.jpg\"}', '2023-07-20 17:29:08', NULL, 1, '2021-02-12 17:59:45', '2023-07-20 17:29:08'),
(3, 100, 2, '测试账号', 'test', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', '0.00', '4.00', 'http://alioss.qvnidaye.com//images/2021/03/12/image_1615529198_vMK4kwq2.jpg', 1, '', 'c@qq.cc', '15303888888', '2016-04-13', 371100, '大潮街道666号', 1, 2, 'tr_1 ', '222', NULL, '2023-05-14 12:29:15', '', 1, '2022-02-11 17:59:45', '2023-05-14 12:29:15'),
-(8, 101, 200, 'ameng', 'ameng', '382df3b083a27886edb94e669a857c33', 'hfuUEb', '', '11.00', '3.22', '', 1, '', '', '', NULL, 0, '', 1, 2, 'tr_1 ', '333', NULL, '2023-05-14 12:25:24', '', 1, '2023-02-03 17:34:31', '2023-05-14 12:25:24');
+(8, 101, 200, 'ameng', 'ameng', '382df3b083a27886edb94e669a857c33', 'hfuUEb', '', '11.00', '4.22', '', 2, '', '', '', NULL, 0, '', 1, 2, 'tr_1 ', '333', NULL, '2023-05-14 12:25:24', '', 1, '2023-02-03 17:34:31', '2023-07-06 17:17:39');
-- --------------------------------------------------------
@@ -282,14 +297,14 @@ CREATE TABLE `hg_admin_menu` (
--
INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES
-(2047, 0, 'Dashboard', 'Dashboard', '/dashboard', 'DashboardOutlined', 1, '/dashboard/console', 'dashboard', '控制台', 'LAYOUT', 0, NULL, 0, 1, NULL, 0, 0, 0, 1, '', 10, '这是一个备注..', 1, '2022-07-17 11:40:03', '2022-07-17 11:40:03'),
+(2047, 0, 'Dashboard', 'Dashboard', '/dashboard', 'DashboardOutlined', 1, '/dashboard/console', 'dashboard', '控制台', 'LAYOUT', 0, '', 0, 1, '', 0, 0, 0, 1, '', 10, '这是一个备注..', 1, '2022-07-17 11:40:03', '2023-07-03 10:08:08'),
(2048, 2047, '主控台', 'dashboard_console', 'console', '', 2, '', '/console/stat', '主控台', '/dashboard/console/console', 0, '', 0, 1, '', 0, 0, 0, 2, '', 20, '', 1, '2022-07-17 11:45:09', '2022-11-22 11:32:30'),
-(2050, 2047, '工作台', 'dashboard_workplace', 'workplace', NULL, 2, NULL, 'dashboard_workplace', '工作台', '/dashboard/workplace/workplace', 0, NULL, 0, 1, NULL, 0, 0, 0, 2, '', 40, NULL, 1, '2022-07-17 11:45:09', '2022-07-17 11:45:12'),
-(2061, 0, '组织管理', 'Org', '/org', 'AppstoreOutlined', 1, '/org/user/user', '', '', 'LAYOUT', 0, '', 0, 0, '', 0, 0, 0, 1, '', 20, '', 1, '2022-09-16 06:08:19', '2023-05-16 14:38:12'),
-(2062, 2061, '后台用户', 'user', 'user', '', 2, '', '/dept/list,/post/list,/role/list,/member/list,/dept/option', '', '/org/user/user', 0, '', 0, 0, '', 1, 0, 0, 2, '', 10, '', 1, '2022-09-16 06:09:25', '2023-05-16 18:04:12'),
+(2050, 2047, '工作台', 'dashboard_workplace', 'workplace', '', 2, '', 'dashboard_workplace', '工作台', '/dashboard/workplace/workplace', 0, '', 0, 1, '', 0, 0, 0, 2, '', 40, '', 1, '2022-07-17 11:45:09', '2023-07-03 10:06:57'),
+(2061, 0, '组织管理', 'Org', '/org', 'AppstoreOutlined', 1, '/org/user', '', '', 'LAYOUT', 1, '', 0, 0, '', 0, 0, 0, 1, '', 20, '', 1, '2022-09-16 06:08:19', '2023-07-15 23:07:06'),
+(2062, 2061, '后台用户', 'user', 'user', '', 2, '', '/dept/list,/post/list,/role/list,/member/list,/dept/option', '', '/org/user/user', 0, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-16 06:09:25', '2023-07-15 23:02:50'),
(2063, 2061, '部门管理', 'org_dept', 'dept', '', 2, '', '', '', '/org/dept/dept', 0, '', 0, 0, '', 1, 0, 0, 2, '', 20, '', 1, '2022-09-16 14:10:12', '2023-05-16 18:02:11'),
-(2064, 2061, '岗位管理', 'org_post', 'post', '', 2, '', '/post/list', '', '/org/post/post', 0, '', 0, 0, '', 1, 0, 0, 2, '', 30, '', 1, '2022-09-16 14:11:05', '2023-05-16 14:38:16'),
-(2065, 0, '权限管理', 'Permission', '/permission', 'SafetyCertificateOutlined', 1, '/permission/menu', '', '', 'LAYOUT', 1, '', 0, 0, '', 0, 0, 0, 1, '', 40, '', 1, '2022-09-15 22:08:19', '2023-01-10 17:17:53'),
+(2064, 2061, '岗位管理', 'org_post', 'post', '', 2, '', '/post/list', '', '/org/post/post', 0, '', 0, 0, '', 1, 0, 0, 2, '', 30, '', 1, '2022-09-16 14:11:05', '2023-07-03 10:13:25'),
+(2065, 0, '权限管理', 'Permission', '/permission', 'SafetyCertificateOutlined', 1, '/permission/menu', '', '', 'LAYOUT', 1, '', 0, 0, '', 0, 0, 0, 1, '', 40, '', 1, '2022-09-15 22:08:19', '2023-06-25 18:58:43'),
(2066, 2065, '菜单权限', 'permission_menu', 'menu', '', 2, '', '/menu/list', '', '/permission/menu/menu', 0, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-16 06:09:25', '2022-11-22 16:34:12'),
(2067, 2065, '角色权限', 'permission_role', 'role', '', 2, '', '/role/list', '', '/permission/role/role', 0, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-15 22:09:25', '2022-11-22 16:34:01'),
(2068, 0, '系统设置', 'System', '/system', 'SettingOutlined', 1, '/system/config', '', '', 'LAYOUT', 1, '', 0, 0, '', 0, 0, 0, 1, '', 30, '', 1, '2022-09-15 09:17:57', '2023-01-10 17:16:41'),
@@ -299,16 +314,15 @@ INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type
(2072, 2068, '黑名单', 'system_blacklist', 'blacklist', '', 2, '', '', '', '/system/blacklist/index', 1, '', 0, 0, '', 0, 0, 0, 2, '', 40, '', 1, '2022-09-16 17:34:01', '2022-09-16 17:34:01'),
(2073, 2219, '个人设置', 'home_account', 'account', '', 2, '', '', '', '/home/account/account', 1, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-16 17:34:35', '2023-02-01 15:05:57'),
(2074, 0, '日志管理', 'Logs', '/log', 'UnorderedListOutlined', 1, '', '', '', 'LAYOUT', 1, '', 0, 0, '', 0, 0, 0, 1, '', 60, '', 1, '2022-09-16 01:38:32', '2023-01-10 17:19:46'),
-(2075, 2074, '访问日志', 'log', 'log', '', 1, '/log/log/index', '', '', 'ParentLayout', 0, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-09 17:39:16', '2023-01-20 23:08:41'),
-(2076, 2074, '登录日志', 'login_log', 'login-log', '', 1, '/log/login-log/index', '', '', 'ParentLayout', 0, '', 0, 0, '', 1, 0, 0, 2, '', 20, '', 1, '2022-09-15 20:04:20', '2023-05-16 14:39:47'),
-(2077, 2075, '全局日志详情', 'log_view', 'view/:id?', '', 2, '', '/log/view', '', '/log/log/view', 0, 'log', 0, 0, '', 0, 1, 0, 3, '', 62, '', 1, '2022-09-14 20:07:04', '2022-11-23 22:12:27'),
-(2078, 2075, '全局日志列表', 'log_list', 'index', '', 2, '', '/log/list', '', '/log/log/index', 0, 'log', 0, 0, '', 0, 1, 0, 3, '', 61, '', 1, '2022-09-15 04:38:33', '2022-11-23 22:12:07'),
-(2082, 2076, '登录日志详情', 'loginLogView', 'view/:id?', '', 2, '', '/loginLog/view', '', '/log/login-log/view', 0, 'login_log', 0, 0, '', 0, 1, 0, 3, '', 62, '', 1, '2022-09-14 20:07:04', '2023-01-19 21:13:43'),
-(2083, 2076, '登录列表', 'login_log_index', 'index', '', 2, '', '', '', '/log/login-log/index', 0, 'login_log', 0, 0, '', 0, 1, 0, 3, '', 61, '', 1, '2022-09-15 04:38:33', '2023-05-16 16:31:24'),
+(2075, 2074, '全局日志', 'log', 'log', '', 2, '', '', '', '/log/log/index', 0, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-09 17:39:16', '2023-07-15 22:57:48'),
+(2076, 2074, '登录日志', 'login_log', 'login-log', '', 2, '', '', '', '/log/login-log/index', 0, '', 0, 0, '', 1, 0, 0, 2, '', 20, '', 1, '2022-09-15 20:04:20', '2023-07-15 22:53:01'),
+(2077, 2074, '全局日志详情', 'log_view', 'view/:id?', '', 2, '', '/log/view', '', '/log/log/view', 0, 'log', 0, 0, '', 0, 1, 0, 2, '', 15, '', 1, '2022-09-14 20:07:04', '2023-07-15 22:57:56'),
+(2082, 2076, '登录日志详情', 'loginLogView', 'view/:id?', '', 3, '', '/loginLog/view', '', '/log/login-log/view', 0, 'login_log', 0, 0, '', 0, 1, 0, 3, '', 62, '', 1, '2022-09-14 20:07:04', '2023-07-15 22:53:06'),
+(2083, 2076, '登录列表', 'login_log_index', 'index', '', 3, '', '', '', '/log/login-log/index', 0, 'login_log', 0, 0, '', 0, 1, 0, 3, '', 61, '', 1, '2022-09-15 04:38:33', '2023-07-15 22:52:56'),
(2084, 2074, '短信记录', 'sms_log', 'sms', '', 1, '', '', '', '/log/sms-log/index', 0, '', 0, 0, '', 0, 0, 0, 2, '', 70, '', 1, '2022-09-17 19:13:51', '2023-05-11 21:59:17'),
-(2087, 2074, '服务日志', 'monitor_serve_log', 'serve_log', '', 1, '/log/serve_log/index', '', '', 'ParentLayout', 1, '', 0, 0, '', 0, 0, 0, 2, '', 30, '', 1, '2022-09-18 20:59:28', '2023-01-20 23:08:50'),
-(2088, 2087, '服务日志详情', 'monitor_serve_log_view', 'view/:id?', '', 2, '', '/serve_log/view', '', '/monitor/serve-log/view', 0, 'monitor_serve_log', 0, 0, '', 0, 1, 0, 3, '', 62, '', 1, '2022-09-14 20:07:04', '2023-01-20 18:41:13'),
-(2089, 2087, '服务日志列表', 'monitor_serve_log_index', 'index', '', 2, '', '', '', '/monitor/serve-log/index', 0, 'monitor_serve_log', 0, 0, '', 0, 1, 0, 2, '', 61, '', 1, '2022-09-15 04:38:33', '2022-09-18 13:14:27'),
+(2087, 2074, '服务日志', 'monitor_serve_log', 'serve_log', '', 2, '', '', '', '/monitor/serve-log/index', 1, '', 0, 0, '', 0, 0, 0, 2, '', 30, '', 1, '2022-09-18 20:59:28', '2023-07-15 22:48:59'),
+(2088, 2087, '服务日志详情', 'monitor_serve_log_view', 'view/:id?', '', 3, '', '/serve_log/view', '', '/monitor/serve-log/view', 0, 'monitor_serve_log', 0, 0, '', 0, 1, 0, 3, '', 62, '', 1, '2022-09-14 20:07:04', '2023-07-15 22:49:17'),
+(2089, 2087, '服务日志列表', 'monitor_serve_log_index', 'index', '', 3, '', '', '', '/monitor/serve-log/index', 0, 'monitor_serve_log', 0, 0, '', 0, 1, 0, 3, '', 61, '', 1, '2022-09-15 04:38:33', '2023-07-15 22:49:02'),
(2090, 0, '系统监控', 'Monitors', '/monitor', 'FundProjectionScreenOutlined', 1, '', '', '', 'LAYOUT', 1, '', 0, 0, '', 0, 0, 0, 1, '', 80, '', 1, '2022-09-15 17:38:32', '2023-01-10 17:21:15'),
(2091, 2090, '在线用户', 'monitor_online', 'online', '', 2, '', '', '', '/monitor/online/index', 1, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-18 21:23:36', '2022-09-18 21:23:36'),
(2092, 2090, '服务监控', 'monitor_serve_monitor', 'serve_monitor', '', 2, '', '', '', '/monitor/serve-monitor/index', 1, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-18 21:23:36', '2022-09-18 21:23:36'),
@@ -318,10 +332,10 @@ INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type
(2096, 2093, '地区编码', 'apply_provinces', 'provinces', '', 2, '', '/provinces/list', '', '/apply/provinces/index', 1, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-18 21:31:01', '2022-11-23 22:19:52'),
(2097, 0, '开发工具', 'Develops', '/develop', 'CodeOutlined', 1, '/develop/code', '', '', 'LAYOUT', 1, '', 0, 0, '', 0, 0, 0, 1, '', 120, '', 1, '2022-09-18 21:32:27', '2023-01-10 17:23:25'),
(2098, 2097, '代码生成', 'develop_code', 'code', '', 2, '', '', '', '/develop/code/index', 1, '', 0, 0, '', 0, 0, 0, 2, '', 10, '', 1, '2022-09-18 21:32:46', '2022-09-18 21:32:46'),
-(2099, 2120, 'API文档', 'https://hotgo.facms.cn/swagger', '/docs', '', 1, '', '', '', 'LAYOUT', 1, '', 0, 1, 'https://hotgo.facms.cn/swagger', 0, 0, 0, 2, '', 1000, '', 1, '2022-09-18 21:34:09', '2023-02-22 18:55:13'),
+(2099, 2120, 'API文档', 'apidocs', 'apidocs', '', 1, '', '', '', 'IFRAME', 0, '', 0, 1, 'https://hotgo.facms.cn/swagger', 0, 0, 0, 2, '', 1000, '', 1, '2022-09-18 21:34:09', '2023-07-15 23:14:30'),
(2100, 2120, '使用文档', 'https://github.com/bufanyun/hotgo/tree/v2.0/docs/guide-zh-CN', '/hotgo', '', 1, '', '', '', 'LAYOUT', 1, '', 0, 0, '', 0, 0, 0, 2, '', 1100, '', 1, '2022-09-18 21:35:17', '2023-02-22 18:53:21'),
-(2102, 0, '关于', 'about', '/about', 'ProjectOutlined', 1, '/about/index', '', '', 'LAYOUT', 1, 'about_index', 1, 0, '', 0, 0, 0, 1, '', 9000, '', 1, '2022-09-18 13:37:04', '2022-11-24 00:09:05'),
-(2103, 2102, '关于详情', 'about_index', 'index', '', 2, '', '', '', '/about/index', 1, 'about_index', 0, 0, '', 0, 1, 0, 2, '', 10, '', 1, '2022-09-18 13:38:00', '2022-09-18 21:38:25'),
+(2102, 0, '关于', 'about', '/about', 'ProjectOutlined', 1, '/about/index', '', '', 'LAYOUT', 1, '', 1, 0, '', 0, 0, 0, 1, '', 9000, '', 1, '2022-09-18 13:37:04', '2023-07-03 11:25:36'),
+(2103, 2102, '关于详情', 'about_index', 'index', '', 2, '', '', '', '/about/index', 1, 'about', 0, 0, '', 0, 1, 0, 2, '', 10, '', 1, '2022-09-18 13:38:00', '2023-07-03 11:25:30'),
(2109, 2062, '编辑用户', 'org_user_edit', '', '', 3, '', '/member/edit,/member/view', '', '/', 1, '', 0, 0, '', 0, 1, 0, 3, '', 10, '', 1, '2022-11-22 23:49:17', '2023-04-27 00:02:31'),
(2110, 2062, '删除用户', 'org_user_delete', 'user', '', 3, '', '/member/delete', '', '/', 1, '', 0, 0, '', 0, 1, 0, 3, '', 10, '', 1, '2022-11-23 21:34:51', '2022-11-23 21:51:11'),
(2111, 2062, '修改用户状态', 'org_user_status', 'user', '', 3, '', '/member/status', '', '/', 1, '', 0, 0, '', 0, 1, 0, 3, '', 10, '', 1, '2022-11-23 21:35:48', '2023-01-10 17:39:52'),
@@ -332,8 +346,8 @@ INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type
(2116, 2064, '删除岗位', 'post_delete', 'post', '', 3, '', '/post/delete', '', '/', 1, '', 0, 0, '', 0, 0, 0, 3, '', 10, '', 1, '2022-11-23 22:00:13', '2022-11-23 22:03:06'),
(2117, 2064, '修改岗位状态', 'post_status', 'post', '', 3, '', '/post/status', '', '/', 1, '', 0, 0, '', 0, 0, 0, 3, '', 10, '', 1, '2022-11-23 22:00:54', '2022-11-23 22:00:54'),
(2118, 2095, '上传附件图片', 'attachment_upload_image', 'attachment', '', 3, '', '/upload/image', '', '/', 1, '', 0, 0, '', 0, 0, 0, 3, '', 10, '', 1, '2022-11-23 22:14:19', '2022-11-23 22:19:15'),
-(2120, 0, '文档中心', 'doc', 'doc', 'FileTextOutlined', 1, 'LAYOUT', '', '', '/doc', 1, '', 0, 0, '', 0, 0, 0, 1, '', 2000, '', 1, '2022-11-24 00:08:19', '2023-01-10 17:23:55'),
-(2122, 2228, '表格例子', 'table_index', 'table', '', 2, '', '/hgexample/table/list', '', '/addons/hgexample/table/index', 1, '', 0, 0, '', 0, 0, 0, 4, '', 10, '', 1, '2022-12-23 15:07:28', '2023-02-17 14:28:18'),
+(2120, 0, '文档中心', 'doc', 'doc', 'FileTextOutlined', 1, '/doc/apidocs', '', '', 'LAYOUT', 1, '', 0, 0, '', 0, 0, 0, 1, '', 2000, '', 1, '2022-11-24 00:08:19', '2023-07-15 23:14:47'),
+(2122, 2228, '表格例子', 'hgexample_table_index', 'hgexample_table', '', 2, '', '/hgexample/table/list', '', '/addons/hgexample/table/index', 1, '', 0, 0, '', 0, 0, 0, 3, '', 10, '', 1, '2022-12-23 15:07:28', '2023-07-18 15:55:46'),
(2124, 2228, '表格详情', 'table_view', 'view/:id?', '', 2, '', '/hgexample/table/view', '', '/addons/hgexample/table/view', 0, 'table_index', 0, 0, '', 0, 1, 0, 2, '', 20, '', 1, '2022-09-14 20:07:04', '2022-09-17 10:43:38'),
(2125, 2097, '生成配置', 'develop_code_deploy', 'deploy/:id?', '', 2, '', '', '', '/develop/code/deploy', 0, 'develop_code', 0, 0, '', 0, 1, 0, 2, '', 20, '', 1, '2022-12-31 17:16:26', '2022-12-31 17:17:46'),
(2198, 2097, '生成演示', 'curdDemo', '/curdDemo', 'MenuOutlined', 1, '', '', '', 'ParentLayout', 1, '', 0, 0, '', 0, 0, 0, 1, '', 200, '', 1, '2023-01-18 15:19:43', '2023-01-18 15:19:43'),
@@ -365,7 +379,7 @@ INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type
(2224, 2122, '修改测试状态', 'testStatus', '', '', 3, '', '/test/status', '', '', 1, '', 0, 0, '', 0, 0, 0, 3, '', 10, '', 1, '2023-01-18 15:19:43', '2023-01-18 15:19:43'),
(2225, 2122, '操作测试开关', 'testSwitch', '', '', 3, '', '/test/switch', '', '', 1, '', 0, 0, '', 0, 0, 0, 3, '', 10, '', 1, '2023-01-18 15:19:43', '2023-01-18 15:19:43'),
(2226, 2122, '编辑测试', 'testEdit', '', '', 3, '', '/test/edit', '', '', 1, '', 0, 0, '', 0, 0, 0, 3, '', 10, '', 1, '2023-01-18 15:19:43', '2023-01-18 15:19:43'),
-(2227, 0, '插件应用', 'addons', '/addons', 'AppstoreOutlined', 1, '', '', '', 'LAYOUT', 1, '', 0, 2, '', 0, 0, 0, 1, '', 130, '', 1, '2023-02-17 13:44:27', '2023-02-17 14:42:48'),
+(2227, 0, '插件应用', 'addons', '/addons', 'AppstoreOutlined', 1, '/addons/hgexample/hgexample_portal', '', '', 'LAYOUT', 1, '', 0, 2, '', 0, 0, 0, 1, '', 130, '', 1, '2023-02-17 13:44:27', '2023-07-15 23:06:34'),
(2228, 2227, '功能案例', 'hgexample', '/hgexample', '', 1, '', '', '', '/hgexample', 1, '', 0, 2, '', 0, 0, 0, 2, '', 10, '', 1, '2023-02-17 13:44:27', '2023-02-17 14:21:48'),
(2229, 2097, '插件管理', 'develop_addons', 'addons', '', 2, '', '', '', '/develop/addons/index', 1, '', 0, 0, '', 0, 0, 0, 2, '', 20, '', 1, '2022-09-18 21:32:46', '2022-09-18 21:32:46'),
(2230, 2228, '应用入口', 'hgexample_portal', 'hgexample_portal', '', 2, '', '', '', '/addons/hgexample/portal/index', 1, '', 0, 0, '', 0, 0, 0, 3, '', 5, '', 1, '2022-09-14 20:07:04', '2023-02-18 16:30:05'),
@@ -406,7 +420,14 @@ INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type
(2269, 2072, '删除策略', '/blacklist/delete', '', '', 3, '', '/blacklist/delete', '', '', 1, '', 0, 2, '', 0, 0, 0, 3, '', 40, '', 1, '2023-04-27 23:31:21', '2023-04-27 23:31:21'),
(2270, 2073, '修改登录密码', '/member/updatePwd', '', '', 3, '', '/member/updatePwd', '', '', 1, '', 0, 2, '', 0, 0, 0, 3, '', 10, '', 1, '2023-04-28 16:40:34', '2023-04-28 16:40:34'),
(2271, 2073, '换绑手机号', '/member/updateMobile', '', '', 3, '', '/member/updateMobile', '', '', 1, '', 0, 2, '', 0, 0, 0, 3, '', 20, '', 1, '2023-04-28 16:40:52', '2023-04-28 16:40:52'),
-(2272, 2073, '换绑邮箱', '/member/updateEmail', '', '', 3, '', '/member/updateEmail', '', '', 1, '', 0, 2, '', 0, 0, 0, 3, '', 30, '', 1, '2023-04-28 16:41:11', '2023-04-28 16:41:11');
+(2272, 2073, '换绑邮箱', '/member/updateEmail', '', '', 3, '', '/member/updateEmail', '', '', 1, '', 0, 2, '', 0, 0, 0, 3, '', 30, '', 1, '2023-04-28 16:41:11', '2023-04-28 16:41:11'),
+(2273, 2090, '在线服务', 'monitor_netconn', 'netconn', '', 1, '', '', '', '/monitor/netconn/index', 1, '', 0, 0, '', 0, 0, 0, 2, '', 20, '', 1, '2022-09-18 21:23:36', '2023-07-15 22:47:11'),
+(2275, 2273, '服务许可证列表', 'serveLicenseIndex', 'serveLicenseIndex', '', 3, '', '/serveLicense/list', '', '/serveLicense/index', 1, 'monitor_netconn', 0, 0, '', 0, 1, 0, 3, '', 10, '', 1, '2023-07-15 09:36:38', '2023-07-15 22:46:55'),
+(2277, 2275, '编辑/新增服务许可证', 'serveLicenseEdit', '', '', 3, '', '/serveLicense/edit', '', '', 1, '', 0, 0, '', 0, 1, 0, 4, '', 10, '', 1, '2023-07-15 09:36:38', '2023-07-15 20:13:43'),
+(2278, 2275, '删除服务许可证', 'serveLicenseDelete', '', '', 3, '', '/serveLicense/delete', '', '', 1, '', 0, 0, '', 0, 0, 0, 4, '', 10, '', 1, '2023-07-15 09:36:38', '2023-07-15 20:13:34'),
+(2279, 2275, '修改服务许可证状态', 'serveLicenseStatus', '', '', 3, '', '/serveLicense/status', '', '', 1, '', 0, 0, '', 0, 0, 0, 4, '', 10, '', 1, '2023-07-15 09:36:38', '2023-07-15 20:13:27'),
+(2280, 2275, '导出服务许可证', 'serveLicenseExport', '', '', 3, '', '/serveLicense/export', '', '', 1, '', 0, 0, '', 0, 0, 0, 4, '', 10, '', 1, '2023-07-15 09:36:38', '2023-07-15 20:13:23'),
+(2281, 2275, '分配许可证路由', 'serveLicenseAssignRouter', '', '', 3, '', '/serveLicense/assignRouter', '', '', 1, '', 0, 0, '', 0, 1, 0, 4, '', 10, '', 1, '2023-07-15 09:36:38', '2023-07-15 19:46:30');
-- --------------------------------------------------------
@@ -438,7 +459,7 @@ CREATE TABLE `hg_admin_notice` (
INSERT INTO `hg_admin_notice` (`id`, `title`, `type`, `tag`, `content`, `receiver`, `remark`, `sort`, `status`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`) VALUES
(29, '2023年春季学期开学工作通知!', 1, 1, '1.学生:2月11日、2月12日报到,2月13日起安排考试。\n\n2.教职工:2月10日(周五)起正式上班(2月11日、2月12日正常上班)。\n\n3.校内进行的各类社会服务项目,主办部门、单位须关注参与人员的健康状况,如有异常第一时间报告。感染后仍在康复期内的师生,不参加剧烈活动。开学后两周内,原则上不组织各类竞技性较强的体育比赛等活动。\n\n4.全校师生员工要牢固树立健康第一的观念,切实增强个人责任感和防护意识,掌握防护技能,坚持戴口罩、勤洗手等良好卫生习惯,加强身体锻炼,保持健康生活方式,提升健康素养和自我防护能力,当好自身健康第一责任人。符合条件的师生,积极有序接种第二剂次加强针疫苗。', 'null', '', 10, 1, 1, 1, '2023-02-09 12:25:39', '2023-02-09 12:48:08', NULL),
(30, '国务院办公厅关于2023年部分节假日安排的通知', 1, 3, '新华社北京12月8日电 国务院办公厅关于2023年部分节假日安排的通知,全文如下:\n\n 各省、自治区、直辖市人民政府,国务院\n\n 各部委、各直属机构:\n\n 经国务院批准,现将2023年元旦、春节、清明节、劳动节、端午节、中秋节和国庆节放假调休日期的具体安排通知如下。\n\n 一、元旦:2022年12月31日至2023年1月2日放假调休,共3天。\n\n 二、春节:1月21日至27日放假调休,共7天。1月28日(星期六)、1月29日(星期日)上班。\n\n 三、清明节:4月5日放假,共1天。\n\n 四、劳动节:4月29日至5月3日放假调休,共5天。4月23日(星期日)、5月6日(星期六)上班。\n\n 五、端午节:6月22日至24日放假调休,共3天。6月25日(星期日)上班。\n\n 六、中秋节、国庆节:9月29日至10月6日放假调休,共8天。10月7日(星期六)、10月8日(星期日)上班。\n\n 节假日期间,各地区、各部门要妥善安排好值班和安全、保卫、疫情防控等工作,遇有重大突发事件,要按规定及时报告并妥善处置,确保人民群众祥和平安度过节日假期。', 'null', '', 20, 1, 1, 1, '2023-02-09 12:32:32', '2023-02-09 12:48:28', NULL),
-(31, 'hotgo新版本发布啦!', 2, 4, '
本次更新内容如下:
1. 优化角色权限
2. 优化代码生成
3. ....
', 'null', '', 30, 1, 1, 0, '2023-02-09 12:45:17', '2023-02-09 12:45:17', NULL),
+(31, 'hotgo新版本发布啦!', 2, 4, '
本次更新内容如下:
1. 优化角色权限
2. 优化代码生成
3. ....
', 'null', '', 30, 1, 1, 0, '2023-02-09 12:45:17', '2023-02-09 12:45:17', '2023-06-09 18:04:30'),
(32, '新的好友', 3, 5, '哈喽,你好呀!
', '[1, 3, 8]', '', 40, 1, 1, 3, '2023-02-09 12:45:54', '2023-04-28 16:45:03', NULL),
(33, '1', 2, 0, '', 'null', '', 50, 1, 3, 0, '2023-04-28 16:45:11', '2023-04-28 16:45:11', '2023-04-28 16:45:14'),
(34, '1', 1, 0, '1', 'null', '', 50, 1, 3, 0, '2023-04-28 16:45:22', '2023-04-28 16:45:22', '2023-04-28 16:45:26');
@@ -464,10 +485,11 @@ CREATE TABLE `hg_admin_notice_read` (
INSERT INTO `hg_admin_notice_read` (`id`, `notice_id`, `member_id`, `clicks`, `updated_at`, `created_at`) VALUES
(1, 31, 1, 2, '2023-04-26 22:44:51', '2023-04-25 22:59:16'),
-(2, 30, 1, 2, '2023-04-26 22:44:30', '2023-04-25 23:01:27'),
+(2, 30, 1, 56, '2023-06-09 20:26:48', '2023-04-25 23:01:27'),
(3, 32, 3, 0, '2023-04-28 16:48:41', '2023-04-28 16:48:41'),
(4, 29, 3, 0, '2023-04-28 16:48:47', '2023-04-28 16:48:47'),
-(5, 30, 3, 0, '2023-04-28 16:48:47', '2023-04-28 16:48:47');
+(5, 30, 3, 0, '2023-04-28 16:48:47', '2023-04-28 16:48:47'),
+(6, 29, 1, 0, '2023-06-09 20:26:43', '2023-06-09 20:26:43');
-- --------------------------------------------------------
@@ -525,7 +547,7 @@ CREATE TABLE `hg_admin_post` (
`code` varchar(64) NOT NULL COMMENT '岗位编码',
`name` varchar(50) NOT NULL COMMENT '岗位名称',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
- `sort` int(11) NOT NULL COMMENT '显示顺序',
+ `sort` int(11) NOT NULL COMMENT '排序',
`status` tinyint(1) NOT NULL COMMENT '状态',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '更新时间'
@@ -536,7 +558,7 @@ CREATE TABLE `hg_admin_post` (
--
INSERT INTO `hg_admin_post` (`id`, `code`, `name`, `remark`, `sort`, `status`, `created_at`, `updated_at`) VALUES
-(1, 'ceo', '董事长', '', 1, 1, '2022-01-04 17:54:52', '2023-01-18 00:00:00'),
+(1, 'ceo', '董事长', '', 1, 1, '2022-01-04 17:54:52', '2023-07-06 15:17:48'),
(2, 'se', '项目经理', '', 2, 1, '2022-01-04 17:54:52', '2023-01-18 00:00:00'),
(3, 'hr', '人力资源', '', 3, 1, '2022-01-04 17:54:52', '2023-02-26 00:32:40'),
(4, 'user', '普通员工', '', 4, 1, '2022-01-04 17:54:52', '2022-05-15 22:33:09'),
@@ -571,9 +593,9 @@ CREATE TABLE `hg_admin_role` (
INSERT INTO `hg_admin_role` (`id`, `name`, `key`, `data_scope`, `custom_dept`, `pid`, `level`, `tree`, `remark`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(1, '超级管理员', 'super', 1, '[]', 0, 1, NULL, '超级管理员,拥有全部菜单、数据权限,无需绑定和验证', 1, 1, '2022-01-04 17:54:52', '2023-01-12 00:00:00'),
(2, '管理员', 'manage', 1, '[]', 1, 2, 'tr_1 ', '普通管理员,拥有常规的后台系统权限', 2, 1, '2022-01-04 17:54:52', '2023-04-27 00:00:00'),
-(200, '金牌代理商', 'gold_agent', 7, '[]', 0, 1, NULL, '金牌代理商,分离机构权限,满足sass需求', 200, 1, '2023-01-12 00:00:00', '2022-08-13 23:28:52'),
-(201, '银牌代理商', 'silver_agent', 7, '[]', 200, 2, 'tr_200 ', '银牌代理商,分离机构权限,满足sass需求', 210, 1, '2023-01-12 00:00:00', '2022-08-13 23:28:52'),
-(202, '铜牌代理', 'copper_agent', 5, '[]', 200, 2, 'tr_200 ', '', 220, 1, '2023-01-12 11:20:02', '2023-01-24 20:56:34'),
+(200, '金牌代理商', 'gold_agent', 7, '[]', 0, 1, 'tr_200 ', '金牌代理商,分离机构权限,满足sass需求', 200, 1, '2023-01-12 00:00:00', '2023-05-29 15:17:44'),
+(201, '银牌代理商', 'silver_agent', 7, '[]', 200, 2, 'tr_200 tr_201 ', '银牌代理商,分离机构权限,满足sass需求', 210, 1, '2023-01-12 00:00:00', '2023-05-29 15:17:44'),
+(202, '铜牌代理', 'copper_agent', 5, '[]', 200, 2, 'tr_200 tr_202 ', '', 220, 1, '2023-01-12 11:20:02', '2023-05-29 15:17:44'),
(206, '财务部', 'finance', 2, '[]', 2, 3, 'tr_1 tr_2 ', '', 5, 1, '2023-01-24 20:22:10', '2023-04-26 23:59:30'),
(207, '商务部', 'business', 1, '[]', 2, 3, 'tr_1 tr_2 ', '', 3, 1, '2023-01-24 20:23:27', '2023-04-26 23:59:25'),
(208, '技术部', 'science', 1, '[]', 2, 3, 'tr_1 tr_2 ', '', 2, 1, '2023-01-24 20:23:54', '2023-04-26 23:59:19');
@@ -600,201 +622,199 @@ CREATE TABLE `hg_admin_role_casbin` (
--
INSERT INTO `hg_admin_role_casbin` (`id`, `p_type`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES
-(31157, 'p', 'manage', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31158, 'p', 'manage', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31159, 'p', 'manage', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31160, 'p', 'manage', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31161, 'p', 'manage', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31162, 'p', 'manage', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31163, 'p', 'manage', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31164, 'p', 'manage', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31165, 'p', 'manage', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31166, 'p', 'manage', '/menu/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31167, 'p', 'manage', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31168, 'p', 'manage', '/log/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31169, 'p', 'manage', '/log/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31170, 'p', 'manage', '/loginLog/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31171, 'p', 'manage', '/serve_log/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31172, 'p', 'manage', '/notice/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31173, 'p', 'manage', '/attachment/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31174, 'p', 'manage', '/provinces/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31175, 'p', 'manage', '/member/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31176, 'p', 'manage', '/member/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31177, 'p', 'manage', '/member/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31178, 'p', 'manage', '/member/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31179, 'p', 'manage', '/dept/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31180, 'p', 'manage', '/dept/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31181, 'p', 'manage', '/dept/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31182, 'p', 'manage', '/post/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31183, 'p', 'manage', '/post/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31184, 'p', 'manage', '/post/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31185, 'p', 'manage', '/upload/image', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31186, 'p', 'manage', '/hgexample/table/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31187, 'p', 'manage', '/hgexample/table/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31188, 'p', 'manage', '/curdDemo/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31189, 'p', 'manage', '/curdDemo/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31190, 'p', 'manage', '/curdDemo/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31191, 'p', 'manage', '/curdDemo/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31192, 'p', 'manage', '/curdDemo/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31193, 'p', 'manage', '/curdDemo/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31194, 'p', 'manage', '/curdDemo/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31195, 'p', 'manage', '/curdDemo/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31196, 'p', 'manage', '/loginLog/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31197, 'p', 'manage', '/loginLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31198, 'p', 'manage', '/serveLog/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31199, 'p', 'manage', '/serveLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31200, 'p', 'manage', '/notice/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31201, 'p', 'manage', '/notice/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31202, 'p', 'manage', '/notice/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31203, 'p', 'manage', '/notice/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31204, 'p', 'manage', '/notice/editNotify', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31205, 'p', 'manage', '/notice/editNotice', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31206, 'p', 'manage', '/notice/editLetter', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31207, 'p', 'manage', '/notice/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31208, 'p', 'manage', '/test/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31209, 'p', 'manage', '/test/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31210, 'p', 'manage', '/test/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31211, 'p', 'manage', '/test/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31212, 'p', 'manage', '/test/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31213, 'p', 'manage', '/test/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31214, 'p', 'manage', '/order/create', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31215, 'p', 'manage', '/creditsLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31216, 'p', 'manage', '/creditsLog/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31217, 'p', 'manage', '/order/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31218, 'p', 'manage', '/order/acceptRefund', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31219, 'p', 'manage', '/order/applyRefund', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31220, 'p', 'manage', '/order/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31221, 'p', 'manage', '/cash/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31222, 'p', 'manage', '/cash/apply', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31223, 'p', 'manage', '/cash/apply', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31224, 'p', 'manage', '/cash/payment', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31225, 'p', 'manage', '/cash/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31226, 'p', 'manage', '/member/addBalance', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31227, 'p', 'manage', '/member/addIntegral', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31228, 'p', 'manage', '/member/resetPwd', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31229, 'p', 'manage', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31230, 'p', 'manage', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31231, 'p', 'manage', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31232, 'p', 'manage', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31233, 'p', 'manage', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31234, 'p', 'manage', '/config/get', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31235, 'p', 'manage', '/config/update', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31236, 'p', 'manage', '/dictType/tree', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31237, 'p', 'manage', '/dictData/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31238, 'p', 'manage', '/config/typeSelect', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31239, 'p', 'manage', '/dictData/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31240, 'p', 'manage', '/dictData/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31241, 'p', 'manage', '/dictType/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31242, 'p', 'manage', '/dictType/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31243, 'p', 'manage', '/cron/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31244, 'p', 'manage', '/cronGroup/select', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31245, 'p', 'manage', '/cronGroup/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31246, 'p', 'manage', '/cron/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31247, 'p', 'manage', '/cron/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31248, 'p', 'manage', '/cron/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31249, 'p', 'manage', '/cron/onlineExec', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31250, 'p', 'manage', '/cronGroup/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31251, 'p', 'manage', '/cronGroup/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31252, 'p', 'manage', '/blacklist/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31253, 'p', 'manage', '/blacklist/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31254, 'p', 'manage', '/blacklist/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31255, 'p', 'manage', '/blacklist/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31256, 'p', 'gold_agent', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31257, 'p', 'gold_agent', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31258, 'p', 'gold_agent', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31259, 'p', 'gold_agent', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31260, 'p', 'gold_agent', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31261, 'p', 'gold_agent', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31262, 'p', 'gold_agent', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31263, 'p', 'gold_agent', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31264, 'p', 'gold_agent', '/member/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31265, 'p', 'gold_agent', '/member/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31266, 'p', 'gold_agent', '/member/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31267, 'p', 'gold_agent', '/member/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31268, 'p', 'gold_agent', '/order/create', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31269, 'p', 'gold_agent', '/creditsLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31270, 'p', 'gold_agent', '/creditsLog/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31271, 'p', 'gold_agent', '/order/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31272, 'p', 'gold_agent', '/order/acceptRefund', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31273, 'p', 'gold_agent', '/order/applyRefund', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31274, 'p', 'gold_agent', '/order/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31275, 'p', 'gold_agent', '/cash/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31276, 'p', 'gold_agent', '/cash/apply', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31277, 'p', 'gold_agent', '/cash/apply', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31278, 'p', 'gold_agent', '/cash/payment', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31279, 'p', 'gold_agent', '/cash/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31280, 'p', 'gold_agent', '/member/addBalance', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31281, 'p', 'gold_agent', '/member/addIntegral', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31282, 'p', 'gold_agent', '/member/resetPwd', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31283, 'p', 'gold_agent', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31284, 'p', 'gold_agent', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31285, 'p', 'gold_agent', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31286, 'p', 'gold_agent', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31287, 'p', 'gold_agent', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31288, 'p', 'gold_agent', '/member/updatePwd', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31289, 'p', 'gold_agent', '/member/updateMobile', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31290, 'p', 'gold_agent', '/member/updateEmail', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31291, 'p', 'silver_agent', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31292, 'p', 'silver_agent', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31293, 'p', 'silver_agent', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31294, 'p', 'copper_agent', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31295, 'p', 'copper_agent', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31296, 'p', 'copper_agent', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31297, 'p', 'finance', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31298, 'p', 'finance', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31299, 'p', 'finance', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31300, 'p', 'finance', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31301, 'p', 'finance', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31302, 'p', 'finance', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31303, 'p', 'finance', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31304, 'p', 'finance', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31305, 'p', 'finance', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31306, 'p', 'finance', '/menu/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31307, 'p', 'finance', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31308, 'p', 'finance', '/log/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31309, 'p', 'finance', '/log/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31310, 'p', 'finance', '/loginLog/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31311, 'p', 'finance', '/serve_log/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31312, 'p', 'finance', '/notice/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31313, 'p', 'finance', '/attachment/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31314, 'p', 'finance', '/provinces/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31315, 'p', 'finance', '/member/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31316, 'p', 'finance', '/member/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31317, 'p', 'finance', '/member/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31318, 'p', 'finance', '/member/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31319, 'p', 'finance', '/dept/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31320, 'p', 'finance', '/dept/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31321, 'p', 'finance', '/dept/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31322, 'p', 'finance', '/post/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31323, 'p', 'finance', '/post/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31324, 'p', 'finance', '/post/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31325, 'p', 'finance', '/upload/image', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31326, 'p', 'finance', '/hgexample/table/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31327, 'p', 'finance', '/hgexample/table/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31328, 'p', 'finance', '/loginLog/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31329, 'p', 'finance', '/loginLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31330, 'p', 'finance', '/serveLog/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31331, 'p', 'finance', '/serveLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31332, 'p', 'finance', '/notice/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31333, 'p', 'finance', '/notice/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31334, 'p', 'finance', '/notice/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31335, 'p', 'finance', '/notice/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31336, 'p', 'finance', '/notice/editNotify', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31337, 'p', 'finance', '/notice/editNotice', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31338, 'p', 'finance', '/notice/editLetter', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31339, 'p', 'finance', '/notice/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31340, 'p', 'finance', '/test/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31341, 'p', 'finance', '/test/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31342, 'p', 'finance', '/test/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31343, 'p', 'finance', '/test/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31344, 'p', 'finance', '/test/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31345, 'p', 'finance', '/test/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31346, 'p', 'business', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31347, 'p', 'business', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31348, 'p', 'business', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31349, 'p', 'science', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31350, 'p', 'science', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
-(31351, 'p', 'science', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', '');
+(62295, 'p', 'manage', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62296, 'p', 'manage', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62297, 'p', 'manage', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62298, 'p', 'manage', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62299, 'p', 'manage', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62300, 'p', 'manage', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62301, 'p', 'manage', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62302, 'p', 'manage', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62303, 'p', 'manage', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62304, 'p', 'manage', '/menu/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62305, 'p', 'manage', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62306, 'p', 'manage', '/log/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62307, 'p', 'manage', '/loginLog/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62308, 'p', 'manage', '/serve_log/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62309, 'p', 'manage', '/notice/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62310, 'p', 'manage', '/attachment/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62311, 'p', 'manage', '/provinces/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62312, 'p', 'manage', '/member/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62313, 'p', 'manage', '/member/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62314, 'p', 'manage', '/member/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62315, 'p', 'manage', '/member/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62316, 'p', 'manage', '/dept/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62317, 'p', 'manage', '/dept/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62318, 'p', 'manage', '/dept/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62319, 'p', 'manage', '/post/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62320, 'p', 'manage', '/post/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62321, 'p', 'manage', '/post/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62322, 'p', 'manage', '/upload/image', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62323, 'p', 'manage', '/hgexample/table/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62324, 'p', 'manage', '/hgexample/table/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62325, 'p', 'manage', '/curdDemo/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62326, 'p', 'manage', '/curdDemo/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62327, 'p', 'manage', '/curdDemo/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62328, 'p', 'manage', '/curdDemo/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62329, 'p', 'manage', '/curdDemo/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62330, 'p', 'manage', '/curdDemo/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62331, 'p', 'manage', '/curdDemo/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62332, 'p', 'manage', '/curdDemo/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62333, 'p', 'manage', '/loginLog/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62334, 'p', 'manage', '/loginLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62335, 'p', 'manage', '/serveLog/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62336, 'p', 'manage', '/serveLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62337, 'p', 'manage', '/notice/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62338, 'p', 'manage', '/notice/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62339, 'p', 'manage', '/notice/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62340, 'p', 'manage', '/notice/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62341, 'p', 'manage', '/notice/editNotify', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62342, 'p', 'manage', '/notice/editNotice', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62343, 'p', 'manage', '/notice/editLetter', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62344, 'p', 'manage', '/notice/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62345, 'p', 'manage', '/test/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62346, 'p', 'manage', '/test/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62347, 'p', 'manage', '/test/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62348, 'p', 'manage', '/test/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62349, 'p', 'manage', '/test/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62350, 'p', 'manage', '/test/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62351, 'p', 'manage', '/order/create', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62352, 'p', 'manage', '/creditsLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62353, 'p', 'manage', '/creditsLog/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62354, 'p', 'manage', '/order/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62355, 'p', 'manage', '/order/acceptRefund', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62356, 'p', 'manage', '/order/applyRefund', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62357, 'p', 'manage', '/order/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62358, 'p', 'manage', '/cash/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62359, 'p', 'manage', '/cash/apply', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62360, 'p', 'manage', '/cash/apply', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62361, 'p', 'manage', '/cash/payment', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62362, 'p', 'manage', '/cash/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62363, 'p', 'manage', '/member/addBalance', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62364, 'p', 'manage', '/member/addIntegral', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62365, 'p', 'manage', '/member/resetPwd', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62366, 'p', 'manage', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62367, 'p', 'manage', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62368, 'p', 'manage', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62369, 'p', 'manage', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62370, 'p', 'manage', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62371, 'p', 'manage', '/config/get', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62372, 'p', 'manage', '/config/update', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62373, 'p', 'manage', '/dictType/tree', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62374, 'p', 'manage', '/dictData/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62375, 'p', 'manage', '/config/typeSelect', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62376, 'p', 'manage', '/dictData/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62377, 'p', 'manage', '/dictData/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62378, 'p', 'manage', '/dictType/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62379, 'p', 'manage', '/dictType/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62380, 'p', 'manage', '/cron/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62381, 'p', 'manage', '/cronGroup/select', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62382, 'p', 'manage', '/cronGroup/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62383, 'p', 'manage', '/cron/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62384, 'p', 'manage', '/cron/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62385, 'p', 'manage', '/cron/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62386, 'p', 'manage', '/cron/onlineExec', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62387, 'p', 'manage', '/cronGroup/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62388, 'p', 'manage', '/cronGroup/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62389, 'p', 'manage', '/blacklist/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62390, 'p', 'manage', '/blacklist/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62391, 'p', 'manage', '/blacklist/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62392, 'p', 'manage', '/blacklist/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62393, 'p', 'gold_agent', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62394, 'p', 'gold_agent', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62395, 'p', 'gold_agent', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62396, 'p', 'gold_agent', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62397, 'p', 'gold_agent', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62398, 'p', 'gold_agent', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62399, 'p', 'gold_agent', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62400, 'p', 'gold_agent', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62401, 'p', 'gold_agent', '/member/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62402, 'p', 'gold_agent', '/member/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62403, 'p', 'gold_agent', '/member/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62404, 'p', 'gold_agent', '/member/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62405, 'p', 'gold_agent', '/order/create', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62406, 'p', 'gold_agent', '/creditsLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62407, 'p', 'gold_agent', '/creditsLog/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62408, 'p', 'gold_agent', '/order/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62409, 'p', 'gold_agent', '/order/acceptRefund', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62410, 'p', 'gold_agent', '/order/applyRefund', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62411, 'p', 'gold_agent', '/order/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62412, 'p', 'gold_agent', '/cash/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62413, 'p', 'gold_agent', '/cash/apply', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62414, 'p', 'gold_agent', '/cash/apply', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62415, 'p', 'gold_agent', '/cash/payment', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62416, 'p', 'gold_agent', '/cash/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62417, 'p', 'gold_agent', '/member/addBalance', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62418, 'p', 'gold_agent', '/member/addIntegral', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62419, 'p', 'gold_agent', '/member/resetPwd', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62420, 'p', 'gold_agent', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62421, 'p', 'gold_agent', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62422, 'p', 'gold_agent', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62423, 'p', 'gold_agent', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62424, 'p', 'gold_agent', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62425, 'p', 'gold_agent', '/member/updatePwd', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62426, 'p', 'gold_agent', '/member/updateMobile', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62427, 'p', 'gold_agent', '/member/updateEmail', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62428, 'p', 'silver_agent', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62429, 'p', 'silver_agent', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62430, 'p', 'silver_agent', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62431, 'p', 'copper_agent', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62432, 'p', 'copper_agent', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62433, 'p', 'copper_agent', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62434, 'p', 'finance', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62435, 'p', 'finance', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62436, 'p', 'finance', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62437, 'p', 'finance', '/dept/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62438, 'p', 'finance', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62439, 'p', 'finance', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62440, 'p', 'finance', '/member/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62441, 'p', 'finance', '/dept/option', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62442, 'p', 'finance', '/post/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62443, 'p', 'finance', '/menu/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62444, 'p', 'finance', '/role/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62445, 'p', 'finance', '/log/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62446, 'p', 'finance', '/loginLog/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62447, 'p', 'finance', '/serve_log/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62448, 'p', 'finance', '/notice/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62449, 'p', 'finance', '/attachment/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62450, 'p', 'finance', '/provinces/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62451, 'p', 'finance', '/member/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62452, 'p', 'finance', '/member/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62453, 'p', 'finance', '/member/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62454, 'p', 'finance', '/member/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62455, 'p', 'finance', '/dept/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62456, 'p', 'finance', '/dept/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62457, 'p', 'finance', '/dept/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62458, 'p', 'finance', '/post/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62459, 'p', 'finance', '/post/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62460, 'p', 'finance', '/post/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62461, 'p', 'finance', '/upload/image', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62462, 'p', 'finance', '/hgexample/table/list', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62463, 'p', 'finance', '/hgexample/table/view', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62464, 'p', 'finance', '/loginLog/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62465, 'p', 'finance', '/loginLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62466, 'p', 'finance', '/serveLog/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62467, 'p', 'finance', '/serveLog/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62468, 'p', 'finance', '/notice/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62469, 'p', 'finance', '/notice/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62470, 'p', 'finance', '/notice/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62471, 'p', 'finance', '/notice/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62472, 'p', 'finance', '/notice/editNotify', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62473, 'p', 'finance', '/notice/editNotice', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62474, 'p', 'finance', '/notice/editLetter', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62475, 'p', 'finance', '/notice/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62476, 'p', 'finance', '/test/maxSort', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62477, 'p', 'finance', '/test/export', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62478, 'p', 'finance', '/test/delete', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62479, 'p', 'finance', '/test/status', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62480, 'p', 'finance', '/test/switch', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62481, 'p', 'finance', '/test/edit', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62482, 'p', 'business', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62483, 'p', 'business', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62484, 'p', 'business', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62485, 'p', 'science', 'dashboard', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62486, 'p', 'science', '/console/stat', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', ''),
+(62487, 'p', 'science', 'dashboard_workplace', 'GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD', '', '', '');
-- --------------------------------------------------------
@@ -1197,31 +1217,24 @@ INSERT INTO `hg_sys_addons_install` (`id`, `name`, `version`, `status`, `created
CREATE TABLE `hg_sys_attachment` (
`id` bigint(20) NOT NULL COMMENT '文件ID',
- `app_id` varchar(255) NOT NULL COMMENT '应用ID',
+ `app_id` varchar(64) NOT NULL COMMENT '应用ID',
`member_id` bigint(20) DEFAULT '0' COMMENT '管理员ID',
`cate_id` bigint(20) UNSIGNED DEFAULT '0' COMMENT '上传分类',
- `drive` varchar(50) DEFAULT NULL COMMENT '上传驱动',
+ `drive` varchar(64) DEFAULT NULL COMMENT '上传驱动',
`name` varchar(1000) DEFAULT NULL COMMENT '文件原始名',
- `kind` varchar(10) DEFAULT NULL COMMENT '上传类型',
- `meta_type` varchar(100) NOT NULL DEFAULT '' COMMENT '文件类型',
- `naive_type` varchar(64) NOT NULL COMMENT 'NaiveUI类型',
+ `kind` varchar(16) DEFAULT NULL COMMENT '上传类型',
+ `mime_type` varchar(128) NOT NULL DEFAULT '' COMMENT '扩展类型',
+ `naive_type` varchar(32) NOT NULL COMMENT 'NaiveUI类型',
`path` varchar(1000) DEFAULT NULL COMMENT '本地路径',
`file_url` varchar(1000) DEFAULT NULL COMMENT 'url',
`size` bigint(20) DEFAULT '0' COMMENT '文件大小',
`ext` varchar(50) DEFAULT NULL COMMENT '扩展名',
- `md5` varchar(100) DEFAULT NULL COMMENT 'md5校验码',
+ `md5` varchar(32) DEFAULT NULL COMMENT 'md5校验码',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '修改时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统_附件管理';
---
--- 转存表中的数据 `hg_sys_attachment`
---
-
-INSERT INTO `hg_sys_attachment` (`id`, `app_id`, `member_id`, `cate_id`, `drive`, `name`, `kind`, `meta_type`, `naive_type`, `path`, `file_url`, `size`, `ext`, `md5`, `status`, `created_at`, `updated_at`) VALUES
-(55, 'admin', 1, 0, 'local', 'logo.png', 'images', 'image/png', '', 'attachment/2023-05-14/csltf747yrr4gd4kc5.png', 'attachment/2023-05-14/csltf747yrr4gd4kc5.png', 38601, 'png', '492c0e0f0eb8e7e6c7b6901d32854d19', 1, '2023-05-14 15:17:25', '2023-05-14 15:17:25');
-
-- --------------------------------------------------------
--
@@ -1279,12 +1292,12 @@ INSERT INTO `hg_sys_config` (`id`, `group`, `name`, `type`, `key`, `value`, `def
(1, 'theme', '默认主题', 'string', 'themeDarkTheme', 'dark', 'dark', 50, '', 1, 1, '2021-01-30 13:27:43', '2022-09-05 20:29:05'),
(2, 'theme', '默认系统主题', 'string', 'themeAppTheme', '#2d8cf0', '#2d8cf0', 60, '', 1, 1, '2021-01-30 13:27:43', '2022-09-05 20:29:05'),
(3, 'theme', '默认侧边栏风格', 'string', 'themeNavTheme', 'light', 'dark', 70, '', 1, 1, '2021-01-30 13:27:43', '2022-09-05 20:29:05'),
-(6, 'basic', '网站名称', 'string', 'basicName', 'HotGo', 'HotGo!', 10, '', 1, 1, '2021-01-30 13:27:43', '2023-04-30 20:38:06'),
-(7, 'basic', '网站logo', 'string', 'basicLogo', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', '', 20, '首页使用', 1, 1, '2021-01-30 13:27:43', '2023-04-30 20:38:06'),
-(8, 'basic', '网站备案号', 'string', 'basicIcpCode', '豫ICP备16035288号', '', 30, '', 1, 1, '2021-01-30 13:27:43', '2023-04-30 20:38:06'),
-(9, 'basic', '网站开启访问', 'bool', 'basicSystemOpen', '1', 'true', 50, '', 1, 1, '2021-01-30 13:27:43', '2023-04-30 20:38:06'),
-(10, 'basic', '网站关闭提示', 'string', 'basicCloseText', '网站维护中,暂时无法访问!本网站正在进行系统维护和技术升级,网站暂时无法访问,敬请谅解!', '网站维护中,暂时无法访问!本网站正在进行系统维护和技术升级,网站暂时无法访问,敬请谅解!', 60, '', 1, 1, '2021-01-30 13:27:43', '2023-04-30 20:38:06'),
-(11, 'basic', '版权所有', 'string', 'basicCopyright', '© 2019 - 2023 HotGo All Rights Reserved.', '© 2021 - 2023 HotGo All Rights Reserved.', 40, '', 1, 1, '2021-01-30 13:27:43', '2023-04-30 20:38:06'),
+(6, 'basic', '网站名称', 'string', 'basicName', 'HotGo', 'HotGo!', 10, '', 1, 1, '2021-01-30 13:27:43', '2023-07-19 10:19:16'),
+(7, 'basic', '网站logo', 'string', 'basicLogo', 'http://localhost:8000/attachment/2023-07-18/cu4xo65svzsoz0zapn.jpg', '', 20, '首页使用', 1, 1, '2021-01-30 13:27:43', '2023-07-19 10:19:16'),
+(8, 'basic', '网站备案号', 'string', 'basicIcpCode', '豫ICP备16035288号', '', 30, '', 1, 1, '2021-01-30 13:27:43', '2023-07-19 10:19:16'),
+(9, 'basic', '网站开启访问', 'bool', 'basicSystemOpen', '1', 'true', 50, '', 1, 1, '2021-01-30 13:27:43', '2023-07-19 10:19:16'),
+(10, 'basic', '网站关闭提示', 'string', 'basicCloseText', '网站维护中,暂时无法访问!本网站正在进行系统维护和技术升级,网站暂时无法访问,敬请谅解!', '网站维护中,暂时无法访问!本网站正在进行系统维护和技术升级,网站暂时无法访问,敬请谅解!', 60, '', 1, 1, '2021-01-30 13:27:43', '2023-07-19 10:19:16'),
+(11, 'basic', '版权所有', 'string', 'basicCopyright', '© 2019 - 2023 HotGo All Rights Reserved.', '© 2021 - 2023 HotGo All Rights Reserved.', 40, '', 1, 1, '2021-01-30 13:27:43', '2023-07-19 10:19:16'),
(12, 'smtp', 'SMTP服务器', 'string', 'smtpHost', 'smtpdm.aliyun.com', 'smtpdm.aliyun.com', 50, '错误的配置发送邮件会导致服务器超时', 1, 1, '2021-01-30 13:27:43', '2023-02-04 16:59:13'),
(13, 'smtp', 'SMTP端口', 'int', 'smtpPort', '25', '25', 100, '(不加密默认25,SSL默认465,TLS默认587)', 1, 1, '2021-01-30 13:27:43', '2023-02-04 16:59:13'),
(14, 'smtp', 'SMTP用户名', 'string', 'smtpUser', 'ali@mail.qvnidaye.com', '', 110, '填写完整用户名', 1, 1, '2021-01-30 13:27:43', '2023-02-04 16:59:13'),
@@ -1317,8 +1330,8 @@ INSERT INTO `hg_sys_config` (`id`, `group`, `name`, `type`, `key`, `value`, `def
(51, 'smtp', '最小发送间隔', 'int', 'smtpMinInterval', '60', '', 150, '同地址', 1, 1, '2021-01-30 13:27:43', '2023-02-04 16:59:13'),
(52, 'smtp', 'IP最大发送次数', 'int', 'smtpMaxIpLimit', '10', '', 160, '同IP每天最大允许发送次数', 1, 1, '2021-01-30 13:27:43', '2023-02-04 16:59:13'),
(53, 'smtp', '验证码有效期', 'int', 'smtpCodeExpire', '600', '', 170, '单位:秒', 1, 1, '2021-01-30 13:27:43', '2023-02-04 16:59:13'),
-(54, 'basic', '网站域名', 'string', 'basicDomain', 'https://hotgo.facms.cn', 'https://hotgo.facms.cn', 45, '', 1, 1, '2021-01-30 13:27:43', '2023-04-30 20:38:06'),
-(55, 'basic', 'websocket地址', 'string', 'basicWsAddr', 'wss://hotgo.facms.cn/socket', 'wss://hotgo.facms.cn/socket', 48, '', 1, 1, '2021-01-30 13:27:43', '2023-04-30 20:38:06'),
+(54, 'basic', '网站域名', 'string', 'basicDomain', 'https://hotgo.facms.cn', 'https://hotgo.facms.cn', 45, '', 1, 1, '2021-01-30 13:27:43', '2023-07-19 10:19:16'),
+(55, 'basic', 'websocket地址', 'string', 'basicWsAddr', 'wss://hotgo.facms.cn/socket', 'wss://hotgo.facms.cn/socket', 48, '', 1, 1, '2021-01-30 13:27:43', '2023-07-19 10:19:16'),
(56, 'upload', 'COS存储路径', 'string', 'uploadCosPath', 'hotgo/attachment/', 'hotgo/attachment/', 450, 'COS对象存储中的相对路径', 1, 1, '2021-01-30 13:27:43', '2023-03-20 17:41:17'),
(57, 'upload', 'COS秘钥ID', 'string', 'uploadCosSecretId', '', '', 460, '子账号密钥获取可参考 https://cloud.tencent.com/document/product/598/37140', 1, 1, '2021-01-30 13:27:43', '2023-03-20 17:41:17'),
(58, 'upload', 'COS秘钥', 'string', 'uploadCosSecretKey', '', '', 470, '', 1, 1, '2021-01-30 13:27:43', '2023-03-20 17:41:17'),
@@ -1433,7 +1446,7 @@ CREATE TABLE `hg_sys_cron_group` (
INSERT INTO `hg_sys_cron_group` (`id`, `pid`, `name`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES
(1, 0, '系统默认', 1, 0, '这是系统默认的任务分组,无法删除!', 1, '2021-02-25 17:38:07', '2021-02-25 19:32:57'),
-(2, 0, '测试', 0, 0, '这是测试任务分组', 1, '2021-02-25 17:38:07', '2021-02-25 19:32:57');
+(2, 0, '测试', 0, 0, '这是测试任务分组', 1, NULL, '2023-05-29 14:59:39');
-- --------------------------------------------------------
@@ -1536,7 +1549,7 @@ INSERT INTO `hg_sys_dict_data` (`id`, `label`, `value`, `value_type`, `type`, `l
(150, '重置密码', 'resetPwd', 'string', 'config_ems_template', 'error', 0, 40, '', 1, '2023-01-21 10:29:10', '2023-01-21 10:29:10'),
(151, '绑定手机号', 'bind', 'string', 'config_ems_template', 'info', 0, 50, '', 1, '2023-01-21 10:29:22', '2023-01-21 10:29:22'),
(152, '申请提现', 'cash', 'string', 'config_ems_template', 'primary', 0, 60, '', 1, '2023-01-21 10:29:36', '2023-01-21 10:29:40'),
-(153, '富文本', 'text', 'string', 'config_ems_template', 'default', 0, 0, '自定义编辑邮件内容时使用', 1, '2023-01-21 10:29:36', '2023-02-04 12:55:19'),
+(153, '富文本', 'text', 'string', 'config_ems_template', 'default', 0, 0, '自定义编辑邮件内容时使用', 1, '2023-01-21 10:29:36', '2023-05-29 14:30:49'),
(154, '腾讯云', 'cos', 'string', 'config_upload_drive', 'info', 1, 30, '', 1, '2022-12-30 17:58:26', '2022-12-30 17:58:26'),
(155, '阿里云', 'oss', 'string', 'config_upload_drive', 'info', 1, 40, '', 1, '2022-12-30 17:58:26', '2022-12-30 17:58:26'),
(156, '七牛云', 'qiniu', 'string', 'config_upload_drive', 'success', 1, 50, '', 1, '2022-12-30 17:58:26', '2022-12-30 17:58:26');
@@ -1581,7 +1594,7 @@ INSERT INTO `hg_sys_dict_type` (`id`, `pid`, `name`, `type`, `sort`, `remark`, `
(29, 0, '通知枚举', 'notice', 50, '', 1, '2022-01-24 11:33:16', '2022-01-24 11:33:16'),
(30, 27, '用户爱好', 'sys_user_hobby', 0, NULL, 1, '2021-03-01 11:41:07', '2021-03-01 11:41:07'),
(31, 27, '用户渠道', 'sys_user_channel', 0, NULL, 1, '2021-03-01 11:41:07', '2021-03-01 11:41:07'),
-(32, 0, '配置枚举', 'config', 60, '', 1, '2022-12-30 17:55:42', '2022-12-30 17:55:53'),
+(32, 0, '配置枚举', 'config', 60, '', 1, '2022-12-30 17:55:42', '2023-05-29 14:47:01'),
(33, 32, '上传驱动', 'config_upload_drive', 10, '', 1, '2022-12-30 17:57:18', '2022-12-30 17:57:18'),
(34, 28, '日志类型', 'sys_log_type', 50, '', 1, '2023-01-20 16:39:52', '2023-02-24 17:40:45'),
(35, 32, '短信驱动', 'config_sms_drive', 20, '', 1, '2023-01-21 10:27:01', '2023-01-21 10:27:01'),
@@ -1643,7 +1656,7 @@ CREATE TABLE `hg_sys_gen_codes` (
--
INSERT INTO `hg_sys_gen_codes` (`id`, `gen_type`, `gen_template`, `var_name`, `options`, `db_name`, `table_name`, `table_comment`, `dao_name`, `master_columns`, `addon_name`, `status`, `created_at`, `updated_at`) VALUES
-(1, 10, 0, 'CurdDemo', '{\"join\": [{\"uuid\": \"pgJsFoqfaGjqgKjy\", \"alias\": \"testCategory\", \"field\": \"id\", \"columns\": [{\"dc\": \"分类ID\", \"id\": 1, \"name\": \"id\", \"extra\": \"auto_increment\", \"index\": \"PRI\", \"goName\": \"TestCategoryId\", \"goType\": \"int64\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryId\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"分类名称\", \"id\": 2, \"name\": \"name\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryName\", \"goType\": \"string\", \"isEdit\": false, \"isList\": true, \"isSort\": false, \"length\": 255, \"tsName\": \"testCategoryName\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": true, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": true, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"NO\", \"defaultValue\": \"\"}, {\"dc\": \"描述\", \"id\": 3, \"name\": \"description\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryDescription\", \"goType\": \"string\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 255, \"tsName\": \"testCategoryDescription\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"排序\", \"id\": 4, \"name\": \"sort\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategorySort\", \"goType\": \"int\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategorySort\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"int(11)\", \"dataType\": \"int\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"备注\", \"id\": 5, \"name\": \"remark\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryRemark\", \"goType\": \"string\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 255, \"tsName\": \"testCategoryRemark\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"状态\", \"id\": 6, \"name\": \"status\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryStatus\", \"goType\": \"int\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryStatus\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"tinyint(1)\", \"dataType\": \"tinyint\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 1}, {\"dc\": \"创建时间\", \"id\": 7, \"name\": \"created_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryCreatedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryCreatedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"修改时间\", \"id\": 8, \"name\": \"updated_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryUpdatedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryUpdatedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"删除时间\", \"id\": 9, \"name\": \"deleted_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryDeletedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryDeletedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}], \"daoName\": \"TestCategory\", \"linkMode\": 1, \"linkTable\": \"hg_test_category\", \"masterField\": \"category_id\"}], \"menu\": {\"pid\": 2097, \"icon\": \"MenuOutlined\", \"sort\": 200}, \"autoOps\": [\"genMenuPermissions\", \"runDao\", \"runService\", \"forcedCover\"], \"headOps\": [\"add\", \"batchDel\", \"export\"], \"columnOps\": [\"edit\", \"del\", \"view\", \"status\", \"switch\", \"check\"]}', 'default', 'hg_sys_gen_curd_demo', '生成演示', 'SysGenCurdDemo', '[{\"dc\": \"ID\", \"id\": 1, \"name\": \"id\", \"extra\": \"auto_increment\", \"index\": \"PRI\", \"goName\": \"Id\", \"goType\": \"int64\", \"isEdit\": false, \"isList\": true, \"isSort\": true, \"length\": 0, \"tsName\": \"id\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": true, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"分类ID\", \"id\": 2, \"name\": \"category_id\", \"extra\": \"\", \"index\": \"\", \"goName\": \"CategoryId\", \"goType\": \"int64\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"categoryId\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"标题\", \"id\": 3, \"name\": \"title\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Title\", \"goType\": \"string\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 64, \"tsName\": \"title\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(64)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"Input\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"NO\", \"defaultValue\": \"\"}, {\"dc\": \"描述\", \"id\": 4, \"name\": \"description\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Description\", \"goType\": \"string\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 255, \"tsName\": \"description\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"InputTextarea\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"NO\", \"defaultValue\": \"\"}, {\"dc\": \"内容\", \"id\": 5, \"name\": \"content\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Content\", \"goType\": \"string\", \"isEdit\": true, \"isList\": false, \"isSort\": false, \"length\": 65535, \"tsName\": \"content\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"text\", \"dataType\": \"text\", \"dictType\": 0, \"formMode\": \"InputEditor\", \"formRole\": \"none\", \"isExport\": false, \"required\": false, \"queryWhere\": \"LIKE %...%\", \"isAllowNull\": \"NO\", \"defaultValue\": \"\"}, {\"dc\": \"单图\", \"id\": 6, \"name\": \"image\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Image\", \"goType\": \"string\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 255, \"tsName\": \"image\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"UploadImage\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"附件\", \"id\": 7, \"name\": \"attachfile\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Attachfile\", \"goType\": \"string\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 255, \"tsName\": \"attachfile\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"UploadFile\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"所在城市\", \"id\": 8, \"name\": \"city_id\", \"extra\": \"\", \"index\": \"\", \"goName\": \"CityId\", \"goType\": \"int64\", \"isEdit\": true, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"cityId\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"CitySelector\", \"formRole\": \"none\", \"isExport\": false, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 0}, {\"dc\": \"显示开关\", \"id\": 9, \"name\": \"switch\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Switch\", \"goType\": \"int\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"switch\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"int(11)\", \"dataType\": \"int\", \"dictType\": 0, \"formMode\": \"Switch\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 1}, {\"dc\": \"排序\", \"id\": 10, \"name\": \"sort\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Sort\", \"goType\": \"int\", \"isEdit\": true, \"isList\": true, \"isSort\": true, \"length\": 0, \"tsName\": \"sort\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"int(11)\", \"dataType\": \"int\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"状态\", \"id\": 11, \"name\": \"status\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Status\", \"goType\": \"int\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"status\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": true, \"sqlType\": \"tinyint(1)\", \"dataType\": \"tinyint\", \"dictType\": 3, \"formMode\": \"Select\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 1}, {\"dc\": \"创建者\", \"id\": 12, \"name\": \"created_by\", \"extra\": \"\", \"index\": \"\", \"goName\": \"CreatedBy\", \"goType\": \"int64\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"createdBy\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 0}, {\"dc\": \"更新者\", \"id\": 13, \"name\": \"updated_by\", \"extra\": \"\", \"index\": \"\", \"goName\": \"UpdatedBy\", \"goType\": \"int64\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"updatedBy\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 0}, {\"dc\": \"创建时间\", \"id\": 14, \"name\": \"created_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"CreatedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"createdAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": true, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"TimeRange\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"BETWEEN\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"修改时间\", \"id\": 15, \"name\": \"updated_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"UpdatedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"updatedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"Time\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"删除时间\", \"id\": 16, \"name\": \"deleted_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"DeletedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"deletedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"Time\", \"formRole\": \"none\", \"isExport\": false, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}]', '', 1, '2023-01-18 11:51:22', '2023-04-28 15:28:40');
+(1, 10, 0, 'CurdDemo', '{\"join\": [{\"uuid\": \"pgJsFoqfaGjqgKjy\", \"alias\": \"testCategory\", \"field\": \"id\", \"columns\": [{\"dc\": \"分类ID\", \"id\": 1, \"name\": \"id\", \"extra\": \"auto_increment\", \"index\": \"PRI\", \"goName\": \"TestCategoryId\", \"goType\": \"int64\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryId\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"分类名称\", \"id\": 2, \"name\": \"name\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryName\", \"goType\": \"string\", \"isEdit\": false, \"isList\": true, \"isSort\": false, \"length\": 255, \"tsName\": \"testCategoryName\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": true, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": true, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"NO\", \"defaultValue\": \"\"}, {\"dc\": \"描述\", \"id\": 3, \"name\": \"description\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryDescription\", \"goType\": \"string\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 255, \"tsName\": \"testCategoryDescription\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"排序\", \"id\": 4, \"name\": \"sort\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategorySort\", \"goType\": \"int\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategorySort\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"int(11)\", \"dataType\": \"int\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"备注\", \"id\": 5, \"name\": \"remark\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryRemark\", \"goType\": \"string\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 255, \"tsName\": \"testCategoryRemark\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"状态\", \"id\": 6, \"name\": \"status\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryStatus\", \"goType\": \"int\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryStatus\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"tinyint(1)\", \"dataType\": \"tinyint\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 1}, {\"dc\": \"创建时间\", \"id\": 7, \"name\": \"created_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryCreatedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryCreatedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"修改时间\", \"id\": 8, \"name\": \"updated_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryUpdatedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryUpdatedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"删除时间\", \"id\": 9, \"name\": \"deleted_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"TestCategoryDeletedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"testCategoryDeletedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"\", \"formRole\": \"\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}], \"daoName\": \"TestCategory\", \"linkMode\": 1, \"linkTable\": \"hg_test_category\", \"masterField\": \"category_id\"}], \"menu\": {\"pid\": 2097, \"icon\": \"MenuOutlined\", \"sort\": 200}, \"autoOps\": [\"genMenuPermissions\", \"runDao\", \"runService\", \"forcedCover\"], \"headOps\": [\"add\", \"batchDel\", \"export\"], \"columnOps\": [\"edit\", \"del\", \"view\", \"status\", \"switch\", \"check\"]}', 'default', 'hg_sys_gen_curd_demo', '生成演示', 'SysGenCurdDemo', '[{\"dc\": \"ID\", \"id\": 1, \"name\": \"id\", \"extra\": \"auto_increment\", \"index\": \"PRI\", \"goName\": \"Id\", \"goType\": \"int64\", \"isEdit\": false, \"isList\": true, \"isSort\": true, \"length\": 0, \"tsName\": \"id\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": true, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"分类ID\", \"id\": 2, \"name\": \"category_id\", \"extra\": \"\", \"index\": \"\", \"goName\": \"CategoryId\", \"goType\": \"int64\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"categoryId\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"标题\", \"id\": 3, \"name\": \"title\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Title\", \"goType\": \"string\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 64, \"tsName\": \"title\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(64)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"Input\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"NO\", \"defaultValue\": \"\"}, {\"dc\": \"描述\", \"id\": 4, \"name\": \"description\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Description\", \"goType\": \"string\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 255, \"tsName\": \"description\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"InputTextarea\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"NO\", \"defaultValue\": \"\"}, {\"dc\": \"内容\", \"id\": 5, \"name\": \"content\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Content\", \"goType\": \"string\", \"isEdit\": true, \"isList\": false, \"isSort\": false, \"length\": 65535, \"tsName\": \"content\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"text\", \"dataType\": \"text\", \"dictType\": 0, \"formMode\": \"InputEditor\", \"formRole\": \"none\", \"isExport\": false, \"required\": true, \"queryWhere\": \"LIKE %...%\", \"isAllowNull\": \"NO\", \"defaultValue\": \"\"}, {\"dc\": \"单图\", \"id\": 6, \"name\": \"image\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Image\", \"goType\": \"string\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 255, \"tsName\": \"image\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"UploadImage\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"附件\", \"id\": 7, \"name\": \"attachfile\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Attachfile\", \"goType\": \"string\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 255, \"tsName\": \"attachfile\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"varchar(255)\", \"dataType\": \"varchar\", \"dictType\": 0, \"formMode\": \"UploadFile\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"LIKE\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"所在城市\", \"id\": 8, \"name\": \"city_id\", \"extra\": \"\", \"index\": \"\", \"goName\": \"CityId\", \"goType\": \"int64\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"cityId\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"CitySelector\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 0}, {\"dc\": \"显示开关\", \"id\": 9, \"name\": \"switch\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Switch\", \"goType\": \"int\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"switch\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"int(11)\", \"dataType\": \"int\", \"dictType\": 0, \"formMode\": \"Switch\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 1}, {\"dc\": \"排序\", \"id\": 10, \"name\": \"sort\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Sort\", \"goType\": \"int\", \"isEdit\": true, \"isList\": true, \"isSort\": true, \"length\": 0, \"tsName\": \"sort\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"int(11)\", \"dataType\": \"int\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": true, \"queryWhere\": \"=\", \"isAllowNull\": \"NO\", \"defaultValue\": 0}, {\"dc\": \"状态\", \"id\": 11, \"name\": \"status\", \"extra\": \"\", \"index\": \"\", \"goName\": \"Status\", \"goType\": \"int\", \"isEdit\": true, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"status\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": true, \"sqlType\": \"tinyint(1)\", \"dataType\": \"tinyint\", \"dictType\": 3, \"formMode\": \"Select\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 1}, {\"dc\": \"创建者\", \"id\": 12, \"name\": \"created_by\", \"extra\": \"\", \"index\": \"\", \"goName\": \"CreatedBy\", \"goType\": \"int64\", \"isEdit\": false, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"createdBy\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 0}, {\"dc\": \"更新者\", \"id\": 13, \"name\": \"updated_by\", \"extra\": \"\", \"index\": \"\", \"goName\": \"UpdatedBy\", \"goType\": \"int64\", \"isEdit\": false, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"updatedBy\", \"tsType\": \"number\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"bigint(20)\", \"dataType\": \"bigint\", \"dictType\": 0, \"formMode\": \"InputNumber\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": 0}, {\"dc\": \"创建时间\", \"id\": 14, \"name\": \"created_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"CreatedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"createdAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": true, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"TimeRange\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"BETWEEN\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"修改时间\", \"id\": 15, \"name\": \"updated_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"UpdatedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": true, \"isSort\": false, \"length\": 0, \"tsName\": \"updatedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"Time\", \"formRole\": \"none\", \"isExport\": true, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}, {\"dc\": \"删除时间\", \"id\": 16, \"name\": \"deleted_at\", \"extra\": \"\", \"index\": \"\", \"goName\": \"DeletedAt\", \"goType\": \"*gtime.Time\", \"isEdit\": false, \"isList\": false, \"isSort\": false, \"length\": 0, \"tsName\": \"deletedAt\", \"tsType\": \"string\", \"unique\": false, \"isQuery\": false, \"sqlType\": \"datetime\", \"dataType\": \"datetime\", \"dictType\": 0, \"formMode\": \"Time\", \"formRole\": \"none\", \"isExport\": false, \"required\": false, \"queryWhere\": \"=\", \"isAllowNull\": \"YES\", \"defaultValue\": \"\"}]', '', 1, '2023-01-18 11:51:22', '2023-07-20 15:25:46');
-- --------------------------------------------------------
@@ -1675,7 +1688,7 @@ CREATE TABLE `hg_sys_gen_curd_demo` (
--
INSERT INTO `hg_sys_gen_curd_demo` (`id`, `category_id`, `title`, `description`, `content`, `image`, `attachfile`, `city_id`, `switch`, `sort`, `status`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`) VALUES
-(1, 1, '测试标题', '描述', '不知道写点啥!
', 'https://bufanyun.cn-bj.ufileos.com/hotgo/logo.sig.png', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2022-12-30/cpf1x44idoycrtajf2.xlsx', 110102, 1, 10, 1, 0, 1, '2022-12-15 19:30:14', '2023-05-08 23:19:49', NULL);
+(1, 1, '测试标题', '描述', '不知道写点啥!
', 'https://bufanyun.cn-bj.ufileos.com/hotgo/logo.sig.png', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2022-12-30/cpf1x44idoycrtajf2.xlsx', 110102, 1, 10, 1, 0, 1, '2022-12-15 19:30:14', '2023-07-06 20:31:29', NULL);
-- --------------------------------------------------------
@@ -1967,20 +1980,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(830900, '嘉义市', 'J', '121.97387097872', '24.086956718805', 830000, 2, 'tr_0 tr_830000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(830901, '东区', 'D', '114.2466374103', '22.728825804821', 830900, 3, 'tr_0 tr_830000 tr_830900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(830902, '西区', 'X', '114.2466374103', '22.728825804821', 830900, 3, 'tr_0 tr_830000 tr_830900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839001, '宜兰县', 'Y', '121.39369436652', '31.211883015985', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839002, '新竹县', 'X', '119.76701381388', '49.221741849328', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839003, '苗栗县', 'M', '', '', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839004, '彰化县', 'Z', '109.04292985822', '26.632603089128', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839005, '南投县', 'N', '', '', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839006, '嘉义县', 'J', '114.2466374103', '22.728825804821', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839007, '云林县', 'Y', '124.7995182988', '42.918396678776', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839008, '屏东县', 'P', '119.30846756124', '26.107056743573', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839009, '台东县', 'T', '119.33983605008', '26.095631255982', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839010, '花莲县', 'H', '120.16162991211', '33.366606824641', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839011, '澎湖县', 'P', '121.13156576447', '30.875327117717', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839012, '金门县', 'J', '118.3304151596', '24.440444541055', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(839013, '连江县', 'L', '119.54647881621', '26.203583291029', 839000, 3, 'tr_0 tr_830000 tr_839000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(110000, '北京市', 'B', '116.41338369712', '39.9109245473', 0, 1, 'tr_0 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(110000, '北京市', 'B', '116.41338369712', '39.9109245473', 0, 1, '', 0, 1, '2022-10-07 20:42:26', '2023-05-29 16:02:45'),
(120000, '天津市', 'T', '117.21081309155', '39.14392990331', 0, 1, 'tr_0 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(130000, '河北省', 'H', '114.53659630532', '38.0432016452', 0, 1, 'tr_0 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140000, '山西省', 'S', '112.56937550968', '37.879829423856', 0, 1, 'tr_0 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -2099,8 +2099,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(331100, '丽水市', 'L', '119.92957305844', '28.473278180563', 330000, 2, 'tr_0 tr_330000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(340100, '合肥市', 'H', '117.23344266498', '31.826577833687', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(340200, '芜湖市', 'W', '118.43943137654', '31.358536655799', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(340300, '蚌埠市', 'B', '117.39551332814', '32.921523704351', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(340300, '蚌埠市', 'B', '117.39551332814', '32.921523704351', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(340400, '淮南市', 'H', '117.00638885072', '32.631847399053', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(340500, '马鞍山市', 'M', '118.51357957943', '31.676265597609', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(340600, '淮北市', 'H', '116.80453726703', '33.961656300276', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -2113,7 +2112,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(341500, '六安市', 'L', '116.52640966419', '31.741450815323', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(341600, '亳州市', 'B', '115.78446321127', '33.850642695789', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(341700, '池州市', 'C', '117.4984209616', '30.670883790765', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(341800, '宣城市', 'X', '118.76553424277', '30.946601545293', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(341800, '宣城市', 'X', '118.76553424277', '30.946601545293', 340000, 2, 'tr_0 tr_340000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(350100, '福州市', 'F', '119.30346983854', '26.080429420698', 350000, 2, 'tr_0 tr_350000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(350200, '厦门市', 'S', '118.09643549977', '24.485406605176', 350000, 2, 'tr_0 tr_350000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(350300, '莆田市', 'P', '119.01452097813', '25.459865455923', 350000, 2, 'tr_0 tr_350000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -2447,8 +2447,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(140824, '稷山县', 'J', '110.98941457872', '35.610403569616', 140800, 3, 'tr_0 tr_140000 tr_140800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140825, '新绛县', 'X', '111.23140649497', '35.622630103082', 140800, 3, 'tr_0 tr_140000 tr_140800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140826, '绛县', 'J', '111.57548652056', '35.497276373896', 140800, 3, 'tr_0 tr_140000 tr_140800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(140827, '垣曲县', 'Y', '111.67660670572', '35.303014517418', 140800, 3, 'tr_0 tr_140000 tr_140800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(140827, '垣曲县', 'Y', '111.67660670572', '35.303014517418', 140800, 3, 'tr_0 tr_140000 tr_140800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140828, '夏县', 'X', '111.2264314994', '35.147461779807', 140800, 3, 'tr_0 tr_140000 tr_140800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140829, '平陆县', 'P', '111.22348047596', '34.842925154581', 140800, 3, 'tr_0 tr_140000 tr_140800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140830, '芮城县', 'R', '110.7006115132', '34.699388110563', 140800, 3, 'tr_0 tr_140000 tr_140800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -2460,7 +2459,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(140923, '代县', 'D', '112.96655194854', '39.072728346381', 140900, 3, 'tr_0 tr_140000 tr_140900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140924, '繁峙县', 'F', '113.27140827251', '39.195237430734', 140900, 3, 'tr_0 tr_140000 tr_140900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140925, '宁武县', 'N', '112.32639824212', '39.024342381431', 140900, 3, 'tr_0 tr_140000 tr_140900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(140926, '静乐县', 'J', '111.94543190585', '38.365147088438', 140900, 3, 'tr_0 tr_140000 tr_140900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(140926, '静乐县', 'J', '111.94543190585', '38.365147088438', 140900, 3, 'tr_0 tr_140000 tr_140900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(140927, '神池县', 'S', '112.21738276001', '39.096875824863', 140900, 3, 'tr_0 tr_140000 tr_140900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140928, '五寨县', 'W', '111.85340993856', '38.917019909692', 140900, 3, 'tr_0 tr_140000 tr_140900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(140929, '岢岚县', 'K', '111.57947778177', '38.710151038936', 140900, 3, 'tr_0 tr_140000 tr_140900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -2779,8 +2779,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(220822, '通榆县', 'T', '123.09452077673', '44.818963735882', 220800, 3, 'tr_0 tr_220000 tr_220800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(220871, '吉林白城经济开发区', 'J', '122.81641245977', '45.642168989302', 220800, 3, 'tr_0 tr_220000 tr_220800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(220881, '洮南市', 'T', '122.7944676826', '45.341131872567', 220800, 3, 'tr_0 tr_220000 tr_220800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(220882, '大安市', 'D', '124.29850428102', '45.513045149628', 220800, 3, 'tr_0 tr_220000 tr_220800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(220882, '大安市', 'D', '124.29850428102', '45.513045149628', 220800, 3, 'tr_0 tr_220000 tr_220800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(222401, '延吉市', 'Y', '129.52052013726', '42.91271700988', 222400, 3, 'tr_0 tr_220000 tr_222400 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(222402, '图们市', 'T', '129.85038151375', '42.974283499075', 222400, 3, 'tr_0 tr_220000 tr_222400 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(222403, '敦化市', 'D', '128.23861239315', '43.378291274517', 222400, 3, 'tr_0 tr_220000 tr_222400 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -2792,7 +2791,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(230102, '道里区', 'D', '126.62343158837', '45.761844478815', 230100, 3, 'tr_0 tr_230000 tr_230100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(230103, '南岗区', 'N', '126.67563849952', '45.765866163758', 230100, 3, 'tr_0 tr_230000 tr_230100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(230104, '道外区', 'D', '126.65560404089', '45.797776220434', 230100, 3, 'tr_0 tr_230000 tr_230100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(230108, '平房区', 'P', '126.54161509032', '45.808825827952', 230100, 3, 'tr_0 tr_230000 tr_230100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(230108, '平房区', 'P', '126.54161509032', '45.808825827952', 230100, 3, 'tr_0 tr_230000 tr_230100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(230109, '松北区', 'S', '126.51648256825', '45.808592561429', 230100, 3, 'tr_0 tr_230000 tr_230100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(230110, '香坊区', 'X', '126.66962434413', '45.713619645389', 230100, 3, 'tr_0 tr_230000 tr_230100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(230111, '呼兰区', 'H', '126.5943989831', '45.895209780863', 230100, 3, 'tr_0 tr_230000 tr_230100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -3112,8 +3112,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(330803, '衢江区', 'Q', '118.9655390736', '28.986237907969', 330800, 3, 'tr_0 tr_330000 tr_330800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(330822, '常山县', 'C', '118.51755663118', '28.906997949113', 330800, 3, 'tr_0 tr_330000 tr_330800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(330824, '开化县', 'K', '118.42145932131', '29.143187521187', 330800, 3, 'tr_0 tr_330000 tr_330800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(330825, '龙游县', 'L', '119.17841825566', '29.034486553295', 330800, 3, 'tr_0 tr_330000 tr_330800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(330825, '龙游县', 'L', '119.17841825566', '29.034486553295', 330800, 3, 'tr_0 tr_330000 tr_330800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(330881, '江山市', 'J', '118.63358329793', '28.742868480118', 330800, 3, 'tr_0 tr_330000 tr_330800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(330902, '定海区', 'D', '122.11360080392', '30.025462378363', 330900, 3, 'tr_0 tr_330000 tr_330900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(330903, '普陀区', 'P', '122.33154416586', '29.976835696536', 330900, 3, 'tr_0 tr_330000 tr_330900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -3125,7 +3124,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(331022, '三门县', 'S', '121.40255379759', '29.110355206289', 331000, 3, 'tr_0 tr_330000 tr_331000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(331023, '天台县', 'T', '121.01355337629', '29.149514378149', 331000, 3, 'tr_0 tr_330000 tr_331000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(331024, '仙居县', 'X', '120.73543520575', '28.853225693258', 331000, 3, 'tr_0 tr_330000 tr_331000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(331081, '温岭市', 'W', '121.39258889458', '28.37765548985', 331000, 3, 'tr_0 tr_330000 tr_331000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(331081, '温岭市', 'W', '121.39258889458', '28.37765548985', 331000, 3, 'tr_0 tr_330000 tr_331000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(331082, '临海市', 'L', '121.15158529413', '28.864049329083', 331000, 3, 'tr_0 tr_330000 tr_331000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(331083, '玉环市', 'Y', '121.23851297084', '28.141862986829', 331000, 3, 'tr_0 tr_330000 tr_331000 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(331102, '莲都区', 'L', '119.91951913335', '28.451745135046', 331100, 3, 'tr_0 tr_330000 tr_331100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -3445,8 +3445,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(370103, '市中区', 'S', '117.00439910401', '36.657551673642', 370100, 3, 'tr_0 tr_370000 tr_370100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(370104, '槐荫区', 'H', '116.90745837507', '36.657561734426', 370100, 3, 'tr_0 tr_370000 tr_370100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(370105, '天桥区', 'T', '116.99339917338', '36.684067874353', 370100, 3, 'tr_0 tr_370000 tr_370100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(370112, '历城区', 'L', '117.07158975107', '36.685655534711', 370100, 3, 'tr_0 tr_370000 tr_370100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(370112, '历城区', 'L', '117.07158975107', '36.685655534711', 370100, 3, 'tr_0 tr_370000 tr_370100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(370113, '长清区', 'Z', '116.75838709095', '36.56021587991', 370100, 3, 'tr_0 tr_370000 tr_370100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(370114, '章丘区', 'Z', '117.53256537437', '36.68553275142', 370100, 3, 'tr_0 tr_370000 tr_370100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(370115, '济阳区', 'J', '117.18062113319', '36.983970518315', 370100, 3, 'tr_0 tr_370000 tr_370100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -3458,7 +3457,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(370211, '黄岛区', 'H', '120.20454654768', '35.966382870945', 370200, 3, 'tr_0 tr_370000 tr_370200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(370212, '崂山区', 'L', '120.47539724708', '36.113499423971', 370200, 3, 'tr_0 tr_370000 tr_370200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(370213, '李沧区', 'L', '120.43960282675', '36.151024667784', 370200, 3, 'tr_0 tr_370000 tr_370200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(370214, '城阳区', 'C', '120.40252679394', '36.31288619735', 370200, 3, 'tr_0 tr_370000 tr_370200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(370214, '城阳区', 'C', '120.40252679394', '36.31288619735', 370200, 3, 'tr_0 tr_370000 tr_370200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(370215, '即墨区', 'J', '120.45353617402', '36.394749170322', 370200, 3, 'tr_0 tr_370000 tr_370200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(370271, '青岛高新技术产业开发区', 'Q', '120.44085344768', '36.124685571214', 370200, 3, 'tr_0 tr_370000 tr_370200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(370281, '胶州市', 'J', '120.03953537127', '36.270349088049', 370200, 3, 'tr_0 tr_370000 tr_370200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -3776,8 +3776,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(420102, '江岸区', 'J', '114.31657918761', '30.605402797562', 420100, 3, 'tr_0 tr_420000 tr_420100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(420103, '江汉区', 'J', '114.27750613182', '30.607282276827', 420100, 3, 'tr_0 tr_420000 tr_420100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(420104, '硚口区', 'Q', '114.22146031207', '30.587584340776', 420100, 3, 'tr_0 tr_420000 tr_420100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(420105, '汉阳区', 'H', '114.22544555464', '30.560052027443', 420100, 3, 'tr_0 tr_420000 tr_420100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(420105, '汉阳区', 'H', '114.22544555464', '30.560052027443', 420100, 3, 'tr_0 tr_420000 tr_420100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(420106, '武昌区', 'W', '114.35362228468', '30.564860292785', 420100, 3, 'tr_0 tr_420000 tr_420100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(420107, '青山区', 'Q', '114.39149265697', '30.646593075543', 420100, 3, 'tr_0 tr_420000 tr_420100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(420111, '洪山区', 'H', '114.35045554602', '30.506333956808', 420100, 3, 'tr_0 tr_420000 tr_420100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -3789,7 +3788,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(420117, '新洲区', 'X', '114.8075433929', '30.847243870523', 420100, 3, 'tr_0 tr_420000 tr_420100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(420202, '黄石港区', 'H', '115.07241748608', '30.229052639992', 420200, 3, 'tr_0 tr_420000 tr_420200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(420203, '西塞山区', 'X', '115.11648143744', '30.210695184118', 420200, 3, 'tr_0 tr_420000 tr_420200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(420204, '下陆区', 'X', '114.96741590247', '30.180046155273', 420200, 3, 'tr_0 tr_420000 tr_420200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(420204, '下陆区', 'X', '114.96741590247', '30.180046155273', 420200, 3, 'tr_0 tr_420000 tr_420200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(420205, '铁山区', 'T', '114.90757141821', '30.212250832587', 420200, 3, 'tr_0 tr_420000 tr_420200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(420222, '阳新县', 'Y', '115.22142677197', '29.836541808086', 420200, 3, 'tr_0 tr_420000 tr_420200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(420281, '大冶市', 'D', '114.98643626402', '30.101667800103', 420200, 3, 'tr_0 tr_420000 tr_420200 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -4108,8 +4108,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(441523, '陆河县', 'L', '115.66648271471', '23.30767707649', 441500, 3, 'tr_0 tr_440000 tr_441500 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(441581, '陆丰市', 'L', '115.78802975191', '22.967876723873', 441500, 3, 'tr_0 tr_440000 tr_441500 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(441602, '源城区', 'Y', '114.70843899033', '23.740298338347', 441600, 3, 'tr_0 tr_440000 tr_441600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(441621, '紫金县', 'Z', '115.19044771834', '23.641430253189', 441600, 3, 'tr_0 tr_440000 tr_441600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(441621, '紫金县', 'Z', '115.19044771834', '23.641430253189', 441600, 3, 'tr_0 tr_440000 tr_441600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(441622, '龙川县', 'L', '115.26655548485', '24.105850721955', 441600, 3, 'tr_0 tr_440000 tr_441600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(441623, '连平县', 'L', '114.49544419635', '24.375808067414', 441600, 3, 'tr_0 tr_440000 tr_441600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(441624, '和平县', 'H', '114.9454488143', '24.448252767689', 441600, 3, 'tr_0 tr_440000 tr_441600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -4121,7 +4120,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(441802, '清城区', 'Q', '113.06947663537', '23.704022037925', 441800, 3, 'tr_0 tr_440000 tr_441800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(441803, '清新区', 'Q', '112.99155779512', '23.754270337093', 441800, 3, 'tr_0 tr_440000 tr_441800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(441821, '佛冈县', 'F', '113.53844124873', '23.885475421111', 441800, 3, 'tr_0 tr_440000 tr_441800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(441823, '阳山县', 'Y', '112.64751954085', '24.47094363588', 441800, 3, 'tr_0 tr_440000 tr_441800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(441823, '阳山县', 'Y', '112.64751954085', '24.47094363588', 441800, 3, 'tr_0 tr_440000 tr_441800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(441825, '连山壮族瑶族自治县', 'L', '112.10042570409', '24.576845604093', 441800, 3, 'tr_0 tr_440000 tr_441800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(441826, '连南瑶族自治县', 'L', '112.29351728187', '24.73154858148', 441800, 3, 'tr_0 tr_440000 tr_441800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(441881, '英德市', 'Y', '113.42144297474', '24.191939355217', 441800, 3, 'tr_0 tr_440000 tr_441800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -4439,8 +4439,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(510623, '中江县', 'Z', '104.68553015058', '31.038953695302', 510600, 3, 'tr_0 tr_510000 tr_510600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(510681, '广汉市', 'G', '104.28842189311', '30.982415239743', 510600, 3, 'tr_0 tr_510000 tr_510600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(510682, '什邡市', 'S', '104.17442710355', '31.132889048238', 510600, 3, 'tr_0 tr_510000 tr_510600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(510683, '绵竹市', 'M', '104.227609305', '31.343592258211', 510600, 3, 'tr_0 tr_510000 tr_510600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(510683, '绵竹市', 'M', '104.227609305', '31.343592258211', 510600, 3, 'tr_0 tr_510000 tr_510600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(510703, '涪城区', 'F', '104.76342033491', '31.46131438858', 510700, 3, 'tr_0 tr_510000 tr_510700 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(510704, '游仙区', 'Y', '104.77242899171', '31.479904474058', 510700, 3, 'tr_0 tr_510000 tr_510700 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(510705, '安州区', 'A', '104.5735550213', '31.540750527876', 510700, 3, 'tr_0 tr_510000 tr_510700 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -4452,7 +4451,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(510781, '江油市', 'J', '104.75241160088', '31.784128193388', 510700, 3, 'tr_0 tr_510000 tr_510700 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(510802, '利州区', 'L', '105.85242622329', '32.440207812726', 510800, 3, 'tr_0 tr_510000 tr_510800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(510811, '昭化区', 'Z', '105.96941892782', '32.329618490159', 510800, 3, 'tr_0 tr_510000 tr_510800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(510812, '朝天区', 'C', '105.8965888086', '32.649726240308', 510800, 3, 'tr_0 tr_510000 tr_510800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(510812, '朝天区', 'C', '105.8965888086', '32.649726240308', 510800, 3, 'tr_0 tr_510000 tr_510800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(510821, '旺苍县', 'W', '106.29649124536', '32.235097383079', 510800, 3, 'tr_0 tr_510000 tr_510800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(510822, '青川县', 'Q', '105.24540705459', '32.5816168573', 510800, 3, 'tr_0 tr_510000 tr_510800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(510823, '剑阁县', 'J', '105.53157601887', '32.293478516773', 510800, 3, 'tr_0 tr_510000 tr_510800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -4771,8 +4771,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(532532, '河口瑶族自治县', 'H', '103.9454436278', '22.535465602947', 532500, 3, 'tr_0 tr_530000 tr_532500 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(532601, '文山市', 'W', '104.23854382746', '23.391944131908', 532600, 3, 'tr_0 tr_530000 tr_532600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(532622, '砚山县', 'Y', '104.3435508907', '23.6114865767', 532600, 3, 'tr_0 tr_530000 tr_532600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(532623, '西畴县', 'X', '104.67852542203', '23.443271275283', 532600, 3, 'tr_0 tr_530000 tr_532600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(532623, '西畴县', 'X', '104.67852542203', '23.443271275283', 532600, 3, 'tr_0 tr_530000 tr_532600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(532624, '麻栗坡县', 'M', '104.70954948078', '23.13158558356', 532600, 3, 'tr_0 tr_530000 tr_532600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(532625, '马关县', 'M', '104.40041497692', '23.018993577166', 532600, 3, 'tr_0 tr_530000 tr_532600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(532626, '丘北县', 'Q', '104.17344174074', '24.056993896218', 532600, 3, 'tr_0 tr_530000 tr_532600 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -4784,7 +4783,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(532901, '大理市', 'D', '100.23651930044', '25.597604905452', 532900, 3, 'tr_0 tr_530000 tr_532900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(532922, '漾濞彝族自治县', 'Y', '99.964413758168', '25.676295762972', 532900, 3, 'tr_0 tr_530000 tr_532900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(532923, '祥云县', 'X', '100.55744657937', '25.489872506242', 532900, 3, 'tr_0 tr_530000 tr_532900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(532924, '宾川县', 'B', '100.57845668762', '25.835249028198', 532900, 3, 'tr_0 tr_530000 tr_532900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(532924, '宾川县', 'B', '100.57845668762', '25.835249028198', 532900, 3, 'tr_0 tr_530000 tr_532900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(532925, '弥渡县', 'M', '100.49758601546', '25.349336028746', 532900, 3, 'tr_0 tr_530000 tr_532900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(532926, '南涧彝族自治县', 'N', '100.51554862227', '25.049426762094', 532900, 3, 'tr_0 tr_530000 tr_532900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(532927, '巍山彝族回族自治县', 'W', '100.31346033515', '25.233438729799', 532900, 3, 'tr_0 tr_530000 tr_532900 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -5103,8 +5103,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(632723, '称多县', 'C', '97.115000009277', '33.374225698944', 632700, 3, 'tr_0 tr_630000 tr_632700 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(632724, '治多县', 'Z', '95.61979357437', '33.857953267719', 632700, 3, 'tr_0 tr_630000 tr_632700 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(632725, '囊谦县', 'N', '96.486918271283', '32.209194368698', 632700, 3, 'tr_0 tr_630000 tr_632700 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(632726, '曲麻莱县', 'Q', '95.803750013992', '34.132298666997', 632700, 3, 'tr_0 tr_630000 tr_632700 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(632726, '曲麻莱县', 'Q', '95.803750013992', '34.132298666997', 632700, 3, 'tr_0 tr_630000 tr_632700 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(632801, '格尔木市', 'G', '94.933310210425', '36.412371046954', 632800, 3, 'tr_0 tr_630000 tr_632800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(632802, '德令哈市', 'D', '97.367470299975', '37.375345907463', 632800, 3, 'tr_0 tr_630000 tr_632800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(632803, '茫崖市', 'M', '90.87951750334', '38.261902814972', 632800, 3, 'tr_0 tr_630000 tr_632800 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -5116,7 +5115,8 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(640105, '西夏区', 'X', '106.15658124015', '38.496817469604', 640100, 3, 'tr_0 tr_640000 tr_640100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(640106, '金凤区', 'J', '106.24956089094', '38.478695238722', 640100, 3, 'tr_0 tr_640000 tr_640100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(640121, '永宁县', 'Y', '106.25960457536', '38.283001541521', 640100, 3, 'tr_0 tr_640000 tr_640100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(640122, '贺兰县', 'H', '106.3565182653', '38.560406689579', 640100, 3, 'tr_0 tr_640000 tr_640100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
+(640122, '贺兰县', 'H', '106.3565182653', '38.560406689579', 640100, 3, 'tr_0 tr_640000 tr_640100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
+INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
(640181, '灵武市', 'L', '106.34644035545', '38.108658666793', 640100, 3, 'tr_0 tr_640000 tr_640100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(540502, '乃东区', 'N', '91.778681965641', '29.234229154985', 540500, 3, 'tr_0 tr_540000 tr_540500 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(540521, '扎囊县', 'Z', '91.343627127639', '29.251164315795', 540500, 3, 'tr_0 tr_540000 tr_540500 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -5434,8 +5434,7 @@ INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `l
(131125, '安平县', 'A', '115.52554928532', '38.240506922191', 131100, 3, 'tr_0 tr_130000 tr_131100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(131126, '故城县', 'G', '115.97260216135', '37.353347552477', 131100, 3, 'tr_0 tr_130000 tr_131100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(131127, '景县', 'J', '116.2774107853', '37.698814551395', 131100, 3, 'tr_0 tr_130000 tr_131100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
-(131128, '阜城县', 'F', '116.18242153525', '37.868732457906', 131100, 3, 'tr_0 tr_130000 tr_131100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00');
-INSERT INTO `hg_sys_provinces` (`id`, `title`, `pinyin`, `lng`, `lat`, `pid`, `level`, `tree`, `sort`, `status`, `created_at`, `updated_at`) VALUES
+(131128, '阜城县', 'F', '116.18242153525', '37.868732457906', 131100, 3, 'tr_0 tr_130000 tr_131100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(131171, '河北衡水高新技术产业开发区', 'H', '115.73456139967', '37.807821775773', 131100, 3, 'tr_0 tr_130000 tr_131100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(131172, '衡水滨湖新区', 'H', '115.70627999969', '37.701616037093', 131100, 3, 'tr_0 tr_130000 tr_131100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
(131182, '深州市', 'S', '115.56636927583', '38.006941234922', 131100, 3, 'tr_0 tr_130000 tr_131100 ', 0, 1, '2022-10-07 20:42:26', '2022-11-01 00:00:00'),
@@ -5455,29 +5454,27 @@ CREATE TABLE `hg_sys_serve_license` (
`name` varchar(128) NOT NULL COMMENT '许可名称',
`appid` varchar(64) NOT NULL COMMENT '应用ID',
`secret_key` varchar(255) DEFAULT NULL COMMENT '应用秘钥',
- `desc` text COMMENT '授权说明',
`remote_addr` varchar(64) DEFAULT NULL COMMENT '最后连接地址',
- `online` tinyint(4) DEFAULT '0' COMMENT '在线数量',
- `online_limit` int(11) DEFAULT '1' COMMENT '在线数量限制,默认1',
+ `online_limit` int(11) DEFAULT '1' COMMENT '在线限制',
`login_times` bigint(20) DEFAULT NULL COMMENT '登录次数',
`last_login_at` datetime DEFAULT NULL COMMENT '最后登录时间',
- `last_active_at` datetime DEFAULT NULL COMMENT '最后活跃时间',
+ `last_active_at` datetime DEFAULT NULL COMMENT '最后心跳',
`routes` json DEFAULT NULL COMMENT '路由表,空使用默认分组路由',
- `allowed_ips` varchar(512) DEFAULT NULL COMMENT '白名单,*代表所有,只有允许的IP才能连接到tcp服务',
- `end_at` datetime NOT NULL COMMENT '授权结束时间',
+ `allowed_ips` varchar(512) DEFAULT NULL COMMENT 'IP白名单',
+ `end_at` datetime NOT NULL COMMENT '授权有效期',
`remark` varchar(512) DEFAULT NULL COMMENT '备注',
`status` tinyint(1) DEFAULT '1' COMMENT '状态',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
`updated_at` datetime DEFAULT NULL COMMENT '修改时间'
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统_服务许可';
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统_服务许可证';
--
-- 转存表中的数据 `hg_sys_serve_license`
--
-INSERT INTO `hg_sys_serve_license` (`id`, `group`, `name`, `appid`, `secret_key`, `desc`, `remote_addr`, `online`, `online_limit`, `login_times`, `last_login_at`, `last_active_at`, `routes`, `allowed_ips`, `end_at`, `remark`, `status`, `created_at`, `updated_at`) VALUES
-(1, 'cron', '默认的定时任务', '1002', 'hotgo', '这是默认的定时任务TCP客户端授权凭证。', '127.0.0.1:62092', 1, 1, 337, '2023-05-16 12:44:16', '2023-05-16 18:06:18', NULL, '127.0.0.1', '2033-03-09 00:00:00', '', 1, '2023-03-11 00:00:00', '2023-05-16 18:06:18'),
-(2, 'auth', '测试授权', 'mengshuai', '123456', '这是一个测试的授权服务,可以为第三方平台提供授权支持。', '127.0.0.1:51615', 1, 1, 0, '2023-05-04 23:23:52', '2023-05-04 23:23:52', NULL, '127.0.0.1', '2033-03-09 00:00:00', '', 1, '2023-03-11 00:00:00', '2023-05-04 23:23:52');
+INSERT INTO `hg_sys_serve_license` (`id`, `group`, `name`, `appid`, `secret_key`, `remote_addr`, `online_limit`, `login_times`, `last_login_at`, `last_active_at`, `routes`, `allowed_ips`, `end_at`, `remark`, `status`, `created_at`, `updated_at`) VALUES
+(1, 'cron', '定时任务', '1002', 'hotgo', '127.0.0.1:56950', 1, 0, '2023-07-20 14:17:20', '2023-07-20 14:17:57', NULL, '127.0.0.1', '2033-03-09 00:00:00', '这是默认的定时任务TCP客户端授权凭证。', 1, '2023-03-11 00:00:00', '2023-07-20 14:17:57'),
+(2, 'auth', '授权服务', 'mengshuai', '123456', '127.0.0.1:56949', 1, 0, '2023-07-20 14:17:20', '2023-07-20 14:17:20', '[\"ExampleRPCHelloReq\", \"ExampleHelloReq\", \"AuthSummaryReq\"]', '127.0.0.1', '2033-03-09 00:00:00', '这是一个测试的授权服务,可以为第三方平台提供授权支持。', 1, '2023-03-11 00:00:00', '2023-07-20 14:17:20');
-- --------------------------------------------------------
@@ -5836,13 +5833,13 @@ ALTER TABLE `hg_addon_hgexample_table`
-- 使用表AUTO_INCREMENT `hg_admin_cash`
--
ALTER TABLE `hg_admin_cash`
- MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID';
+ MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', AUTO_INCREMENT=2;
--
-- 使用表AUTO_INCREMENT `hg_admin_credits_log`
--
ALTER TABLE `hg_admin_credits_log`
- MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '变动ID';
+ MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '变动ID', AUTO_INCREMENT=4;
--
-- 使用表AUTO_INCREMENT `hg_admin_dept`
@@ -5860,7 +5857,7 @@ ALTER TABLE `hg_admin_member`
-- 使用表AUTO_INCREMENT `hg_admin_menu`
--
ALTER TABLE `hg_admin_menu`
- MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜单ID', AUTO_INCREMENT=2273;
+ MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜单ID', AUTO_INCREMENT=2282;
--
-- 使用表AUTO_INCREMENT `hg_admin_notice`
@@ -5872,7 +5869,7 @@ ALTER TABLE `hg_admin_notice`
-- 使用表AUTO_INCREMENT `hg_admin_notice_read`
--
ALTER TABLE `hg_admin_notice_read`
- MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '记录ID', AUTO_INCREMENT=6;
+ MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '记录ID', AUTO_INCREMENT=7;
--
-- 使用表AUTO_INCREMENT `hg_admin_oauth`
@@ -5902,7 +5899,7 @@ ALTER TABLE `hg_admin_role`
-- 使用表AUTO_INCREMENT `hg_admin_role_casbin`
--
ALTER TABLE `hg_admin_role_casbin`
- MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=31352;
+ MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=62488;
--
-- 使用表AUTO_INCREMENT `hg_pay_log`
@@ -5926,13 +5923,13 @@ ALTER TABLE `hg_sys_addons_config`
-- 使用表AUTO_INCREMENT `hg_sys_addons_install`
--
ALTER TABLE `hg_sys_addons_install`
- MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', AUTO_INCREMENT=2;
+ MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', AUTO_INCREMENT=3;
--
-- 使用表AUTO_INCREMENT `hg_sys_attachment`
--
ALTER TABLE `hg_sys_attachment`
- MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '文件ID', AUTO_INCREMENT=56;
+ MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '文件ID', AUTO_INCREMENT=74;
--
-- 使用表AUTO_INCREMENT `hg_sys_blacklist`
@@ -5980,7 +5977,7 @@ ALTER TABLE `hg_sys_ems_log`
-- 使用表AUTO_INCREMENT `hg_sys_gen_codes`
--
ALTER TABLE `hg_sys_gen_codes`
- MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '生成ID', AUTO_INCREMENT=2;
+ MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '生成ID', AUTO_INCREMENT=3;
--
-- 使用表AUTO_INCREMENT `hg_sys_gen_curd_demo`
diff --git a/server/utility/convert/match.go b/server/utility/convert/match.go
index 7193025..a5224b5 100644
--- a/server/utility/convert/match.go
+++ b/server/utility/convert/match.go
@@ -97,3 +97,14 @@ func IpFilterStrategy(originIp string) (list map[string]struct{}) {
}
return list
}
+
+// MatchIpStrategy 匹配IP策略,输入ip如果在策略当中返回true
+func MatchIpStrategy(rules, ip string) bool {
+ allowedIps := IpFilterStrategy(rules)
+ if _, ok := allowedIps["*"]; ok {
+ return true
+ }
+
+ _, ok := allowedIps[ip]
+ return ok
+}
diff --git a/server/utility/simple/simple.go b/server/utility/simple/simple.go
index ab91d9d..9656aed 100644
--- a/server/utility/simple/simple.go
+++ b/server/utility/simple/simple.go
@@ -82,20 +82,20 @@ func CheckPassword(input, salt, hash string) (err error) {
}
// SafeGo 安全的调用协程,遇到错误时输出错误日志而不是抛出panic
-func SafeGo(ctx context.Context, f func(ctx context.Context), level ...interface{}) {
- var newLevel = glog.LEVEL_ERRO
- if len(level) > 0 {
- newLevel = gconv.Int(level[0])
+func SafeGo(ctx context.Context, f func(ctx context.Context), lv ...interface{}) {
+ var level = glog.LEVEL_ERRO
+ if len(lv) > 0 {
+ level = gconv.Int(lv[0])
}
err := grpool.AddWithRecover(ctx, func(ctx context.Context) {
f(ctx)
}, func(ctx context.Context, err error) {
- Logf(newLevel, ctx, "SafeGo exec failed:%+v", err)
+ Logf(level, ctx, "SafeGo exec failed:%+v", err)
})
if err != nil {
- Logf(newLevel, ctx, "SafeGo AddWithRecover err:%+v", err)
+ Logf(level, ctx, "SafeGo AddWithRecover err:%+v", err)
return
}
}
diff --git a/server/utility/validate/filter.go b/server/utility/validate/filter.go
index 68986fd..265e568 100644
--- a/server/utility/validate/filter.go
+++ b/server/utility/validate/filter.go
@@ -3,11 +3,11 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
-//
package validate
import (
"context"
+ "github.com/gogf/gf/v2/frame/g"
)
// Filter 通用过滤器
@@ -21,8 +21,12 @@ type Filter interface {
// PreFilter 预过滤
func PreFilter(ctx context.Context, in interface{}) error {
- if c, ok := in.(Filter); ok {
- return c.Filter(ctx)
- }
- return nil
+ return g.Try(ctx, func(ctx context.Context) {
+ if c, ok := in.(Filter); ok {
+ if err := c.Filter(ctx); err != nil {
+ g.Throw(err)
+ }
+ return
+ }
+ })
}
diff --git a/web/package.json b/web/package.json
index ef8cf88..ef52129 100644
--- a/web/package.json
+++ b/web/package.json
@@ -1,6 +1,6 @@
{
"name": "hotgo",
- "version": "2.7.6",
+ "version": "2.8.4",
"author": {
"name": "MengShuai",
"email": "133814250@qq.com",
diff --git a/web/src/api/apply/attachment.ts b/web/src/api/apply/attachment.ts
index bf07ff4..3050de6 100644
--- a/web/src/api/apply/attachment.ts
+++ b/web/src/api/apply/attachment.ts
@@ -39,3 +39,18 @@ export function View(params) {
params,
});
}
+
+export function ChooserOption() {
+ return http.request({
+ url: '/attachment/chooserOption',
+ method: 'GET',
+ });
+}
+
+export function ClearKind(params) {
+ return http.request({
+ url: '/attachment/clearKind',
+ method: 'POST',
+ params,
+ });
+}
diff --git a/web/src/api/monitor/monitor.ts b/web/src/api/monitor/monitor.ts
index e48df91..d9333f8 100644
--- a/web/src/api/monitor/monitor.ts
+++ b/web/src/api/monitor/monitor.ts
@@ -2,7 +2,7 @@ import { http } from '@/utils/http/axios';
export function OnlineList(params) {
return http.request({
- url: '/monitor/onlineList',
+ url: '/monitor/userOnlineList',
method: 'get',
params,
});
@@ -10,8 +10,31 @@ export function OnlineList(params) {
export function Offline(params) {
return http.request({
- url: '/monitor/offline',
+ url: '/monitor/userOffline',
method: 'POST',
params,
});
}
+
+export function NetOnlineList(params) {
+ return http.request({
+ url: '/monitor/netOnlineList',
+ method: 'get',
+ params,
+ });
+}
+
+export function NetOffline(params) {
+ return http.request({
+ url: '/monitor/netOffline',
+ method: 'POST',
+ params,
+ });
+}
+
+export function NetOption() {
+ return http.request({
+ url: '/monitor/netOption',
+ method: 'get',
+ });
+}
diff --git a/web/src/api/order/index.ts b/web/src/api/order/index.ts
index 110e783..d5a0d5a 100644
--- a/web/src/api/order/index.ts
+++ b/web/src/api/order/index.ts
@@ -97,8 +97,6 @@ export function AcceptRefund(params) {
});
}
-
-
// 导出充值订单
export function Export(params) {
jumpExport('/order/export', params);
diff --git a/web/src/api/serveLicense/index.ts b/web/src/api/serveLicense/index.ts
new file mode 100644
index 0000000..63f7351
--- /dev/null
+++ b/web/src/api/serveLicense/index.ts
@@ -0,0 +1,60 @@
+import { http, jumpExport } from '@/utils/http/axios';
+
+// 获取服务许可证列表
+export function List(params) {
+ return http.request({
+ url: '/serveLicense/list',
+ method: 'get',
+ params,
+ });
+}
+
+// 删除/批量删除服务许可证
+export function Delete(params) {
+ return http.request({
+ url: '/serveLicense/delete',
+ method: 'POST',
+ params,
+ });
+}
+
+// 添加/编辑服务许可证
+export function Edit(params) {
+ return http.request({
+ url: '/serveLicense/edit',
+ method: 'POST',
+ params,
+ });
+}
+
+// 修改服务许可证状态
+export function Status(params) {
+ return http.request({
+ url: '/serveLicense/status',
+ method: 'POST',
+ params,
+ });
+}
+
+// 获取服务许可证指定详情
+export function View(params) {
+ return http.request({
+ url: '/serveLicense/view',
+ method: 'GET',
+ params,
+ });
+}
+
+// 分配服务许可证路由
+export function AssignRouter(params) {
+ return http.request({
+ url: '/serveLicense/assignRouter',
+ method: 'POST',
+ params,
+ });
+}
+
+// 导出服务许可证
+export function Export(params) {
+ jumpExport('/serveLicense/export', params);
+}
diff --git a/web/src/api/system/menu.ts b/web/src/api/system/menu.ts
index e574652..9ac9bc9 100644
--- a/web/src/api/system/menu.ts
+++ b/web/src/api/system/menu.ts
@@ -1,5 +1,5 @@
-import {http} from '@/utils/http/axios';
-import {ApiEnum} from "@/enums/apiEnum";
+import { http } from '@/utils/http/axios';
+import { ApiEnum } from '@/enums/apiEnum';
/**
* @description: 根据用户id获取用户菜单
diff --git a/web/src/components/CountTo/CountTo.vue b/web/src/components/CountTo/CountTo.vue
index 7b4d015..9576a82 100644
--- a/web/src/components/CountTo/CountTo.vue
+++ b/web/src/components/CountTo/CountTo.vue
@@ -46,7 +46,7 @@
const source = ref(props.startVal);
const disabled = ref(false);
let outputValue = useTransition(source);
-
+
const value = computed(() => formatNumber(unref(outputValue)));
watchEffect(() => {
diff --git a/web/src/components/FileChooser/index.vue b/web/src/components/FileChooser/index.vue
new file mode 100644
index 0000000..dc6f29c
--- /dev/null
+++ b/web/src/components/FileChooser/index.vue
@@ -0,0 +1,361 @@
+
+
+
+ 选择{{ buttonText }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ getFileExt(item) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 上传文件
+
+
+
+
+
+
+
+
+ 取消
+ 确定
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/components/FileChooser/src/Chooser.vue b/web/src/components/FileChooser/src/Chooser.vue
new file mode 100644
index 0000000..fdf1d52
--- /dev/null
+++ b/web/src/components/FileChooser/src/Chooser.vue
@@ -0,0 +1,428 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ getFileExt(item.fileUrl) }}
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.kind === 'image' ? '预览' : '下载' }}
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/components/FileChooser/src/Preview.vue b/web/src/components/FileChooser/src/Preview.vue
new file mode 100644
index 0000000..f00a3cf
--- /dev/null
+++ b/web/src/components/FileChooser/src/Preview.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
diff --git a/web/src/components/FileChooser/src/Upload.vue b/web/src/components/FileChooser/src/Upload.vue
new file mode 100644
index 0000000..a32c801
--- /dev/null
+++ b/web/src/components/FileChooser/src/Upload.vue
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+ 点击或者拖动{{ typeTag }}到该区域来上传
+ 单次最多允许{{ maxUpload }}个{{ typeTag }}
+
+
+
+
+
+
diff --git a/web/src/components/FileChooser/src/model.ts b/web/src/components/FileChooser/src/model.ts
new file mode 100644
index 0000000..5a0e3d6
--- /dev/null
+++ b/web/src/components/FileChooser/src/model.ts
@@ -0,0 +1,57 @@
+import { VNode } from '@vue/runtime-core';
+
+export type Attachment = {
+ id: number;
+ appId: string;
+ memberId: number;
+ cateId: number;
+ drive: string;
+ name: string;
+ kind: string;
+ metaType: string;
+ naiveType: string;
+ path: string;
+ fileUrl: string;
+ size: number;
+ ext: string;
+ md5: string;
+ status: number;
+ createdAt: string;
+ updatedAt: string;
+ sizeFormat: string;
+};
+
+export interface KindRawOption {
+ key: string;
+ label: string;
+ icon: string;
+}
+
+export interface KindOption {
+ key: string;
+ label: any;
+ icon: VNode;
+ extra: any;
+ disabled: boolean;
+}
+
+export type FileType = 'image' | 'doc' | 'audio' | 'video' | 'zip' | 'other' | 'default';
+
+export function getFileType(fileType: string): string {
+ switch (fileType) {
+ case 'image':
+ return '图片';
+ case 'doc':
+ return '文档';
+ case 'audio':
+ return '音频';
+ case 'video':
+ return '视频';
+ case 'zip':
+ return '压缩包';
+ case 'other':
+ case 'default':
+ return '文件';
+ }
+ return '文件';
+}
diff --git a/web/src/components/SvgIcon/index.vue b/web/src/components/SvgIcon/index.vue
index 5749a83..db6d71e 100644
--- a/web/src/components/SvgIcon/index.vue
+++ b/web/src/components/SvgIcon/index.vue
@@ -5,7 +5,7 @@
diff --git a/web/src/views/home/account/BasicSetting.vue b/web/src/views/home/account/BasicSetting.vue
index f30722b..adad530 100644
--- a/web/src/views/home/account/BasicSetting.vue
+++ b/web/src/views/home/account/BasicSetting.vue
@@ -73,7 +73,7 @@
style="margin-top: 15px"
>
-
+
@@ -122,13 +122,13 @@
+
+
diff --git a/web/src/views/monitor/netconn/modal/edit.vue b/web/src/views/monitor/netconn/modal/edit.vue
new file mode 100644
index 0000000..6b33182
--- /dev/null
+++ b/web/src/views/monitor/netconn/modal/edit.vue
@@ -0,0 +1,192 @@
+
+
+
+
+
+ 注意:如果服务在线,为了确保更新后的许可证信息生效,服务需要重新登录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确定
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/views/monitor/netconn/modal/index.vue b/web/src/views/monitor/netconn/modal/index.vue
new file mode 100644
index 0000000..1ee83b1
--- /dev/null
+++ b/web/src/views/monitor/netconn/modal/index.vue
@@ -0,0 +1,347 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加许可证
+
+
+
+
+
+
+
+ 批量删除
+
+
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+ 如果许可证未分配任何路由,则客户端可以访问所有服务路由接口
+
+
+
+
+
+
+
+ 取消
+ 确定
+
+
+
+
+
+
+
+
+
diff --git a/web/src/views/monitor/netconn/modal/modal.vue b/web/src/views/monitor/netconn/modal/modal.vue
new file mode 100644
index 0000000..cbdd692
--- /dev/null
+++ b/web/src/views/monitor/netconn/modal/modal.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/views/monitor/netconn/modal/model.ts b/web/src/views/monitor/netconn/modal/model.ts
new file mode 100644
index 0000000..1b9dadf
--- /dev/null
+++ b/web/src/views/monitor/netconn/modal/model.ts
@@ -0,0 +1,307 @@
+import { h, ref } from 'vue';
+import { NTag } from 'naive-ui';
+import { cloneDeep } from 'lodash-es';
+import { FormSchema } from '@/components/Form';
+import { Dicts } from '@/api/dict/dict';
+import { isNullObject } from '@/utils/is';
+import { defRangeShortcuts, formatBefore } from '@/utils/dateUtil';
+import { getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
+import { NetOption } from '@/api/monitor/monitor';
+
+export interface State {
+ id: number;
+ group: string;
+ name: string;
+ appid: string;
+ secretKey: string;
+ remoteAddr: string;
+ onlineLimit: number;
+ loginTimes: number;
+ lastLoginAt: string;
+ lastActiveAt: string;
+ routes: any;
+ allowedIps: string;
+ endAt: string;
+ remark: string;
+ status: number;
+ createdAt: string;
+ updatedAt: string;
+}
+
+export const defaultState = {
+ id: 0,
+ group: '',
+ name: '',
+ appid: '',
+ secretKey: '',
+ remoteAddr: '',
+ onlineLimit: 1,
+ loginTimes: 0,
+ lastLoginAt: '',
+ lastActiveAt: '',
+ routes: null,
+ allowedIps: '',
+ endAt: '',
+ remark: '',
+ status: 1,
+ createdAt: '',
+ updatedAt: '',
+};
+
+export function newState(state: State | null): State {
+ if (state !== null) {
+ return cloneDeep(state);
+ }
+ return cloneDeep(defaultState);
+}
+
+export const options = ref({
+ sys_normal_disable: [],
+ group: [],
+ routes: [],
+});
+
+export const rules = {
+ group: {
+ required: true,
+ trigger: ['blur', 'input'],
+ type: 'string',
+ message: '请输入分组',
+ },
+ name: {
+ required: true,
+ trigger: ['blur', 'input'],
+ type: 'string',
+ message: '请输入许可名称',
+ },
+ appid: {
+ required: true,
+ trigger: ['blur', 'input'],
+ type: 'string',
+ message: '请输入应用ID',
+ },
+ endAt: {
+ required: true,
+ trigger: ['blur', 'input', 'focus'],
+ type: 'string',
+ message: '请输入授权结束时间',
+ },
+};
+
+export const schemas = ref([
+ {
+ field: 'id',
+ component: 'NInput',
+ label: '许可ID',
+ componentProps: {
+ placeholder: '请输入许可ID',
+ onUpdateValue: (e: any) => {
+ console.log(e);
+ },
+ },
+ },
+ {
+ field: 'group',
+ component: 'NSelect',
+ label: '授权分组',
+ defaultValue: null,
+ componentProps: {
+ placeholder: '请选择授权分组',
+ options: options.value.group,
+ onUpdateValue: (e: any) => {
+ console.log(e);
+ },
+ },
+ },
+ {
+ field: 'name',
+ component: 'NInput',
+ label: '许可名称',
+ componentProps: {
+ placeholder: '请输入许可名称',
+ onUpdateValue: (e: any) => {
+ console.log(e);
+ },
+ },
+ },
+ {
+ field: 'appid',
+ component: 'NInput',
+ label: 'APPID',
+ componentProps: {
+ placeholder: '请输入APPID',
+ onUpdateValue: (e: any) => {
+ console.log(e);
+ },
+ },
+ },
+ {
+ field: 'status',
+ component: 'NSelect',
+ label: '状态',
+ defaultValue: null,
+ componentProps: {
+ placeholder: '请选择状态',
+ options: [],
+ onUpdateValue: (e: any) => {
+ console.log(e);
+ },
+ },
+ },
+ {
+ field: 'endAt',
+ component: 'NDatePicker',
+ label: '过期时间',
+ componentProps: {
+ type: 'datetimerange',
+ clearable: true,
+ shortcuts: defRangeShortcuts(),
+ onUpdateValue: (e: any) => {
+ console.log(e);
+ },
+ },
+ },
+ {
+ field: 'createdAt',
+ component: 'NDatePicker',
+ label: '创建时间',
+ componentProps: {
+ type: 'datetimerange',
+ clearable: true,
+ shortcuts: defRangeShortcuts(),
+ onUpdateValue: (e: any) => {
+ console.log(e);
+ },
+ },
+ },
+]);
+
+export const columns = [
+ {
+ title: '许可ID',
+ key: 'id',
+ width: 100,
+ },
+ {
+ title: '授权分组',
+ key: 'group',
+ width: 100,
+ render(row) {
+ return h(
+ NTag,
+ {
+ style: {
+ marginRight: '6px',
+ },
+ type: 'info',
+ bordered: false,
+ },
+ {
+ default: () => getOptionLabel(options.value.group, row.group),
+ }
+ );
+ },
+ },
+ {
+ title: '授权许可',
+ key: 'name',
+ render(row) {
+ return h('p', { id: 'app' }, [
+ h('div', {
+ innerHTML: '',
+ }),
+ h('div', {
+ innerHTML: '',
+ }),
+ ]);
+ },
+ width: 180,
+ },
+ {
+ title: '在线',
+ key: 'online',
+ render(row) {
+ return row.online + ' / ' + row.onlineLimit;
+ },
+ width: 100,
+ },
+ {
+ title: '授权有效期',
+ key: 'endAt',
+ width: 150,
+ },
+ {
+ title: '状态',
+ key: 'status',
+ width: 100,
+ render(row) {
+ if (isNullObject(row.status)) {
+ return ``;
+ }
+ return h(
+ NTag,
+ {
+ style: {
+ marginRight: '6px',
+ },
+ type: getOptionTag(options.value.sys_normal_disable, row.status),
+ bordered: false,
+ },
+ {
+ default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
+ }
+ );
+ },
+ },
+ {
+ title: '最后连接',
+ key: 'remoteAddr',
+ width: 150,
+ },
+ {
+ title: '最近登录 / 心跳',
+ key: 'name',
+ render(row) {
+ if (row.lastLoginAt === null) {
+ return '从未登录';
+ }
+ return (
+ formatBefore(new Date(row.lastLoginAt)) + ' / ' + formatBefore(new Date(row.lastActiveAt))
+ );
+ },
+ width: 180,
+ },
+ {
+ title: '累计登录',
+ key: 'loginTimes',
+ width: 100,
+ },
+ {
+ title: '创建时间',
+ key: 'createdAt',
+ width: 150,
+ },
+];
+
+async function loadOptions() {
+ options.value = await Dicts({
+ types: ['sys_normal_disable'],
+ });
+
+ const netOption = await NetOption();
+ options.value.group = netOption.licenseGroup;
+ options.value.routes = netOption.routes;
+
+ for (const item of schemas.value) {
+ switch (item.field) {
+ case 'status':
+ item.componentProps.options = options.value.sys_normal_disable;
+ break;
+ case 'group':
+ item.componentProps.options = options.value.group;
+ break;
+ }
+ }
+}
+
+await loadOptions();
diff --git a/web/src/views/monitor/online/index.vue b/web/src/views/monitor/online/index.vue
index 8224362..d581eb7 100644
--- a/web/src/views/monitor/online/index.vue
+++ b/web/src/views/monitor/online/index.vue
@@ -1,20 +1,25 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
+
diff --git a/web/src/views/org/user/model.ts b/web/src/views/org/user/model.ts
index aaf80c1..b595b73 100644
--- a/web/src/views/org/user/model.ts
+++ b/web/src/views/org/user/model.ts
@@ -178,7 +178,7 @@ export const options = ref({
post: [],
});
-async function loadOptions() {
+export async function loadOptions() {
const dept = await getDeptOption();
if (dept.list !== undefined) {
options.value.dept = dept.list;
@@ -187,6 +187,7 @@ async function loadOptions() {
const role = await getRoleOption();
if (role.list !== undefined) {
options.value.role = role.list;
+ options.value.roleTabs = [{ id: -1, name: '全部' }];
treeDataToCompressed(role.list);
}
@@ -207,8 +208,5 @@ function treeDataToCompressed(source) {
? treeDataToCompressed(source[i].children)
: ''; // 子级递归
}
-
return options.value.roleTabs;
}
-
-await loadOptions();
diff --git a/web/src/views/org/user/user.vue b/web/src/views/org/user/user.vue
index c82054e..705a35f 100644
--- a/web/src/views/org/user/user.vue
+++ b/web/src/views/org/user/user.vue
@@ -39,7 +39,8 @@
}
});
- function handleBeforeLeave(tabName: string) {
+ function handleBeforeLeave(tabName: string): boolean | Promise {
defaultTab.value = tabName;
+ return true;
}
diff --git a/web/src/views/permission/menu/CreateDrawer.vue b/web/src/views/permission/menu/CreateDrawer.vue
index 8f7612c..656b6e9 100644
--- a/web/src/views/permission/menu/CreateDrawer.vue
+++ b/web/src/views/permission/menu/CreateDrawer.vue
@@ -296,7 +296,7 @@
},
},
emits: ['loadData'],
- setup(props, context) {
+ setup(_props, context) {
const message = useMessage();
const formRef: any = ref(null);
const state = reactive({
diff --git a/web/src/views/permission/role/columns.ts b/web/src/views/permission/role/columns.ts
index 2ed0b91..198db0c 100644
--- a/web/src/views/permission/role/columns.ts
+++ b/web/src/views/permission/role/columns.ts
@@ -40,7 +40,7 @@ export const columns = [
{
title: '角色编码',
key: 'key',
- // width: 150,
+ width: 150,
},
// {
// title: '上级角色',
@@ -60,22 +60,22 @@ export const columns = [
}
);
},
- // width: 80,
+ width: 80,
},
{
title: '排序',
key: 'sort',
- // width: 100,
+ width: 100,
},
{
title: '备注',
key: 'remark',
- // width: 300,
+ width: 180,
},
{
title: '状态',
key: 'status',
- // width: 80,
+ width: 80,
render(row) {
return h(
NTag,
diff --git a/web/src/views/permission/role/role.vue b/web/src/views/permission/role/role.vue
index 8b81402..e816e82 100644
--- a/web/src/views/permission/role/role.vue
+++ b/web/src/views/permission/role/role.vue
@@ -31,8 +31,8 @@